Was ist der beste Weg, um verschiedene Arten von ResponseEntity in Spring-Boot zurückzugeben (Fehlerbehandlung für REST mit Spring)
Lesezeit: 7 Minuten
Saveendra Ekanayake
Ich habe eine einfache REST-Anwendung in geschrieben Spring Boot (Spring Rahmen).
Es kehrt zurück ResponseEntity<Success> als Erfolg Reaktion in der Steuerungsebene. Aber ich möchte eine ganz andere zurückgeben Fehler Antwort ResponseEntity<Error>falls ein Fehler vorliegt (Validierungsfehler, Logikfehler, Laufzeitfehler) in der API.
Erfolg & Fehler Antworten sind für die Anwendung völlig unterschiedlich. Success & Error sind die 2 Java-Klassen, die die Anwendung zur Darstellung verwendet Erfolg & Fehler Antworten.
Was ist der beste Weg, um verschiedene Arten von zurückzugeben ResponseEntity In Spring-Boot (Der beste Weg, um die Fehler für REST mit zu behandeln Spring)?
Eine Lösung ist die Verwendung ResponseEntity<Object>. Eine andere Möglichkeit besteht darin, eine BaseClass oder eine Schnittstelle für die Typen Success und Error zu verwenden.
– Jens
30. Juni 2016 um 8:28 Uhr
Könntest du nicht einfach zurückkehren ResponseEntity in Ihrer Methodendefinition? ` public ResponseEntity myControllerMethod(…) und entweder a ResponseEntity<Success> oder ein ResponseEntity<Error>
– J. Mengelle
30. Juni 2016 um 8:40 Uhr
ResponseEntity<Either<Error, Success>> wäre gut, wenn du es schaffst, die datenstruktur in java zu implementieren
– Ali Deghani
30. Juni 2016 um 13:08 Uhr
Markus Norman
Ich empfehle die Verwendung von Spring’s @ControllerAdvice Fehler zu behandeln. Lesen diese Anleitung für eine gute Einführung, beginnend mit dem Abschnitt “Spring Boot Error Handling”. Für eine eingehende Diskussion gibt’s ein Artikel im Spring.io-Blog, der im April 2018 aktualisiert wurde.
Eine kurze Zusammenfassung, wie das funktioniert:
Ihre Controller-Methode sollte nur zurückkehren ResponseEntity<Success>. Es ist nicht für die Rückgabe von Fehler- oder Ausnahmeantworten verantwortlich.
Sie implementieren eine Klasse, die Ausnahmen für alle Controller behandelt. Diese Klasse wird mit kommentiert @ControllerAdvice
Diese Controller Advice-Klasse enthält Methoden, die mit annotiert sind @ExceptionHandler
Jede Ausnahmebehandlungsmethode wird so konfiguriert, dass sie einen oder mehrere Ausnahmetypen behandelt. Mit diesen Methoden geben Sie den Antworttyp für Fehler an
Für Ihr Beispiel würden Sie (in der Controller Advice-Klasse) eine Ausnahmebehandlungsmethode für den Validierungsfehler deklarieren. Der Rückgabetyp wäre ResponseEntity<Error>
Bei diesem Ansatz müssen Sie die Ausnahmebehandlung Ihres Controllers nur an einer Stelle für alle Endpunkte in Ihrer API implementieren. Es macht es Ihrer API auch leicht, eine einheitliche Ausnahmeantwortstruktur für alle Endpunkte zu haben. Dies vereinfacht die Ausnahmebehandlung für Ihre Clients.
Dies ist der Standard und sollte meiner Meinung nach die akzeptierte Antwort sein.
– Honza Zidek
14. September 2018 um 15:15 Uhr
Was ist mit der Tatsache, dass es nicht empfohlen wird, den erwarteten Anwendungsfluss über Ausnahmen in Java zu behandeln? Zum Beispiel gibt ein getCustomerForIBAN einen optionalen Wert zurück, der über eine REST-API verfügbar gemacht wird GET /api/customer/{iban} was gibt 200 ok oder 404 nicht gefunden zurück? Würden Sie raten, dann eine Ausnahme auszulösen und das auf die gleiche Weise zu handhaben?
– LukasSolar
18. Juli 2019 um 20:55 Uhr
Wenn Sie die Verwendung von Ausnahmen in Java vermeiden möchten, können Sie Ihre Controller-Methode so entwerfen, dass sie a zurückgibt ResponseEntity. ResponseEntity ermöglicht es Ihnen, den zurückgegebenen HTTP-Statuscode zu steuern, und es ist ein generischer Typ, sodass Sie jede Objektstruktur zurückgeben können. Hier ist eine Erklärung zur Verwendung: baeldung.com/spring-response-entity
– Markus Norman
19. Juli 2019 um 14:46 Uhr
Ist dies wirklich der Standard für den Umgang mit “Validierungsfehlern”? Validierungsfehler sollen (vermutlich) ein kontrollierter Fluss in Ihrer Serviceschicht sein. Warum sollten wir eine Ausnahme unbehandelt auf die Controller-Ebene steigen lassen? Ich verstehe unerwartete Ausnahmen (dh 5xx-Fehlercodes), aber keine Validierungscodes (4xx). Übersehe ich etwas?
– Taylorkresse
7. Juli 2020 um 22:17 Uhr
Dies ist der Standard für die Behandlung von Fehlern, die andere Schichten der Anwendung nach oben übertragen oder explizit auslösen können. RE: Validierungsfehler, die der Service Layer noch abfangen und behandeln kann. Ich war zu restriktiv, als ich im ersten Satz “Validierungsfehler behandeln” angegeben habe. Ich habe “Validierung” gelöscht, um anzuzeigen, dass dies allgemein für Fehler gilt. Danke für den Hinweis.
– Markus Norman
7. Juli 2020 um 23:49 Uhr
Saravana
Sie können einen generischen Platzhalter zurückgeben <?> zurückgeben Success Und Error auf einer gleichen Anforderungszuordnungsmethode
public ResponseEntity<?> method() {
boolean b = // some logic
if (b)
return new ResponseEntity<Success>(HttpStatus.OK);
else
return new ResponseEntity<Error>(HttpStatus.CONFLICT); //appropriate error code
}
@ Mark Norman Antwort ist der richtige Ansatz
Es ist nur so, dass Codequalitätstools (wie Sonar Lint) diese Codierungspraxis kennzeichnen Generische Platzhaltertypen sollten nicht in Rückgabeparametern verwendet werden (squid:S1452)
– Sabir Khan
12. Oktober 2017 um 4:05 Uhr
Das ist eher ein hacken wie man den (unvollkommenen) Mechanismus von Java-Generika umgeht. Die Antwort von @ MarkNorman ist der Standard und sollte akzeptiert werden.
– Honza Zidek
14. September 2018 um 15:19 Uhr
Ich bin gerade auf das gleiche Problem gestoßen und suche nach etwas, das mit VAVRs funktionieren würde Eitherdamit ich eine haben könnte public ResponseEntity<Either<Error, Success>> method() oder besser a public Either<ResponseEntity<Error>, ResponseEntity<Success>> method(). Ich denke, der Weg, dies zu tun, wäre, eine zu erstellen HttpMessageConverter das wüsste, wie man damit umgeht und würde einfach entweder auf die linke/rechte Seite umwandeln und die normale Verarbeitung passieren lassen. Auf diese Weise könnte ich meine gültigen Zustände signalisieren, ohne Ausnahmen zu verwenden. Irgendwelche Ideen dazu?
– Dominik Dorn
3. Februar 2019 um 16:58 Uhr
Gibt es eine Möglichkeit, Wildcard-Generika in ein bestimmtes Generikum umzuwandeln?
– DanielPaul
31. Mai 2022 um 7:44 Uhr
Sathiamoorthy
Frühling 2 eingeführt ResponseStatusException Mit diesem können Sie zurückkehren String, anderer HTTP-Statuscode, DTO am gleiche Zeit.
@PostMapping("/save")
public ResponseEntity<UserDto> saveUser(@RequestBody UserDto userDto) {
if(userDto.getId() != null) {
throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE,"A new user cannot already have an ID");
}
return ResponseEntity.ok(userService.saveUser(userDto));
}
Maulik Patel
Ich bin mir nicht sicher, aber ich denke, Sie können verwenden @ResponseEntity Und @ResponseBody und senden Sie 2 verschiedene, eine ist Erfolg und die zweite ist eine Fehlermeldung wie:
@RequestMapping(value ="/book2", produces =MediaType.APPLICATION_JSON_VALUE )
@ResponseBody
Book bookInfo2() {
Book book = new Book();
book.setBookName("Ramcharitmanas");
book.setWriter("TulasiDas");
return book;
}
@RequestMapping(value ="/book3", produces =MediaType.APPLICATION_JSON_VALUE )
public ResponseEntity<Book> bookInfo3() {
Book book = new Book();
book.setBookName("Ramayan");
book.setWriter("Valmiki");
return ResponseEntity.accepted().body(book);
}
Sie können eine Karte mit Ihrem Objekt oder String wie unten verwenden:
@RequestMapping(value = "/path",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<Map<String,String>> getData(){
Map<String,String> response = new HashMap<String, String>();
boolean isValid = // some logic
if (isValid){
response.put("ok", "success saving data");
return ResponseEntity.accepted().body(response);
}
else{
response.put("error", "an error expected on processing file");
return ResponseEntity.badRequest().body(response);
}
}
Maria Ines Parnisari
Hier ist ein Weg, wie ich es tun würde:
public ResponseEntity < ? extends BaseResponse > message(@PathVariable String player) { //REST Endpoint.
try {
Integer.parseInt(player);
return new ResponseEntity < ErrorResponse > (new ErrorResponse("111", "player is not found"), HttpStatus.BAD_REQUEST);
} catch (Exception e) {
}
Message msg = new Message(player, "Hello " + player);
return new ResponseEntity < Message > (msg, HttpStatus.OK);
}
@RequestMapping(value = "/getAll/{player}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity < List < ? extends BaseResponse >> messageAll(@PathVariable String player) { //REST Endpoint.
try {
Integer.parseInt(player);
List < ErrorResponse > errs = new ArrayList < ErrorResponse > ();
errs.add(new ErrorResponse("111", "player is not found"));
return new ResponseEntity < List < ? extends BaseResponse >> (errs, HttpStatus.BAD_REQUEST);
} catch (Exception e) {
}
Message msg = new Message(player, "Hello " + player);
List < Message > msgList = new ArrayList < Message > ();
msgList.add(msg);
return new ResponseEntity < List < ? extends BaseResponse >> (msgList, HttpStatus.OK);
}
KARTHIKEYAN.A
Sie können auch so implementieren, um Erfolg und Fehler auf derselben Anforderungszuordnungsmethode zurückzugeben, verwenden Sie die Objektklasse (übergeordnete Klasse jeder Klasse in Java): –
public ResponseEntity< Object> method() {
boolean b = // logic here
if (b)
return new ResponseEntity< Object>(HttpStatus.OK);
else
return new ResponseEntity< Object>(HttpStatus.CONFLICT); //appropriate error code
}
14449600cookie-checkWas ist der beste Weg, um verschiedene Arten von ResponseEntity in Spring-Boot zurückzugeben (Fehlerbehandlung für REST mit Spring)yes
Eine Lösung ist die Verwendung
ResponseEntity<Object>
. Eine andere Möglichkeit besteht darin, eine BaseClass oder eine Schnittstelle für die Typen Success und Error zu verwenden.– Jens
30. Juni 2016 um 8:28 Uhr
Könntest du nicht einfach zurückkehren
ResponseEntity
in Ihrer Methodendefinition? ` public ResponseEntity myControllerMethod(…) und entweder aResponseEntity<Success>
oder einResponseEntity<Error>
– J. Mengelle
30. Juni 2016 um 8:40 Uhr
ResponseEntity<Either<Error, Success>>
wäre gut, wenn du es schaffst, die datenstruktur in java zu implementieren– Ali Deghani
30. Juni 2016 um 13:08 Uhr