21

Spring、Jersey、Hibernate(JPA)を使用してJavaでRESTWebサービスを構築しています。

現在、リソースに検証のサポートを追加しようとしています。JSR-303(Bean Validation)は当然適切な選択肢として登場しました(私はJSR-303のリファレンス実装であるHibernate Validatorを使用しています)。ただし、最初にいくつかの概念を統合しようとしています。

少なくとも2種類の可能な検証があるように思われます。

  • フィールドの定期的な検証。たとえば、プロパティがnullでないことの確認、Stringプロパティが有効な電子メールであるかどうかの確認、Integerプロパティがより大きいかどうかの確認10など。これは期待どおりに機能しています。javax.validation.ConstraintViolationExceptionを適切なHTTP応答にマップするJAX-RSExceptionMapperを登録しました。
  • データ整合性の検証

「データ整合性検証」の正確な意味を例を挙げて説明します。これは、2つ以上のリソース間に関係がある場合に発生します。Productaとaの2つのリソースを想像してみてくださいCategory。AProduct にはがありCategoryます。Productクライアントが作成するの表現(POST HTTPリクエスト)をサーバーに送信するとき、クライアントCategoryは製品を通知する必要があります。もちろん、クライアントは事前にカテゴリを知っている必要があります。JSONで次のようなものを想像してみてください。

{
   "quantity": "10",
   "state": "PRODUCED",
   "category": {
      "id": "123"
   }
}

ええと、idのカテゴリ123は存在しないかもしれません。これをデータベースに挿入しようとすると、明らかに外部キー関連の例外が発生します。したがって、通常のプロパティ検証と同様に、これらの問題を検証し、クライアントに適切なメッセージを返す必要があると思います。


今、私の主な質問は次のとおりです。

  1. 現在、JPAとBean Validationの統合により、データアクセスレベルで検証を実行しています。検証は、シリアル化プロセス前/後、データベース操作の前/後、またはその両方で実行する必要がありますか?
  2. データ整合性検証を処理する方法は?手動で?(つまり、データの整合性をチェックするデータベースを明示的に参照します)または、とにかくそれを挿入してから、データベース(またはDAO)の例外をキャッチする必要がありますか?Bean Validationは、この種の検証とは何の関係もありませんよね?
  3. JAX-RS / RESTとBeanValidationの経験があれば、教えていただければ幸いです。グループを使用していますか?

これらの質問はJavaにいくらか関連していますが、私はこれらの問題についていくつかの新しい視点を得ることも望んでいました。いくつかの技術に依存しないもの。:)RESTWebサービスでこれらの問題に対する独自のソリューションを提供できれば素晴らしいと思います。

4

4 に答える 4

8

JacksonJaxbJsonProvider解決策は、JAX-RSMessageBodyReaderとを実装するJacksonをサブクラス化することになりましたMessageBodyWriter私は驚くべきdropwizardのアプローチに触発されました。このプロバイダーでは、何らかの方法でValidatorインスタンスをインジェクトする必要があります(インジェクションにはSpringを使用し、JSR-303実装にはHibernate Validatorを使用しました)。Hibernate ORMを使用する場合は、エンティティ検証を無効にすることを忘れないでください。無効にしないと、同じエンティティを2回検証することになります。しかし、それは望ましいことかもしれません。

次に、このサブクラス化されたオブジェクトで、オブジェクトを検証し、バリデーターからのエラーを使用してMessageBodyReaderカスタムをスローします。また、すべてを適切なHTTP応答にマップInvalidEntityExceptionするJAX-RSを作成しました。私の場合、BadRequestとエラーの説明を含むJSONオブジェクトを返しました。ExceptionMapper<InvalidEntityException>InvalidEntityException

このMessageBodyReaderが注釈@Validをチェックすることに注意してください。@Validatedこれは、グループを正しくサポートしていることを意味します。アプリケーション全体で同じ種類の検証を実行したくない場合があるため、これは重要です。例として、部分更新(PUT)を実行する場合があります。または、たとえば、IDプロパティはPOSTリクエストではnullである必要がありますが、それ以外の場合はnullではありません。

データ整合性の検証はまだ完全には処理されていません。しかし、データベースの例外をキャッチし、それらを自分のドメイン例外(たとえば、DataIntegrityException)に変換することを計画しています。これは、より効率的で、私とのつながりが緩いように思われるためです。


アップデート:

JAX-RS 2以降、これを行うための推奨される方法は、BeanValidationサポートを使用することです。ここをチェックしてください:https ://jersey.java.net/documentation/latest/bean-validation.html

于 2013-01-09T12:53:38.633 に答える
6

これで、Jersey 2.0を使用して、JSR-303/JSR-349を介したリソース引数の検証を行うことができます。

https://jersey.java.net/documentation/latest/bean-validation.html#d0e9301

于 2013-06-21T10:01:46.647 に答える
1

を利用jersey filtersして、リクエストデータに対していくつかの検証を行うことができます。

ID123のカテゴリは存在しない可能性があります。これをデータベースに挿入しようとすると、明らかに外部キー関連の例外が発生します。

このような場合、データアクセスレベルの検証に頼ることができます。ただし、クライアントに同期的に応答する場合は、通常、このビジネスロジックを何らかのサービスAPIで公開することをお勧めします。つまり、のようなAPIを使用している場合がありますisValidCategory(int id)。これは、DAOよりも高いレベルでクエリできるため、データアクセス層でエラー/例外が発生するまで実際に待つ必要はありません。明らかに、これはデータベースルックアップを意味する可能性があります(システムによって異なります)が、キャッシングまたはその他のメカニズムを使用して応答時間を改善するためにそれを最適化することは、まったく別の問題です。

Beanバリデーターについて言えば、JSR303の実装であるHibernateバリデーターを見ることができます。

于 2013-01-08T16:13:04.507 に答える
0

楕円形は、オブジェクトを評価するのに最適なパッケージです。単体テストアサーションと自動テストを生成すると非常に便利です。

于 2017-06-15T07:25:55.970 に答える