Announcement Announcement Module
Collapse
No announcement yet.
Marshalling exceptions JSON Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Marshalling exceptions JSON

    Hello, I started developing a very simple REST webservice with Spring 3, starting from scratch with a new Maven archetype. Following the documentation I found on the web I managed to marshall and unmarshall java objects to/from JSON using Jackson and RestTemplate. The problem is that I can't figure out how to manage exceptions, since when they arise i get an html response and not the expected JSON.

    Here is my code and configuration. My dispatcher servlet:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:mvc="http://www.springframework.org/schema/mvc"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
                               http://www.springframework.org/schema/beans/spring-beans.xsd
                               http://www.springframework.org/schema/context 
                               http://www.springframework.org/schema/context/spring-context.xsd
                               http://www.springframework.org/schema/mvc 
    						   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    
    	<mvc:annotation-driven/>
    	<context:component-scan base-package="com.mypackage" />
    	<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    		<property name="messageConverters">
    			<list>
    				<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    			</list>
    		</property>
    	</bean>
    	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
    	</bean>
    
    	<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="viewResolvers">
    			<list>
    				<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
    			</list>
    		</property>
    		<property name="defaultViews">
    			<list>
    				<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
    			</list>
    		</property>
    	</bean>
    	
    </beans>
    My controller:

    Code:
    import org.apache.log4j.Logger;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.mypackage.exception.PrizeNotFoundException;
    import com.mypackage.pojo.Prize;
    import com.mypackage.pojo.User;
    import com.mypackage.services.MyServices;
    
    @Controller
    public class ServiceController {
    	private Logger log = Logger.getLogger(ServiceController.class);
    	
    	@Autowired
    	private MyServices myServices;
    	
    	@RequestMapping(method=RequestMethod.GET, value="/prize")
    	public @ResponseBody Prize getPrize() {
    		return myServices.getRandomPrize();
    	}
    	
    	@RequestMapping(method=RequestMethod.GET, value="/prizes")
    	public @ResponseBody List<Prize> getRandomPrizes() {
    		return myServices.getRandomPrizes();
    	}
    	
    	@RequestMapping(method=RequestMethod.GET, value="/user")
    	public @ResponseBody User getRandomUser() {
    		return myServices.getUser();
    	}
    	
    	@RequestMapping(method=RequestMethod.GET, value="/exception")
    	public @ResponseBody Prize getPrizeNotFoundException() throws PrizeNotFoundException {
                    // this method has an hard coded exception thrown
    		return myServices.getExceptionPrize();
    	}
    	
    	@ExceptionHandler(PrizeNotFoundException.class)
    	public @ResponseBody PrizeNotFoundException handlePrizeNotFoundException(PrizeNotFoundException ex) {
    		return new PrizeNotFoundException("ciao");
    	}
    	
    }
    If I do a curl to /user (curl -i -H "Accept: application/json" http://localhost:8080/rest-services/app/user) I get:

    Code:
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    Content-Type: application/json;charset=UTF-8
    Transfer-Encoding: chunked
    Date: Fri, 28 Jan 2011 09:21:03 GMT
    
    {"name":"imm_user","id":1,"prizes":[{"name":"prize_name_1","id":1},{"name":"prize_name_2","id":2}]}
    But if I do a curl to /exception (curl -i -H "Accept: application/json" http://localhost:8080/rest-services/app/exception), I get:

    Code:
    HTTP/1.1 500 Internal Server Error
    Server: Apache-Coyote/1.1
    Content-Type: text/html;charset=utf-8
    Content-Length: 3198
    Date: Fri, 28 Jan 2011 09:22:49 GMT
    Connection: close
    
    <html><head><title>Apache Tomcat/6.0.26 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The server encountered an internal error () that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.mypackage.exception.PrizeNotFoundException: Thrown PrizeNotFoundException
    	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:659)
    	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    </pre></p><p><b>root cause</b> <pre>com.mypackage.exception.PrizeNotFoundException: Thrown PrizeNotFoundException
    	com.mypackage.MyServicesImpl.getExceptionPrize(MyServicesImpl.java:34)
    	com.mypackage.controller.ServiceController.getPrizeNotFoundException(ServiceController.java:41)
    	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	java.lang.reflect.Method.invoke(Method.java:616)
    	org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710)
    	org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167)
    	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
    	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
    	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
    	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
    	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
    	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    </pre></p><p><b>note</b> <u>The full stack trace of the root cause is available in the Apache Tomcat/6.0.26 logs.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/6.0.26</h3></body></html>
    Could you give me a hint on how to solve this problem? Thanks in advace.
    Fabio
Working...
X