wake-up-neo.com

So werfen Sie eine Ausnahme in JSON in Spring Boot zurück

Ich habe eine Anforderungszuordnung - 

  @RequestMapping("/fetchErrorMessages")
  public @ResponseBody int fetchErrorMessages(@RequestParam("startTime") String startTime,@RequestParam("endTime") String endTime) throws Exception
  {
      if(SanityChecker.checkDateSanity(startTime)&&SanityChecker.checkDateSanity(endTime))
      {
          return 0;
      }
      else
      {
          throw new NotFoundException("Datetime is invalid");
      }
  }

Wenn startTime und endTime ungültig sind, möchte ich einen 500-Fehler ausgeben, aber die Ausnahmezeichenfolge in JSON zurückgeben. Ich bekomme jedoch stattdessen eine HTML-Seite 

Whitelabel-Fehlerseite

Diese Anwendung hat keine explizite Zuordnung für/error, daher sehen Sie dies als einen Fallback.

Mi 20 Dez 10:49:37 IST 2017
Es ist ein unerwarteter Fehler aufgetreten (Typ = Interner Serverfehler, Status = 500).
Datetime ist ungültig

Ich wollte stattdessen 500 mit einem JSON zurückgeben 

{"error":"Date time format is invalid"}

Wie gehe ich vor?

6

Angenommen, Sie haben eine benutzerdefinierte Ausnahmeklasse NotFoundException und deren Implementierungen in etwa wie folgt:

public class NotFoundException extends Exception {

    private int errorCode;
    private String errorMessage;

    public NotFoundException(Throwable throwable) {
        super(throwable);
    }

    public NotFoundException(String msg, Throwable throwable) {
        super(msg, throwable);
    }

    public NotFoundException(String msg) {
        super(msg);
    }

    public NotFoundException(String message, int errorCode) {
        super();
        this.errorCode = errorCode;
        this.errorMessage = message;
    }


    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }

    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    @Override
    public String toString() {
        return this.errorCode + " : " + this.getErrorMessage();
    }
}

Jetzt möchten Sie eine Ausnahme vom Controller auslösen. Wenn Sie eine Ausnahme auslösen, müssen Sie sie von einer Standard-Error-Handler-Klasse abfangen. Beispielsweise geben Sie im Frühjahr eine @ControllerAdvice-Annotation für die Erstellung einer Klasse als Standardfehlerhandler an. Wenn er auf eine Klasse angewendet wird, kann diese Federkomponente (ich meine die von Ihnen kommentierte Klasse) jede vom Controller geworfene Ausnahme abfangen. Aber wir müssen die Ausnahmeklasse mit der richtigen Methode abbilden. Wir haben also eine Methode mit Ihrem Ausnahmebehandler NotFoundException definiert.

@ControllerAdvice
public class RestErrorHandler {

    @ExceptionHandler(NotFoundException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public Object processValidationError(NotFoundException ex) {
        String result = ex.getErrorMessage();
        System.out.println("###########"+result);
        return ex;
    }
}

Sie möchten den http-Status an den internen Serverfehler (500) senden , daher haben wir hier @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) verwendet. Da Sie Spring-Boot verwendet haben, brauchen Sie keine Json-Zeichenfolge, außer einer einfachen Anmerkung, @ResponseBody kann dies automatisch für Sie tun.

4

Erstellen Sie eine benutzerdefinierte Ausnahme.

public class SecurityException extends RuntimeException {

    private static final long serialVersionUID = -7806029002430564887L;

    private String message;

    public SecurityException() {
    }

    public SecurityException(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

Erstellen Sie eine benutzerdefinierte Antwortentität.

public class SecurityResponse {

    private String error;

    public SecurityResponse() {

    }

    public SecurityResponse(String error) {
        this.error = error;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

}

Erstellen Sie ein ControllerAdvice mit ExceptionHandler für eine benutzerdefinierte Ausnahme. Es behandelt die benutzerdefinierte Ausnahme, füllt die benutzerdefinierte Antwort aus und gibt sie wie folgt zurück.

@ControllerAdvice
public class SecurityControllerAdvice {

    @ExceptionHandler(SecurityException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public SecurityResponse handleSecurityException(SecurityException se) {
        SecurityResponse response = new SecurityResponse(se.getMessage());
        return response;
    }
}

Löst die benutzerdefinierte Ausnahme basierend auf Ihrer Bedingung aus.

throw new SecurityException("Date time format is invalid");

Starten Sie jetzt und testen Sie Ihre App. Z.B. :

 enter image description here

3
Neeraj Benjwal

sie können eine NotFoundException-Klasse mit der @ResponseStatus-Annotation wie folgt erstellen:

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class NotFoundException extends RuntimeException {
   public NotFoundException() {
   }

   public NotFoundException(String message) {
    super(message);
   }

}
1
Hiren

Javax hat einen Schnittstellennamen als ExceptionMapper. Beachten Sie das nachstehende Codefragment. Für jede RuntimeException in Ihrer Anwendung wird es einer Json Response-Entität zugeordnet.

public class RuntimeExceptionMapper implements ExceptionMapper <RuntimeException> {

@Override
public Response toResponse(RuntimeException exception) {
    ErrorResponse errorResponse = new ErrorResponse();
    errorResponse.setMessage(exception.getMessage);
    if (exception== null) {
        logger.error("Exception Details Not found");            
    } else {
        return Response.status(Status.INTERNAL_SERVER_ERROR)
            .entity(errorResponse )
                .type(MediaType.APPLICATION_JSON)
                    .header("trace-id", "1234").build();
    }


}

}

1
Mohit Sharma

So habe ich es in meiner Bewerbung gemacht:

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class ExceptionHandlingControllerAdvice {

   @ExceptionHandler(ExecutionRestrictionViolationException.class)
   public ResponseEntity<String> handleExecutionRestrictionViolationException(ExecutionRestrictionViolationException ex) {
     return response("Invalid Query", ex.getMessage(), HttpStatus.UNPROCESSABLE_ENTITY);
   }

   private static String createJson(String message, String reason) {
    return "{\"error\" : \"" + message + "\"," +
            "\"reason\" : \"" + reason  + "\"}";
   }

   private static ResponseEntity<String> response(String message,
                                               String reason,
                                               HttpStatus httpStatus) {
    String json = createJson(message, reason);
    return new ResponseEntity<>(json, httpStatus);
   }

}

Erläuterung:

  1. Sie erstellen einen Controller-Hinweis, markieren ihn mit einer speziellen Anmerkung und definieren wie jede andere Bean (in meinem Fall war es eine Java-Konfiguration, aber das spielt keine Rolle)

  2. Für jede Ausnahme, die Sie wie folgt behandeln möchten: Definieren Sie einen Handler, der eine Antwort in einem gewünschten Format generiert

  3. Es gibt eine statische Methode createJson - Sie können eine andere Methode verwenden, es spielt auch keine Rolle.

Dies ist jetzt nur eine Möglichkeit (es ist in neueren Federstiefelversionen verfügbar) - aber es gibt andere:

Alle Methoden, die mir bekannt sind (und noch mehr), sind hier aufgelistet.

0
Mark Bramnik