How can I return an error message and an HTTP status code calling the jQuery AJAX function?

Using Spring, I have a SimpleMappingExceptionResolver that catches any unexpected exceptions in my application in the resolveException method. In the method, I return a ModelAndView that returns the text of the error message to the HTTP client. Here is the code:

public class UnExpectedExceptionResolver extends SimpleMappingExceptionResolver { private Log logger = LogFactory.getLog(this.getClass().getName()); private ResourceBundleMessageSource messageSource; @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { // let the end user know that an error occurred Locale locale = RequestContextUtils.getLocale(request); String messageText = messageSource.getMessage("systemError", null, locale); Message message = new Message(messageText, MessageType.ERROR); ModelAndView mav = new ModelAndView(); mav.setView(new MappingJacksonJsonView()); mav.addObject("message", message); return mav; } 

Thus, the response is returned with an HTTP status code of 200 with the response text being a message (JSON). Unfortunately, the client considers it a valid answer due to code 200 and is trying to process it as such. I tried setting the HTTP status code to 500 as follows:

  response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Server Error"); 

front

  return mav; 

statement. Unfortunately, this returns an HTML page indicating an internal error instead of my JSON message. How can I return a JSON message and still indicate a server error (or some error) for the client? In particular, I expect the client error function in the AJAX call to be called and still be sent back to the message. FYI - I am using jQuery on the client side.

+4
source share
4 answers

I do not know exactly how you make requests to the server. But I will do so.

 @ExceptionHandler(Exception.class) @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = "your message") public void handleException(IllegalStateException ex, HttpServletResponse response) throws IOException { } 

Client side

 $.ajax({ type : "POST", url : urlString, data : params, dataType : 'json', success : function(data) { // do something} error: function (xhr, ajaxOptions, thrownError) { alert(xhr.status); //This will be 500 alert(xhr.responseText); // your message //do stuff } 
+9
source

In Spring 3.2, you can put your exception handler inside the annotated @ControllerAdvice class.

From Spring 3.2 documentation

Classes annotated with @ControllerAdvice may contain @ExceptionHandler , @InitBinder and @ModelAttribute , and they will apply to @RequestMapping methods in controller hierarchies, in contrast to the controller hierarchy in which they are declared. @ControllerAdvice is a component annotation that automatically identifies implementation classes through class scanning.

Thus, if your controllers are captured by the autoscanning of @Controller annotated classes, @ControllerAdvice should also work (if you scan @Controller classes with an explicit annotation expression, you may need to register this bean separately).

 @ControllerAdvice public class AppControllerAdvice{ @ExceptionHandler(Throwable.class) ResponseEntity<String> customHandler(Exception ex) { return new ResponseEntity<String>( "Custom user message", HttpStatus.INTERNAL_SERVER_ERROR); } 

Note that the text is part of the returned object, not a HTTP reason phrase.

+6
source

Here is how I did it.

 public class CustomExceptionResolver extends AbstractHandlerExceptionResolver { private static final Logger logger = Logger.getLogger(CustomExceptionResolver.class); protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try { response.reset(); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.setCharacterEncoding("UTF-8"); response.setContentType("text/json"); MappingJacksonJsonView view = new MappingJacksonJsonView(); Map<String, String> asd = new HashMap<String, String>(); asd.put("message", ex.getMessage()); view.setAttributesMap(asd); return new ModelAndView(view); } catch (Exception e) { logger.error("send back error status and message : " + ex.getMessage(), e); } return null; } 

And of course, in my json-servlet.xml file:

 <bean id="exceptionResolver" class="com.autolytix.common.web.CustomExceptionResolver"/> 
+4
source

Add the following code to frontcontrol

  @ExceptionHandler(Exception.class) public @ResponseBody MyErrorBean handleGeneralException(Exception e, HttpServletRequest request, HttpServletResponse response) { logger.info("Exception:" , e); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); MyErrorBean errorBean = new MyErrorBean(); errorBean.setStatus(MyConstants.ERROR_STATUS); return errorBean; }` 

Since you are using JSON, I assume a messageconverter will be configured in your code that will convert it to JSON. By setting the status and sending the bean, you can solve it.

0
source

All Articles