Announcement Announcement Module
Collapse
No announcement yet.
Posting XML to REST service, Not marshalled to object Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Posting XML to REST service, Not marshalled to object

    I am attempting to enhance my Controllers to accept/return XML in addition to Form/HTML data. I am using mvc:annotation-driven and I'm not clear on what exactly I need to configure to accept XML.

    I have configured a ContentNegotiatingViewResolver to return XML or HTML based on the Accept header and this works great. But if I POST XML then my controller method is called with a Customer object that has all elements set to null. What could be wrong? If it matters my application was generated with Roo, but I don't think this is a Roo issue.

    I have the following webmvc-config.xml

    Code:
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="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/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
    		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:oxm="http://www.springframework.org/schema/oxm"
    	xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:mvc="http://www.springframework.org/schema/mvc">
    				
    	<!-- The controllers are autodetected POJOs labeled with the @Controller annotation. -->
    	<context:component-scan base-package="com.foo" use-default-filters="false">
    		<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    	</context:component-scan>
    
    	<oxm:jaxb2-marshaller id="marshaller">
    		<oxm:class-to-be-bound name="com.foo.domain.Customer"/>
    	</oxm:jaxb2-marshaller>
    
    	<!-- Turns on support for mapping requests to Spring MVC @Controller methods
    	     Also registers default Formatters and Validators for use across all @Controllers -->
    	<mvc:annotation-driven/>
    	
    	<!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    		<property name="messageConverters">
    			<list>
    				<ref bean="marshallingHttpMessageConverter"/>
    			</list>
    		</property>
    	</bean> -->
    
    	<!-- register "global" interceptor beans to apply to all registered HandlerMappings -->
    	<mvc:interceptors>
    		<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
    		<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
    	</mvc:interceptors>
    	
    	<!-- selects a static view for rendering without the need for an explicit controller -->
    	<mvc:view-controller path="/login"/>
        <mvc:view-controller path="/index"/>
    	<mvc:view-controller path="/uncaughtException"/>
    	<mvc:view-controller path="/resourceNotFound"/>
    	<mvc:view-controller path="/dataAccessFailure"/>
    
    	<!-- Content negotiating view resolver definition -->
    	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    		<property name="mediaTypes">
    			<map>
    				<entry key="xml" value="application/xml"/>
    				<entry key="html" value="text/html"/>
    			</map>
    		</property>
    		<property name="defaultViews">
    			<list>
    				<bean class="org.springframework.web.servlet.view.xml.MarshallingView" p:marshaller-ref="marshaller"/>
    			</list>
    		</property>
    	</bean>
    	
    	<!-- Resolves logical view names returned by Controllers to Tiles; a view
    		 name to resolve is treated as the name of a tiles definition -->
    	<bean class="org.springframework.js.ajax.AjaxUrlBasedViewResolver" id="tilesViewResolver">
    		<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
    	</bean>
    
    	<!-- Configures the Tiles layout system -->
    	<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
    		<property name="definitions">
    			<list>
    				<value>/WEB-INF/layouts/layouts.xml</value>
    				<!-- Scan views directory for Tiles configurations -->
    				<value>/WEB-INF/views/**/views.xml</value>
    			</list>
    		</property>
    	</bean>
    
    	<!-- Resolves localized messages*.properties and application.properties files in the application to	allow for internationalization. 
    		The messages*.properties files translate Roo generated messages which are part of the admin interface, the application.properties
    		resource bundle localizes all application specific messages such as entity names and menu items. -->
    	<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource" p:basenames="WEB-INF/i18n/messages,WEB-INF/i18n/application" p:fallbackToSystemLocale="false"/>
    	
    	<!-- store preferred language configuration in a cookie -->
    	<bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" id="localeResolver" p:cookieName="locale"/>	
    	
    	<!-- resolves localized <theme_name>.properties files in the classpath to allow for theme support -->
    	<bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource"/>
    	
    	<!-- store preferred theme configuration in a cookie -->
    	<bean class="org.springframework.web.servlet.theme.CookieThemeResolver" id="themeResolver" p:cookieName="theme" p:defaultThemeName="standard"/>
    
    	<!-- This bean resolves specific types of exceptions to corresponding logical - view names for error views. 
    	     The default behaviour of DispatcherServlet - is to propagate all exceptions to the servlet container: 
    	     this will happen - here with all other types of exceptions. -->
    	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" p:defaultErrorView="uncaughtException">
    		<property name="exceptionMappings">
    			<props>
    				<prop key=".DataAccessException">dataAccessFailure</prop>
    				<prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</prop>
    				<prop key=".TypeMismatchException">resourceNotFound</prop>
    				<prop key=".MissingServletRequestParameterException">resourceNotFound</prop>
    			</props>
    		</property>
    	</bean>
    	
    	<!-- allows for integration of file upload functionality -->
    	<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"/>
    </beans>

    My controller method I am posting to looks like this:

    Code:
        @RequestMapping(value = "/customer", method = RequestMethod.POST)
        public String create(/*@Valid*/ Customer customer, BindingResult result, ModelMap modelMap) {
            if (customer == null) throw new IllegalArgumentException("A customer is required");
            if (result.hasErrors()) {
                modelMap.addAttribute("customer", customer);
                return "customer/create";
            }
            customer.persist();
            return "redirect:/customer/" + customer.getId();
        }

    Any and all help is appreciated...Thanks.

  • #2
    I resolved this. The issue was that I did not realize that I needed to use @RequestBody on the method paramater for the message converter to be invoked. Since @RequestBody is not required for Form input with data binding.

    I ended up with two methods that process POSTs. One is for the Form input and uses the @Valid annotation, the other is for the XML input and uses @RequestBody.

    Comment


    • #3
      ^^

      Posting the code will be helpful for some who is looking for the exact issue.

      Comment

      Working...
      X