Spring Data JPAとHibernateを使用するWebアプリケーションでは、web pagination機能を使用して、エンティティのさまざまなリストでページングとソート機能を提供しています。Spring Data JPA無効なpage.sortパラメータ
@Controller
public class MyEntityController {
@RequestMapping(method = RequestMethod.GET)
public ModelAndView list(Pageable pageable) { ... }
}
@Configuration
public class MyWebMvcConfig extends WebMvcConfigurationSupport {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new PageableArgumentResolver());
}
}
public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, String> {
Page<MyEntity> findByPropertyX(String propertyX, Pageable pagable);
}
これはpage.sort
値が実際にソートする際のエンティティ内のプロパティと一致してレンダリングされたHTMLのような特殊なソートrequest parametersで定義されるエンティティのプロパティを可能にします。
<table>
<thead>
<tr>
<th><a href="?page.sort=propertyX&page.sort.dir=asc">Property X</a></th>
<th><a href="?page.sort=propertyY&page.sort.dir=asc">Property Y</a></th>
</tr>
</thead>
<tbody>...</tbody>
</table>
これは、結果として得られるURLを生成する:
http://host/context-root/entities/?page.sort=propertyX&page.sort.dir=asc
ユーザーが無効page.sort
プロパティを使用するURLを変更してもよいということである問題その基準のいずれかが存在しないカラム/プロパティ名、または悪化、無効なJPAクエリー文字を使用して無効な構文が使用されます。 URLが "noSuchProperty" でソートするように変更された場合例えば
は、:
http://host/context-root/entities/?page.sort=noSuchProperty&page.sort.dir=asc
しかし、このプロパティが存在しない、次の例外がスローされます。同様に
java.lang.IllegalArgumentException: No property noSuchProperty found for type class com.my.company.MyEntity
at org.springframework.data.repository.query.parser.Property.<init>(Property.java:76)
. . .
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:86)
. . .
at $Proxy68.findByPropertyX(Unknown Source)
at com.my.company.MyEntityRepository.findByPropertyX(MyEntityRepository.java:17
、 URLが無効なクエリ構文文字(「」など)に変更された場合:
http://host/context-root/entities/?page.sort=%22&page.sort.dir=asc
次のエラーまたは発生します。
java.lang.StackOverflowError
java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
. . .
org.springframework.data.repository.query.parser.Property.create(Property.java:326)
org.springframework.data.repository.query.parser.Property.create(Property.java:326)
org.springframework.data.repository.query.parser.Property.create(Property.java:326)
org.springframework.data.repository.query.parser.Property.create(Property.java:326)
(@Query
が明示的にリポジトリ方法で定義されている場合org.hibernate.QueryException
もたらす例外の第三の風味もある)
スプリングデータJPA抄録離れての詳細をソート、ページング、およびこれらのパラメータの処理。ただし、これらのシナリオ(つまり、無効なソートパラメータが指定されている場合)を適切に処理するようには見えません。
ソートプロパティが実際にエンティティに存在することを検証するカスタムロジックを追加できます。しかし、Spring Data JPAの抽象化のメリットとシンプルさを失わないように、これを行うためのよりクリーンで集中化されたアプローチがあるのだろうかと思います。私たちはこのソート機能を多くの異なるエンティティでアプリ全体に使用しています。理想的には、リクエストされたすべてのエンティティページのソートプロパティを明示的に定義したりチェックしたりする必要はありません。
具体的には、コントローラで提供されるアノテーション付きの並べ替えのデフォルト値を受け入れるように実際に拡張しています(簡単にするためにコード例には示していません)。このデフォルトの並べ替え順に戻すだけです。例外をスローするのではなく、エンティティのデフォルトのソート順です。
私はQueryCreationListener
を使用してクエリの作成をインターセプトし、並べ替えパラメータを取得できます。しかし、私は実際にその時点でクエリを変更することはできません。あるいは、私はソートパラメータを取得するためにカスタムを拡張して使用することができます(これを既に行っています)。PageableArgumentResolver
しかし、私はその時点でエンティティにアクセスすることはできませんし、実体がその名前でプロパティを実際に持っているかどうかを判断する能力もありません。サポートされているプロパティを明示的に宣言できます。しかし、このことは、エンティティの特定のまたは宣言された知識を必要とせずに、このシナリオを集中的かつ自動的に処理するという考え方を打ち消してしまう。
ページング可能なソートパラメータを一元的に検証し、クエリを呼び出す前に必要に応じて変更するために使用できる、他のタイプのインターセプタまたは類似の構造体がありますか?あるいは、Springがこのシナリオを自動的に処理して、無効なソートパラメータをより適切に処理するような設定や方法がありますか?