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.


Reply With Quote
