451 Stimmen

Wie reagiert man in einer Spring MVC @ResponseBody-Methode, die einen String zurückgibt, mit einem HTTP 400-Fehler?

Ich verwende Spring MVC für eine einfache JSON-API, mit einem @ResponseBody Ansatz wie folgt. (Ich habe bereits eine Service-Schicht, die JSON direkt erstellt.)

@RequestMapping(value = "/matches/{matchId}", produces = "application/json")
@ResponseBody
public String match(@PathVariable String matchId) {
    String json = matchService.getMatchJson(matchId);
    if (json == null) {
        // TODO: Wie kann man z.B. mit 400 "Bad Request" antworten?
    }
    return json;
}

In dem gegebenen Szenario, was ist der einfachste, sauberste Weg, um mit einem HTTP 400 Fehler zu antworten?

Ich bin auf Ansätze wie die folgenden gestoßen:

return new ResponseEntity(HttpStatus.BAD_REQUEST);

...aber ich kann es hier nicht verwenden, da der Rückgabetyp meiner Methode String ist, nicht ResponseEntity.

1voto

xlm Punkte 5604

Der einfachste und sauberste Weg, Ausnahmen in Ihrem Controller zu behandeln, ohne explizit ResponseEntity zurückgeben zu müssen, besteht darin, einfach @ExceptionHandler-Methoden hinzuzufügen.

Beispiel-Schnipsel mit Spring Boot 2.0.3.RELEASE:

// Bevorzuge den statischen Import von HttpStatus-Konstanten, da es meiner Meinung nach sauberer ist

// Behandeln, ohne Inhalt zurückzugeben
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(BAD_REQUEST)
void onIllegalArgumentException() {}

// Gib 404 zurück, wenn JdbcTemplate keine einzelne Zeile zurückgibt
@ExceptionHandler(IncorrectResultSizeDataAccessException.class)
@ResponseStatus(NOT_FOUND)
void onIncorrectResultSizeDataAccessException() {}

// Allumfassender Handler mit der Ausnahme als Inhalt
@ExceptionHandler(Exception.class)
@ResponseStatus(I_AM_A_TEAPOT)
@ResponseBody Exception onException(Exception e) {
  return e;
}

Nebenbei bemerkt:

  • Wenn in allen Kontexten/Nutzungen matchService.getMatchJson(matchId) == null ungültig ist, dann wäre mein Vorschlag, dass getMatchJson eine Ausnahme wirft, z.B. IllegalArgumentException, anstatt null zurückzugeben und es bis zum @ExceptionHandler des Controllers durchlässt.

  • Wenn null verwendet wird, um andere Bedingungen zu testen, würde ich eine spezifische Methode haben, z.B. matchService.hasMatchJson(matchId). Im Allgemeinen vermeide ich null, wenn möglich, um eine unerwartete NullPointerException zu vermeiden.

0voto

dtk Punkte 1514

Sie könnten auch einfach throw new HttpMessageNotReadableException("Fehlerbeschreibung") nutzen, um von Spring's Standardfehlerbehandlung zu profitieren.

Allerdings wird, genauso wie bei diesen Standardfehlern, kein Antwortkörper festgelegt.

Ich halte diese für nützlich, um Anfragen abzulehnen, die vernünftigerweise nur von Hand erstellt worden sein könnten, was möglicherweise auf eine böswillige Absicht hinweist, da sie verschleiern, dass die Anfrage auf einer tieferen, benutzerdefinierten Validierung und deren Kriterien beruht.

-1voto

Nankai Punkte 657

Verwenden Sie eine benutzerdefinierte Antwort mit dem Statuscode.

So geht's:

class Response(
    val timestamp: String = DateTimeFormatter
            .ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS")
            .withZone(ZoneOffset.UTC)
            .format(Instant.now()),
    val code: Int = ResultCode.SUCCESS.code,
    val message: String? = ResultCode.SUCCESS.message,
    val status: HttpStatus = HttpStatus.OK,
    val error: String? = "",
    val token: String? = null,
    val data: T? = null
) : : ResponseEntity(status) {

data class CustomResponseBody(
    val timestamp: String = DateTimeFormatter
            .ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS")
            .withZone(ZoneOffset.UTC)
            .format(Instant.now()),
    val code: Int = ResultCode.SUCCESS.code,
    val message: String? = ResultCode.SUCCESS.message,
    val error: String? = "",
    val token: String? = null,
    val data: Any? = null
)

override fun getBody(): CustomResponseBody? = CustomResponseBody(timestamp, code, message, error, token, data)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X