2014-07-17 8 views
5

Ich habe ein Spring MVC REST-Dienst Bean Validation 1.2 mit dem folgenden Verfahren erstellt:Frühling Bean Validation @Valid Handhabung

@RequestMapping(value = "/valid") 
public String validatedMethod(@Valid ValidObject object) { 

} 

Wenn das Objekt nicht gültig ist, Tomcat mich darüber informiert, dass The request sent by the client was syntactically incorrect. und meine validatedMethod ist nie namens. Wie kann ich die Nachricht erhalten, die in der ValidObject Bean definiert wurde? Sollte ich einen Filter oder Interceptor verwenden?

Ich weiß, dass ich wie unten neu schreiben kann, den Satz von ConstraintViolation s aus dem injizierten Validator zu bekommen, aber die oben scheint ordentlich ...

@RequestMapping(value = "/valid") 
public String validatedMethod(ValidObject object) { 
    Set<ConstraintViolation<ValidObject>> constraintViolations = validator 
      .validate(object); 
    if (constraintViolations.isEmpty()) { 
     return "valid"; 
    } else { 
     final StringBuilder message = new StringBuilder(); 
     constraintViolations.forEach((action) -> { 
      message.append(action.getPropertyPath()); 
      message.append(": "); 
      message.append(action.getMessage()); 
     }); 
     return message.toString(); 
    } 
} 

Antwort

4

Versuchen Sie, diese

@RequestMapping(value = "/valid") 
public String validatedMethod(@Valid ValidObject object, BindingResult result) { 
    StringBuilder builder = new StringBuilder(); 
    List<FieldError> errors = bindingResult.getFieldErrors(); 
    for (FieldError error : errors) { 
     builder.append(error.getField() + " : " + error.getDefaultMessage()); 
    } 
    return builder.toString(); 
} 
+0

Prost, funktioniert wie ein Charme :) Wäre aber nett, nicht für jede validierte Methode zu tun. – Dormouse

+0

@Dormouse überprüfen Sie meine Antwort :) – dharam

12

Ich glaube, ein besserer Weg ist die Verwendung von ExceptionHandler.

In Ihrem Controller können Sie ExceptionHandler schreiben, um verschiedene Ausnahmen zu behandeln. Unten ist der Code für das gleiche:

@ExceptionHandler(MethodArgumentNotValidException.class) 
@ResponseStatus(HttpStatus.BAD_REQUEST) 
@ResponseBody 
public ValidationFailureResponse validationError(MethodArgumentNotValidException ex) { 
    BindingResult result = ex.getBindingResult(); 
    final List<FieldError> fieldErrors = result.getFieldErrors(); 

    return new ValidationFailureResponse((FieldError[])(fieldErrors.toArray(new FieldError[fieldErrors.size()]))); 
} 

Wenn Sie eine schlechte Anfrage an den Controller zu senden, führt der Prüfer eine Ausnahme vom Typ MethodArgumentNotValidException. Der ideale Weg wäre also, einen Exception-Handler zu schreiben, der diese Ausnahme spezifisch behandelt.

Dort können Sie eine schöne Antwort erstellen, um den Benutzer von Dingen zu erzählen, die schief gelaufen sind. Ich befürworte dies, weil Sie dies nur einmal schreiben müssen und viele Controller Methoden können es verwenden. :)

UPDATE

Wenn Sie die @Valid Anmerkung für ein Verfahren Argument in den Controller verwenden, wird der Validator automatisch aufgerufen und es versucht, das Objekt zu überprüfen, ob das Objekt ungültig ist, wirft es MethodArgumentNotValidException .

Wenn Spring eine ExceptionHandler Methode für diese Ausnahme findet, wird der Code innerhalb dieser Methode ausgeführt.

Sie müssen nur sicherstellen, dass die obige Methode in Ihrem Controller vorhanden ist.

Jetzt gibt es einen weiteren Fall, wenn Sie mehrere Controller s haben, wo Sie die Argumente der Methode validieren möchten. In diesem Fall empfehle ich Ihnen, eine ExceptionResolver Klasse zu erstellen und diese Methode dort zu platzieren. Machen Sie Ihre Controller s erweitern diese Klasse und Ihre Arbeit ist erledigt.

+0

Ok, das scheint DRY. Könnten Sie ein bisschen mehr ausarbeiten? Wie verbinde ich das mit meiner "validierten Methode"? Oh, und der Methode fehlt ein Name. – Dormouse

+0

Sie müssen nicht. Siehe mein Update. – dharam

+0

"ValidationFailureResponse" scheint in keinem meiner Abhängigkeiten zu sein, und Google glaubt nicht, dass es existiert. Welche Maven-Abhängigkeit könnte ich hinzufügen? – Dormouse