I have a class annotated with @ControllerAdvice
and this method in it:
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ExceptionInfo resourceNotFoundHandler(ResourceNotFoundException ex) {
List<ErrorContent> errors = new ArrayList<>();
errors.add(new ErrorContent(ExceptionsCodes.NOT_FOUND_CODE, null,
"test"));
return fillExceptionInfo(HttpStatus.NOT_FOUND, errors, ex);
}
Here is fillExceptionInfo
:
public ExceptionInfo fillExceptionInfo(HttpStatus status, List<ErrorContent> errors,
Exception ex) {
String msg = ex.getMessage();
return new ExceptionInfo(status.toString(), errors, (msg != null && !msg.equals(""))
? ex.getMessage()
: ExceptionUtils.getFullStackTrace(ex));
}
When a web-client send a request for some json data, which cannot be found, this method works ok. But when server receives a request to image, instead of my exception a HttpMediaTypeNotAcceptableException
is thrown. I understand that it happens because of wrong content type, but how can I fix this problem?
Update
My goal is to throw ResourceNotFoundException
in both cases for json data and for file.
Exception that I get (so it is thrown from AbstractMessageConverterMethodProcessor
):
ERROR o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - doResolveHandlerMethodException - Failed to invoke @ExceptionHandler method: public com.lia.utils.GlobalExceptionHandler$ExceptionInfo com.lia.utils.GlobalExceptionHandler.resourceNotFoundHandler(com.lia.app.controllers.exceptions.ResourceNotFoundException)
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:168) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:101) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:198) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71) ~[spring-web-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:362) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:60) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:138) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1167) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1004) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:717) [jetty-servlet-9.1.1.v20140108.jar:9.1.1.v20140108]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1644) [jetty-servlet-9.1.1.v20140108.jar:9.1.1.v20140108]
....
The problem lies in the incompatibility of the requested content type and the object being returned. See my response on how to configure the ContentNegotiationConfigurer
so that Spring determines the requested content type according to your needs (looking at the path extension, URL parameter or Accept
header).
Depending on how the requested content type is determined, you have following options when an image is requested by the client:
Accept
header, and if the client can/wants to handle a JSON response instead of the image data, then the client should send the request with Accept: image/*, application/json
. That way Spring knows that it can safely return either the image byte data or the error JSON message.Set the error code on the response directly
public byte[] getImage(HttpServletResponse resp) {
try {
// return your image
} catch (Exception e) {
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
Use ResponseEntity
public ResponseEntity<?> getImage(HttpServletResponse resp) {
try {
byte[] img = // your image
return ReponseEntity.ok(img);
} catch (Exception e) {
return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Use a separate @ExceptionHandler
method in that controller, which will override the default Spring exception handling. That assumes you have either a dedicated exception type for image requests or a separate controller just for serving the images. Otherwise, the exception handler will handle exceptions from other endpoints in that controller, too.
What does your ExceptionInfo
class look like? I run into quite similar issue after defining a few exception handlers in @ControllerAdvice
annotated class. When exception happened it was caught, although the response was not return and org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
was thrown.
I figured out that the problem was caused by the fact, that I missed to add getter methods to my ErrorResponse
class. After adding getter methods (this class was immutable, so there were no setter methods) everything worked like a charm.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With