2016-08-17 13 views
2

JSR-303 Bean Validation APISpring's Validatorの組み合わせを使用して、スプリングブートエンドポイントのカスタム検証ロジックを実装しようとしています。JSR-303とSpringのバリデーターの組み合わせを使用したスプリングブートエンドポイント用のカスタム検証ロジックの実装

は、Validatorクラス図に基づいて、オーバーライドされたメソッドvalidate(Object target, Errors errors)にいくつかのカスタム検証ロジックを追加するCustomValidatorBeanSpringValidatorAdapterまたはLocalValidatorFactoryBeanの1を拡張することが可能であるように思われます。

Validator class diagram

しかし、これらの3つのクラスのいずれかを拡張してバリデータを作成し、@InitBinderを使用してバリデータを登録すると、そのメソッドは呼び出されず、検証も実行されません。 @InitBinderを削除すると、デフォルトのスプリングバリデーターがJSR-303 Bean Validationを実行します。

レストコントローラ:

@RestController 
public class PersonEndpoint { 

    @InitBinder("person") 
    protected void initBinder(WebDataBinder binder) { 
     binder.setValidator(new PersonValidator()); 
    } 

    @RequestMapping(path = "/person", method = RequestMethod.PUT) 
    public ResponseEntity<Person> add(@Valid @RequestBody Person person) { 

     person = personService.save(person); 
     return ResponseEntity.ok().body(person); 
    } 
} 

カスタムバリデータ:

public class PersonValidator extends CustomValidatorBean { 

    @Override 
    public boolean supports(Class<?> clazz) { 
     return Person.class.isAssignableFrom(clazz); 
    } 

    @Override 
    public void validate(Object target, Errors errors) { 
     super.validate(target, errors); 
     System.out.println("PersonValidator.validate() target="+ target +" errors="+ errors); 
    } 

} 

私のバリデータがorg.springframework.validation.Validatorが、そのvalidate(Object target, Errors errors)メソッドが呼び出されたが、JSR-303 Bean Validationが、それに先立って行われていない実装している場合。私は道SpringValidatorAdapterに似て私のカスタムJSR-303の検証は、そのJSR-303 Bean Validationを実装して実装する代わりに、それを拡張する方法がなければならないことができます。

@Override 
    public void validate(Object target, Errors errors) { 
     if (this.targetValidator != null) { 
      processConstraintViolations(this.targetValidator.validate(target), errors); 
     } 
    } 

私はorg.springframework.validation.Validatorの使用を避けるために、カスタムJSR-303制約を使用して見てきましたすべてが一緒になっていますが、カスタムバリデーターを作成する方法が必要です。

validation documentationは2を組み合わせることで、超明確ではありません。

セクション9.8.3で説明したように、アプリケーションがまた「のDataBinderの設定」、のDataBinderインスタンスごとに、追加の春のバリデータのインスタンスを登録することができます。これは、注釈を使用せずに検証ロジックをプラグインする場合に便利です。それは

構成する複数のバリデータインスタンスに触れに次いで

以降AのDataBinderもdataBinder.addValidatorsとdataBinder.replaceValidatorsを介して複数のバリデータインスタンスで構成することができます。これは、グローバルに設定されたBean検証と、DataBinderインスタンス上でローカルに構成されたSpring検証ツールを組み合わせる場合に便利です。見る ???。

私はスプリングブート1.4.0を使用しています。

+0

実際の質問が何であるかはっきりしていません。さらに、あなたが完全な例を共有していれば助けになると思います。コード全体)。私たちがあなたを助けるのは簡単です。 –

+0

文書を読んだことがありますか?カスタムロジックのみを 'Validator'に実装し、' setValidator'の代わりに 'addValidators'を使用してください。これにより、JSR-303(デフォルト設定のバリデーター)とカスタムのバリデーターの両方が呼び出されます。しかし、2つの異なるメカニズムを使用する代わりに、おそらくJSR-303バリデータ/制約を使用する方がよいでしょう。 –

+0

ありがとう@M.Deinum - 'setValidator'の代わりに' addValidators'を使って、トリックを行いました。また、JSR-303を使用すると、特にクロスフィールドの検証に基づいた@AssertTrueメソッドが、おそらくよりクリーンなソリューションになることに同意します。コード例はhttps://github.com/pavelfomin/spring-boot-rest-example/tree/feature/custom-validatorにあります。 の例では、中間名の検証はカスタムバネ バリデータを介して実行され、姓の検証はデフォルトのjsr 303 バリデータによって処理されます。 – pavel

答えて

3

@M.Deinum - setValidator()の代わりにaddValidators()を使用すると、そのトリックが実行されました。また、JSR-303を使用すると、クロスフィールドの検証に@AssertTrueメソッドに基づく注釈を使用すると、おそらくよりクリーンなソリューションになることに同意します。コード例はhttps://github.com/pavelfomin/spring-boot-rest-example/tree/feature/custom-validatorです。この例では、ミドルネーム検証はカスタムバネ検証ツールを介して実行され、ラストネーム検証はデフォルトのjsr 303バリデータによって処理されます。

+0

'@Assertクロスフィールド検証のための@AssertTrueメソッドベースのアノテーションは、おそらくよりクリーンなソリューションです。IMHOより洗練されたソリューションは、カスタムJSR-303バリデータを記述することです(例:http://stackoverflow.com/questions/1972933/cross-field -validation-with-hibernate-validator-jsr-303)を実行します。 –

関連する問題