Reputation: 2355
I'm using spring-webmvc : 3.2.3.RELEASE (and its related dependencies).
I have this controller:
@Controller
@RequestMapping("/home")
public class HomeController {
@Autowired
MappingJacksonHttpMessageConverter messageConverter;
@RequestMapping(method = RequestMethod.GET)
public String get() {
throw new RuntimeException("XXXXXX");
}
@ExceptionHandler(value = java.lang.RuntimeException.class)
@ResponseStatus(HttpStatus.CONFLICT)
public ModelAndView runtimeExceptionAndView(ServletWebRequest webRequest) throws Exception {
ModelAndView retVal = handleResponseBody("AASASAS", webRequest);
return retVal;
}
@SuppressWarnings({ "resource", "rawtypes", "unchecked" })
private ModelAndView handleResponseBody(Object body, ServletWebRequest webRequest) throws ServletException, IOException {
ServletServerHttpResponse outputMessage = new ServletServerHttpResponse(webRequest.getResponse());
messageConverter.write(body, MediaType.APPLICATION_JSON, outputMessage);
return new ModelAndView();
}
}
since the "/home" method throws RuntimeException that is being handled with the @ExceptionHandler, when the get() method is invoked, I'm expectin to get HttpStatus.CONFLICT, but instead, I'm getting HttpStatus.OK. Can someone please tell me what should I do in order to get the response status from the annotated exception handler?
Upvotes: 4
Views: 1175
Reputation: 3724
Modify ExceptionHandler method like this
@ExceptionHandler(value = java.lang.RuntimeException.class)
public ModelAndView runtimeExceptionAndView(ServletWebRequest webRequest, HttpServletResponse response) throws Exception {
response.setStatus(HttpStatus.CONFLICT.value());
ModelAndView retVal = handleResponseBody("AASASAS", webRequest);
return retVal;
}
If you want to handle exception by json result, I suggest to use @ResponseBody with Automatic Json return.
@ExceptionHandler(value = java.lang.RuntimeException.class)
@ResponseBody
public Object runtimeExceptionAndView(ServletWebRequest webRequest, HttpServletResponse response) throws Exception {
response.setStatus(HttpStatus.CONFLICT.value());
return new JsonResult();
}
Upvotes: 2
Reputation: 49915
The reason is because you are explicitly writing to the output stream, instead of letting the framework handle it. The header has to go before the body content is written, if you are explicitly handling writing to the output stream, you will have to write the header also yourself.
To let the framework handle the entire flow, you can instead do this:
@ExceptionHandler(value = java.lang.RuntimeException.class)
@ResponseStatus(HttpStatus.CONFLICT)
@ResponseBody
public TypeToBeMarshalled runtimeExceptionAndView(ServletWebRequest webRequest) throws Exception {
return typeToBeMarshalled;
}
Upvotes: 4