2017-11-01 4 views
4

現在、私は春の起動アプリケーションがあり、POJOの検証にはjavax validatorを使用しています。javax validatorまたはspringバリデータを使用する同じタイプの別々のフィールドに対して別々のエラーメッセージを表示する方法

私の質問はです:どうすれば同じタイプの別々のフィールドに別々のエラーメッセージを表示できますか?例えばと

説明:以下のサンプルコードを参照する:a1.nameが存在しない場合は別のエラーメッセージ(ERROR1)を有し、a2.nameが存在しない場合、別のエラーメッセージ(ERROR2)

を有します

@RestController 
public class Controller1{ 
@GetMapping(value="/abc") 
public void api1(@Valid @RequestBody B b){...} 
} 

public class A{ 
@NotNull 
private String name; 
@NotNull 
private String age; 
//..getters and setters 
} 

public class B{ 
@Valid 
private A a1; 
@Valid 
private A a2; 
} 

私の残りのコントローラは次のようになります。javaxのバリデータ注釈付き

私のPOJOは、のようになります10

私はグループを使用しようとしましたが、javax @ invalid annotaion doesntはグループをサポートしていません。 もう1つのオプションは、@ @ @を付けることを試みましたが、問題はそれをフィールドに適用できないということです。

答えて

1

私が知る限り、Bean検証グループは、この使用例を満たすようには設計されていません。

あなたはそのようなあなたのRESTサービスを呼び出す場合:

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET -d '{"a1":{}, "a2":{}}}' http://localhost:8080/abc 

応答は次のとおりです。あなたがよく見ると

{ 
     "timestamp":"2017-11-10T17:22:07.534+0000", 
     "status":400, 
     "error":"Bad Request", 
     "exception":"org.springframework.web.bind.MethodArgumentNotValidException", 
     "errors":[ 
      { 
      "codes":["NotNull.b.a1.name", "NotNull.a1.name", "NotNull.name", "NotNull.java.lang.String", "NotNull"], 
      "arguments":[ 
       { 
        "codes":["b.a1.name", "a1.name" ], 
        "arguments":null, 
        "defaultMessage":"a1.name", 
        "code":"a1.name" 
       } 
      ], 
      "defaultMessage":"may not be null", 
      "objectName":"b", 
      "field":"a1.name", 
      "rejectedValue":null, 
      "bindingFailure":false, 
      "code":"NotNull" 
      }, 
      { 
      "codes":["NotNull.b.a2.age", "NotNull.a2.age", "NotNull.age", "NotNull.java.lang.String", "NotNull"], 
      "arguments":[ 
       { 
        "codes":[ "b.a2.age", "a2.age"], 
        "arguments":null, 
        "defaultMessage":"a2.age", 
        "code":"a2.age" 
       } 
      ], 
      "defaultMessage":"may not be null", 
      "objectName":"b", 
      "field":"a2.age", 
      "rejectedValue":null, 
      "bindingFailure":false, 
      "code":"NotNull" 
      }, 
      { 
      "codes":[ "NotNull.b.a1.age", "NotNull.a1.age", "NotNull.age", "NotNull.java.lang.String", "NotNull"], 
      "arguments":[ 
       { 
        "codes":["b.a1.age", "a1.age"], 
        "arguments":null, 
        "defaultMessage":"a1.age", 
        "code":"a1.age" 
       } 
      ], 
      "defaultMessage":"may not be null", 
      "objectName":"b", 
      "field":"a1.age", 
      "rejectedValue":null, 
      "bindingFailure":false, 
      "code":"NotNull" 
      }, 
      { 
      "codes":["NotNull.b.a2.name", "NotNull.a2.name", "NotNull.name", "NotNull.java.lang.String", "NotNull"], 
      "arguments":[ 
       { 
        "codes":["b.a2.name", "a2.name"], 
        "arguments":null, 
        "defaultMessage":"a2.name", 
        "code":"a2.name" 
       } 
      ], 
      "defaultMessage":"may not be null", 
      "objectName":"b", 
      "field":"a2.name", 
      "rejectedValue":null, 
      "bindingFailure":false, 
      "code":"NotNull" 
      } 
     ], 
     "message":"Validation failed for object='b'. Error count: 4", 
     "path":"/api/profile/abc" 
    } 

あなたは、応答が表示され、4つの検証エラーを取得していることを述べていることがわかりますそれぞれについて、制約、オブジェクト、ターゲットフィールドのような検証の詳細を入力します。例:NotNull.b.a1.name

適切な検証メッセージを表示するのは、このDetailled応答を補間するのがビュー(RESTクライアント)の責任です。


場合によっては、クライアント側でメッセージを補間するオプションではありません。この場合、Springでカスタムの「検証エラー」ハンドラを追加できます。そのような何か:

@RestController 
public class Controller1 { 

    // This assumes that Spring i18n is properly configured 
    @Autowired 
    private MessageSource messageSource; 

    @ExceptionHandler(MethodArgumentNotValidException.class) 
    @ResponseStatus(HttpStatus.BAD_REQUEST) 
    @ResponseBody 
    public Map<String, String> processValidationError(MethodArgumentNotValidException ex) { 
     BindingResult result = ex.getBindingResult(); 
     List<FieldError> fieldErrors = result.getFieldErrors(); 

     Map<String, String> errors = new HashMap<>(); 
     for (FieldError fieldError: fieldErrors) { 
      String fieldPath = fieldError.getField(); 
      String messageCode = fieldError.getCode() + "." + fieldPath; 
      String validationMessage = messageSource.getMessage(messageCode, new Object[]{fieldError.getRejectedValue()}, Locale.getDefault()); 

      // add the validation message, for example "NotNull.a1.name" => "a should not be null" 
      errors.put(fieldError.getField(), validationMessage); 
     } 

     return errors; 
    } 


    @GetMapping(value="/abc") 
    public void api1(@Valid @RequestBody B b){ 
     //... 
    } 
} 
+0

こんにちはSebastein おかげでお返事のためにたくさん。 私は既に提案したものに多少似ている解決策を使用しています。だから私は[fieldName、message]のマップを維持しています。 fieldNameには、parentVariableName.fieldNameが含まれます。これはFieldError.getField()から取得できます。そして、fieldNameを使って、マップからそれぞれのメッセージを得ることができます。 上記のシナリオを処理するための簡単な方法がjavax検証によって提供されているかどうかを知りたいと思っていました。 – kaka

+0

私は参照してください。繰り返しますが、Beanの検証だけでは解決策が見つからないと思います。しかし、妥当性検証エラーが発生した場合に返されるデフォルトの応答を上書きすることができるため、Spring Validationはより高いレベルで動作し、解決策を提供します。したがって、キーとしてのフィールドパスのマップや値としての検証メッセージなどのカスタムレスポンスを返すことができます。 –

関連する問題