Announcement Announcement Module
Collapse
No announcement yet.
Annotation-Driven JSON response Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Annotation-Driven JSON response

    Hi,

    I try to response JSON out of controller. After some google action I found this: http://blog.springsource.com/2010/01...in-spring-3-0/
    Ok this look pretty, but its dos not work.
    I tryed to get Content by
    Code:
    	    $.ajax({
    	    	url: "/WebClient/login/register/",
    	        error: function( XMLHttpRequest, textStatus, errorThrown ) {
    	            console.log( errorThrown );
    	        },
    	        success: function( data, textStatus, XMLHttpRequest ) {
    	            console.log( data );
    	        }
    	    });
    and get follow error:
    Code:
    GET http://localhost:8080/WebClient/login/register/ 406 (Not Acceptable)
    Not Acceptable
    description The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ().
    Here my controller:
    Code:
    package de.tudresden.mmt.kpmi.web.user;
    
    import java.util.Map;
    import java.util.TreeMap;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    public class AjaxRegisterController {
    	/**
    	 * This method handles the /login/register request and returns the needed jsp file.
    	 * 
    	 * @return login/register.jsp	
    	 */
    
    	@RequestMapping(value = "/login/register", method = RequestMethod.GET)
    	public @ResponseBody Map<String, String> getRegisterPage(ModelAndView model) {		
    		model.setViewName("login/register");
    
    		Map<String, String> response = new TreeMap<String, String>();
    		response.put("Title", "FooBaa");
    
    		return response;
    	}
    }
    and my servlet.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:beans="http://www.springframework.org/schema/beans"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
    	
    	<!-- Enables the Spring MVC @Controller programming model -->
    	<annotation-driven />
    
    	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    	<resources mapping="/resources/**" location="/resources/" />
    
    	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<beans:property name="prefix" value="/WEB-INF/jsp/" />
    		<beans:property name="suffix" value=".jsp" />
    	</beans:bean>
    	
    	<context:component-scan base-package="de.tudresden.mmt.kpmi.web" />
    	
    	
    </beans:beans>
    Any help? Thank you.

    Zack

  • #2
    Getting JSON results from controller

    Hey Zack,

    I assume you're wanting to get JSON from your requests to /login/register.
    I'm new at RESTful in Spring but I hope the following helps.

    I believe what you're missing is including the MappingJacksonHttpMessageConverter

    In your servlet.xml you need to include the view resolver to handle transporting JSON data:
    Code:
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
      <property name="mediaTypes">
        <map>
          <entry key="json" value="application/json"/>
        </map>
      </property>
      <property name="defaultViews">
        <list>
          <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
            <property name="prefixJson" value="true"/>
          </bean>
        </list>
      </property>
    </bean>
    In your controller:
    Code:
    /**
     * This method return the login and register content in map;
     * @return Map<String, String>	
     **/
    @RequestMapping(value = "/login/register", method = RequestMethod.GET)
    public Map<String, String> getRegisterPage() {		
    	Map<String, String> response = new TreeMap<String, String>();
    	response.put("Title", "FooBaa");
    
    	return response;
    }
    For some reason the @ResponseBody was causing the 406. I'm not familiar enough with why.

    However, I made these changes local to my environment, ran it and saw the following results:
    Code:
    {"Title":"FooBaa"}
    Good luck.

    Comment


    • #3
      Hi Chris,

      thanks for your solution. I got problems by appending my servlet.xml.

      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <beans:beans xmlns="http://www.springframework.org/schema/mvc"
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xmlns:beans="http://www.springframework.org/schema/beans"
      	xmlns:context="http://www.springframework.org/schema/context"
      	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
      		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
      
      	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
      	
      	<!-- Enables the Spring MVC @Controller programming model -->
      	<annotation-driven />
      
      	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
      	<resources mapping="/resources/**" location="/resources/" />
      
      	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
      	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      		<beans:property name="prefix" value="/WEB-INF/jsp/" />
      		<beans:property name="suffix" value=".jsp" />
      	</beans:bean>
      	
      	<context:component-scan base-package="de.tudresden.mmt.kpmi.web" />
      	
      	<!-- Transporting JSON - Data -->
      	<beans:bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
      		<beans:property name="mediaTypes">
      	    	<beans:map>
      	      		<beans:entry key="json" value="application/json"/>
      	    	</beans:map>
      	  	</beans:property>
      	  	<beans:property name="defaultViews">
      	    	<beans:list>
      	      		<beans:bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
      	        		<beans:property name="prefixJson" value="true"/>
      	      		</beans:bean>
      	    	</beans:list>
      	  	</beans:property>
      	</beans:bean>	
      </beans:beans>
      After changing to this, I got follow error after starting:
      Code:
      org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.view.ContentNegotiatingViewResolver#0' defined in ServletContext resource [/WEB-INF/spring-ws-servlet.xml]: Cannot create inner bean 'org.springframework.web.servlet.view.json.MappingJacksonJsonView#1695d856' of type [org.springframework.web.servlet.view.json.MappingJacksonJsonView] while setting bean property 'defaultViews' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.view.json.MappingJacksonJsonView#1695d856' defined in ServletContext resource [/WEB-INF/spring-ws-servlet.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.web.servlet.view.json.MappingJacksonJsonView]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/codehaus/jackson/map/ObjectMapper
      Thank you,

      Zack

      Comment


      • #4
        NoClassDefFoundError

        Zack,

        Typically a NoClassDefFoundError is because you're missing a crucial library. In this case the codehaus library which contains the MappingJacksonJsonView. Download HERE

        You may get another NoClassDefFoundError after including this library in your classpath. Just follow the rabbit from there...

        Make your servlet.xml look like this:
        Code:
        <?xml version="1.0" encoding="UTF-8"?>
        <beans: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:aop="http://www.springframework.org/schema/aop"
        	xmlns:context="http://www.springframework.org/schema/context"
        	xmlns:tx="http://www.springframework.org/schema/tx"
        	xmlns:beans="http://www.springframework.org/schema/beans"
        	xsi:schemaLocation="
        			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        			http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
        			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
        
        	<!-- Find the controllers. -->
        		<context:component-scan base-package="de.tudresden.mmt.kpmi.web" />
        
        	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        		<property name="mediaTypes">
        			<map>
        				<entry key="html" value="text/html" />
        				<entry key="json" value="application/json" />
        			</map>
        		</property>
        		<property name="viewResolvers">
        			<list>
        				<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        					<property name="viewClass"
        						value="org.springframework.web.servlet.view.JstlView" />
        					<property name="prefix" value="/WEB-INF/jsp/" />
        					<property name="suffix" value=".jsp" />
        				</bean>
        			</list>
        		</property>
        		<property name="defaultViews">
        			<list>
        				<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
        					<property name="prefixJson" value="true" />
        				</bean>
        			</list>
        		</property>
        	</bean>
        </beans:beans>
        I don't believe you need to have both InternalResourceViewResolver and ContentNegotiatingViewResolver.

        The annotated controller method:
        Code:
        /**
         * This method handles the /login/register request and returns the needed jsp file.
         * 
         * @return login/register.jsp	
         */
        @RequestMapping(value = "/login/register", method = RequestMethod.GET)
        public Map<String, String> getRegisterPage() {		
        	Map<String, String> response = new TreeMap<String, String>();
        	response.put("Title", "FooBaa");
        		return response;
        }
        The JSON call:
        Code:
        http://localhost/yourapp/yourservlet/login/register
        Should result:
        Code:
        {"Title":"FooBaa"}
        Good luck!

        Comment


        • #5
          Thanks, its works.

          Comment

          Working...
          X