Google App Engine + JAVA + Spring + REST + Mapping Exceptions to Errors for JSON

error_screenshot

Objective

We are talking REST+JSON from browser to the server and back, so we need to report errors nicely. Exception thrown on the server have to be converted to error messages and transmitted to the client in JSON format. Luckily there is a very elegant solution for this in Spring.

HandlerExceptionResolver interface

Spring provides a very handy HandlerExceptionResolver interface for mapping exceptions to views. If you check the documentation (and you should) you will notice that where are couple exception handlers already implemented, but we will create our own. Just because we can.

Implementing JsonExceptionResolver

Our implementation is very basic, but can be enhanced to return more data about where the exception occurred, etc. To implement HandlerExceptionResolver interface we need to provide one method:

package com.lureto.rjf;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

public class JsonExceptionResolver implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
						 Object handler, Exception exception ) {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("MappingJacksonJsonView");
		mav.addObject("error", exception.getMessage() );
		return mav;
	}

}

resolveException method returns ModelAndView, to which we add a model object “error” holding the message from the exception, and set the view name. The view in this case is MappingJacksonJsonView. Setting error to the exception message comes in handy when we need to return an error from lets say “saveUser” action – we simply throw exception from the controller method like this: throw new Exception(“USER_EMAIL_NOT_UNIQUE”);

Next we need to hook in our exception resolver into Spring context like this:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
  <property name="mediaTypes">
    <map>
      <entry key="json" value="application/json" />
    </map>
  </property>
  <property name="defaultContentType" value="application/json" />
  <property name="defaultViews">
    <list>
      <bean name="MappingJacksonJsonView"
        class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
    </list>
  </property>
</bean>
   
<bean id="exceptionResolver" class="com.lureto.rjf.JsonExceptionResolver" />

We simply define the bean and name call it exceptionResolver. Spring detects implemented interface and automagicaly routes exceptions to this resolver. We needed to modify our view definition – we gave it name, so we can reference it in the code – “MappingJacksonJsonView”.

Conclusion

Trapping exceptions on the server and converting them to JSON error messages can be done with 4 lines of conde and 1 line of xml. You can use this approach to map all sorts of exceptions to custom error jsp pages, JSON errors or any other view type. Your application users do not have to see an ugly Tomcat 500 error page.

2 thoughts on “Google App Engine + JAVA + Spring + REST + Mapping Exceptions to Errors for JSON

  1. Thanks for pointing out how to use the exception resolver, but this aproach works if there is only JsonView (in your case it is named as MappingJacksonJsonView). Consider adding another media type (e.g. application/xml or text/plain), map for that content type a view. If there comes a request that accepts content type other than json, your exception resolver still will respond in a json format. This is beacause JsonExceptionResolver sets specifically JsonView.

Leave a Reply

Your email address will not be published. Required fields are marked *