2017-09-01 1 views
0

Long Story kurz: Ich erstelle API, die 100% REST sein soll. Ich versuche Standardantwort für folgenden Fall zu überschreiben: Ich habe eine Methode in meinem @RestController bekam die @RequestBody als AttributJava/Spring> Handle Bad Request Antwort für Controller-Methode mit @RequestBody, wenn keine Körper in Anfrage gesendet

@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json") 
public Resource<User> registerClient(@RequestBody User user, HttpServletRequest request) 

und das Verfahren funktioniert nur gut, wenn ich eine hat schicken richtige Anfrage. Aber es gibt ein Problem, wenn ich es nicht tue. Wenn eine Anfrage einen leeren Rumpf hat, erhalte ich eine generische Tomcat-Fehlerseite für den Status 400, und ich brauche sie stattdessen, um nur eine Zeichenfolge oder ein JSON-Objekt zu senden.

Bis jetzt habe ich versucht, Exception-Handler in meinem RestControllerAdvice für alle Spring-Ausnahmen aus dem Paket org.springframework.web.binding hinzuzufügen, aber es hat auch nicht funktioniert.

Ich bin mir bereits bewusst, dass für einige sicherheitsrelevante Fehler müssen Sie Handler in der Konfiguration erstellen, aber ich weiß nicht, ob dies der Fall ist.

Hat jemand mit ähnlichen Problemen konfrontiert? Gibt es etwas, das mir fehlt?

+0

"Aber es gibt ein Problem, wenn ich nicht." In welchen Fällen geben Sie keine Benutzerressource zurück? – ruslanys

+0

@ruslanys Ich meine den Fall, wenn ich eine POST-Anfrage ohne Körper oder mit leeren Körper senden, wann immer ich einen Körper mit mindestens ** {} ** es als behandelt behandelt –

+0

@ruslanys leider hilft es nicht, die Content-Type-Header ist da, aber immer noch - kein Körper in der Anfrage bringt das erwähnte Problem –

Antwort

2

Die Lösung war einfach zu setzen erforderlich = falsch in RequestBody Annotation. Danach könnte ich leicht eine Logik hinzufügen, um eine benutzerdefinierte Ausnahme auszulösen und sie in ControllerAdvice zu behandeln.

@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json") 
public Resource<User> registerClient(@RequestBody(required = false) User user, HttpServletRequest request){ 
    logger.debug("addClient() requested from {}; registration of user ({})", getClientIp(request), user); 
    if(user == null){ 
     throw new BadRequestException() 
       .setErrorCode(ErrorCode.USER_IS_NULL.toString()) 
       .setErrorMessage("Wrong body or no body in reqest"); 
    } (...) 
0

Ihre Steuerung wird unter normalen Umständen niemals Ihre Anfrage-Methode erreichen. Wenn Sie eine gute Seite suchen möchten, können Sie web.xml verwenden und konfigurieren, um Ihre Antwort zu produzieren.

<error-page> 
    <error-code>404</error-code> 
    <location>/pages/resource-not-found.html</location> 
</error-page> 

Im Allgemeinen, wenn Sie vorbei an dieses 400 Problem gehen wollen, müssen Sie ein paar annotiations zu Ihrem User.java hinzufügen müssen alle unbekannten Felder während de-Serialisierung zu vermeiden.

1

Zunächst empfehle ich Ihnen BindingResult als Parameter des POST Aufruf zu verwenden und überprüfen, ob es einen Fehler oder nicht zurückgibt.

@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json") 
public ResponseEntity<?> registerClient(@RequestBody User user, HttpServletRequest request, BindingResult brs) 
    if (!brs.hasErrors()) { 
     // add the new one 
     return new ResponseEntity<User>(user, HttpStatus.CREATED); 
    } 
    return new ResponseEntity<String>(brs.toString(), HttpStatus.BAD_REQUEST); 
} 

Zweitens der Anruf einige Fehler werfen, eine gute Praxis ist, sie Carch und sie selbst zurückkehrt oder in Ihr eigenen Ausnahmeobjekt zu verwandeln. Der Vorteil ist, dass es einen Aufruf aller Update/Modify-Methoden (POST, PUT, PATCH) sichert.

@ExceptionHandler(MethodArgumentNotValidException.class) 
@ResponseBody 
public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { 
    return new ResponseEntity<List<MethodArgumentNotValidException>>(e, HttpStatus.BAD_REQUEST); 
} 

@ExceptionHandler({HttpMessageNotReadableException.class}) 
@ResponseBody 
public ResponseEntity<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { 
    return new ResponseEntity<List<HttpMessageNotReadableException>>(e, HttpStatus.BAD_REQUEST); 
} 
+0

Ich wusste nichts darüber! Sieht sehr nützlich aus, danke dafür! –

+0

Willkommen :) Es gibt viele Möglichkeiten, mit einer Ausnahme umzugehen. Ich habe mich für dieses Programm entschieden, da es einfach ist, mit Spring AOP zu loggen. –

Verwandte Themen