I am still really new with Spring Boot, but I have a web application, that is setup to handle either XML requests (when the requests have a "Content-type: application/xml" header, or JSON requests (when the requests have a "Content-type: application/xml" header), and I noticed that if the "Content-type" header is either missing, or contains something other than "Content-type: application/xml" or "Content-type: application/json", I get a "415" response error code. The logging also shows a message like:
.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded' not supported]
I found this older SO thread:
Springboot exception handler doesn't catch exception
and have been trying to implement the code that was posted by "Sannu" on Dec 17 '16 at 13:55. This is the code that I built and am testing (as a test, I was trying to change the error response code to "500" and also have a error response message):
import org.apache.logging.log4j.LogManager;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import mil.nga.geoaxis.pdp.models.ErrorResponse;
import org.springframework.http.HttpStatus;
@ControllerAdvice
public class SpringExceptionHandler extends ExceptionHandlerExceptionResolver
{
@ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class)
public ResponseEntity<Object> handleControllerException(HttpMediaTypeNotSupportedException ex, WebRequest req)
{
ErrorResponse errorResponse = null;
//ex.printStackTrace();
errorResponse = new ErrorResponse();
errorResponse.setCode(HttpCodes.HTTP_CODE_INTERNAL_ERROR);
System.out.println("In SpringExceptionHandler.handleControllerException: HttpStatus.INTERNAL_SERVER_ERROR.value()=[" HttpStatus.INTERNAL_SERVER_ERROR.value() "]");
System.out.println("In SpringExceptionHandler.handleControllerException: ex.getMessage()=[" ex.getMessage() "]");
int myCode = errorResponse.getCode();
System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" String.valueOf(myCode) "]");
errorResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
errorResponse.setMessage(ex.getMessage());
myCode = errorResponse.getCode();
System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" String.valueOf(myCode) "]");
return new ResponseEntity<Object>(errorResponse, HttpStatus.valueOf(errorResponse.getCode()));
}
}
However, when I test, and send a request with no "Content-type:" header (using curl), I am still getting what appears to be a response with "100" response code, then a response with a "415" response code, and no response message.
FYI, here is part of the logging that is appearing:
In SpringExceptionHandler.handleControllerException: HttpStatus.INTERNAL_SERVER_ERROR.value()=[500]
In SpringExceptionHandler.handleControllerException: ex.getMessage()=[Content type 'application/x-www-form-urlencoded' not supported]
In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[0]
In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[500]
WARN 15428 --- [io-18443-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Failure in @ExceptionHandler ....errorhandling.SpringExceptionHandler#handleControllerException(HttpMediaTypeNotSupportedException, WebRequest)
Can anyone suggest why this does not seem to be able to send the error code and response message?
[FYI, I am doing this under Spring Boot 2.5.6.]
Thanks in advance!
Jim
EDIT 1: I modified the class per huy's suggestion to this:
import org.apache.logging.log4j.LogManager;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
@ControllerAdvice
public class SpringExceptionHandler
{
@ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class)
public ResponseEntity handleControllerException(HttpMediaTypeNotSupportedException ex, WebRequest req)
{
ErrorResponse errorResponse = null;
//ex.printStackTrace();
errorResponse = new ErrorResponse();
//errorResponse.setCode(HttpCodes.HTTP_CODE_INTERNAL_ERROR);
System.out.println("In SpringExceptionHandler.handleControllerException: HttpStatus.INTERNAL_SERVER_ERROR.value()=[" HttpStatus.INTERNAL_SERVER_ERROR.value() "]");
System.out.println("In SpringExceptionHandler.handleControllerException: ex.getMessage()=[" ex.getMessage() "]");
int myCode = errorResponse.getCode();
System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" String.valueOf(myCode) "]");
errorResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
errorResponse.setMessage(ex.getMessage());
myCode = errorResponse.getCode();
System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" String.valueOf(myCode) "]");
return ResponseEntity
.status(HttpStatus.valueOf(415))
.body(ex.getMessage());
}
}
The code above causes a response with error code 415, and the text error message from the HttpMediaTypeNotSupportedException exception.
CodePudding user response:
You don't need to extend ExceptionHandlerException..., it's used by default to resolve error.
You only need only ControllerAdvice and ExceptionHandler, ExceptionHandlerExceptionResolver will auto scan annotation ExceptionHandler and handle it.