J'ai un mappage de demandes -
@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");
}
}
Si startTime et endTime ne sont pas valides, je souhaite générer une erreur 500 mais renvoyer la chaîne d'exception au format JSON. Cependant, je reçois une page HTML à la place disant
Whitelabel Error Page
Cette application n'a pas de mappage explicite pour/error, vous la voyez donc comme une solution de secours.
Mer. 20 déc. 10:49:37 IST 2017
Une erreur inattendue s'est produite (type = erreur interne du serveur, statut = 500).
Date/heure est invalide
Au lieu de cela, je voulais retourner 500 avec un JSON
{"error":"Date time format is invalid"}
Comment puis-je m'y prendre?
Supposons que vous ayez une classe d'exception personnalisée NotFoundException
et ses implémentations qui ressemblent à ceci:
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();
}
}
Maintenant, vous voulez lancer une exception du contrôleur. Si vous lancez une exception, vous devez la récupérer dans une classe standard Error Handler. Supposons qu'au printemps, elles fournissent l'annotation @ControllerAdvice
à appliquer pour créer une classe Standard Error Handler. Lorsqu'il est appliqué à une classe, alors ce composant de ressort (je veux dire la classe que vous avez annotée) peut intercepter toute exception levée par le contrôleur. Mais nous devons mapper la classe des exceptions avec la méthode appropriée. Nous avons donc défini une méthode avec votre gestionnaire NotFoundException
d'exception, comme ci-dessous.
@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;
}
}
Vous voulez envoyer le statut http au serveur interne error (500) , nous avons donc utilisé @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
. Puisque vous avez utilisé Spring-boot, vous n'avez donc pas besoin de créer une chaîne json, à l'exception d'une simple annotation @ResponseBody
qui peut le faire pour vous automatiquement.
Créez une exception personnalisée.
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;
}
}
Créez une entité de réponse personnalisée.
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;
}
}
Créez un ControllerAdvice avec ExceptionHandler pour une exception personnalisée. Il gérera l'exception personnalisée, sera rempli et retournera la réponse personnalisée comme indiqué ci-dessous.
@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;
}
}
Lancez l'exception personnalisée en fonction de votre condition.
throw new SecurityException("Date time format is invalid");
Maintenant, lancez et testez votre application. PAR EXEMPLE. :
vous pouvez créer la classe NotFoundException
avec l'annotation @ResponseStatus
comme ci-dessous:
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class NotFoundException extends RuntimeException {
public NotFoundException() {
}
public NotFoundException(String message) {
super(message);
}
}
Javax a un nom d'interface comme ExceptionMapper. Veuillez vous référer à l'extrait de code ci-dessous. Pour chaque exception RuntimeException de votre application, il sera mappé à une entité Json Response.
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();
}
}
}
Voici comment je l'ai fait dans ma candidature:
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);
}
}
Explication:
Vous créez un conseil de contrôleur, vous le marquez avec une annotation spéciale et vous le définissez comme tout autre bean (dans mon cas, il s'agissait d'une configuration Java, mais cela n'a pas vraiment d'importance)
Pour chaque exception que vous souhaitez gérer comme ceci - définissez un gestionnaire qui générera une réponse dans le format de votre choix
À présent, ce n’est qu’une façon de travailler (il est disponible dans les versions les plus récentes de Spring Boot) - mais il en existe d’autres:
Toutes les méthodes que je connais (et même plus) sont listées ici .