java Spring MVC 方法处理 json 和表单参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13857641/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring MVC method handling json and form params
提问by Chakravarthi Bharathi
I want the handle the content types application/x-www-form-urlencoded and application/json in single spring mvc method.
我想要在单个 spring mvc 方法中处理内容类型 application/x-www-form-urlencoded 和 application/json 。
I've a requirement in rest service to accept input as form parameters or json. I can achieve this by writing two methods. Either form params or json, the response will be always json.
我在休息服务中要求接受输入作为表单参数或 json。我可以通过编写两种方法来实现这一点。无论是 params 还是 json,响应总是 json。
@RequestMapping (method = RequestMethod.POST, produces = {"application/json"},
consumes = {"application/x-www-form-urlencoded"})
public @ResponseBody Book createBook(Book book)
throws Exception {
return book;
}
@RequestMapping (method = RequestMethod.POST, produces = {"application/json"},
consumes = {"application/json"})
public @ResponseBody Book createBookJSON(@RequestBody Book book)
throws Exception {
return book;
}
Is it possible to combine these two methods into one and make it work? Any help will be much appreciated.
是否可以将这两种方法合二为一并使其起作用?任何帮助都感激不尽。
Edit
编辑
I've Implemented the same, my controllers and configuration are given below, but when I send json request I get null values as response.
我已经实现了相同的,我的控制器和配置如下,但是当我发送 json 请求时,我得到空值作为响应。
When I send the form params it is working fine. Help me to find out the issue.
当我发送表单参数时,它工作正常。帮我找出问题。
Controller method
控制器方法
@RequestMapping (method = RequestMethod.POST, produces = {"application/json", "application/xml"}, consumes = {"application/x-www-form-urlencoded", "application/json"})
public @ResponseBody Book createBook(Book book)
throws Exception {
return book;
}
servlet-context
servlet 上下文
<mvc:view-controller path="/" view-name="index"/>
<context:annotation-config />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml" />
<entry key="json" value="application/json" />
</map>
</property>
<property name="defaultViews">
<list>
<!-- JSON View -->
<bean class="org.springframework.web.servlet.view.json.MappingHymansonJsonView" />
<!-- JAXB XML View -->
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<ref bean="jaxb2Marshaller" />
</constructor-arg>
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
<property name="order" value="1" />
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingHymansonHttpMessageConverter" >
<property name="supportedMediaTypes" value="application/json"/>
</bean>
<bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="jaxb2Marshaller" />
<property name="unmarshaller" ref="jaxb2Marshaller" />
<property name="supportedMediaTypes" value="application/xml"/>
</bean>
<bean class = "org.springframework.http.converter.FormHttpMessageConverter">
<property name="supportedMediaTypes" value = "application/x-www-form-urlencoded" />
</bean>
<bean class = "org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
</bean>
</list>
</property>
</bean>
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" >
<property name="classesToBeBound">
<list>
<value>com.lt.domain.Book</value>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2" />
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
回答by G-Man
@RequestMapping (method = RequestMethod.POST)
public Book createBook(Book book)
throws Exception {
return book;
}
consumes takes a string array of whatever it can consume, spring bean binding should take care of the rest. The problem might be you haven't set up bean binding correctly in order to marshall and unmarshall json automaticaly. using @RequestBody and @RepsonseBody isn't the best option imho.
消费接受它可以消费的任何字符串数组,spring bean 绑定应该处理其余的。问题可能是您没有正确设置 bean 绑定以便自动编组和解组 json。恕我直言,使用@RequestBody 和@RepsonseBody 并不是最好的选择。
make sure Hymanson is added to your dependencies
确保将 Hymanson 添加到您的依赖项中
<dependency>
<groupId>org.codehaus.Hymanson</groupId>
<artifactId>Hymanson-mapper-asl</artifactId>
<version>latest</version>
</dependency>
and use a contentnegotiatingviewresolver
并使用 contentnegotiatingviewresolver
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="mediaTypes"> <map> <entry key="htm" value="text/htm"/> <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.BeanNameViewResolver"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <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.MappingHymansonJsonView"/> </list> </property> </bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="mediaTypes"> <map> <entry key="htm" value="text/htm"/> <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.BeanNameViewResolver"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <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.MappingHymansonJsonView"/> </list> </property> </bean>
make sure the accept headers are set in your client application to the needed values. You also should be able to drop all producing and consuming data in the requestmethod annotation
确保在您的客户端应用程序中将接受标头设置为所需的值。您还应该能够删除 requestmethod 注释中的所有生产和消费数据
回答by David
If you want spring to convert from JSON to your object automatically you will have to use @RequestBody
. If you don't use it, the values will not be bound and all parameters are null as you described when sending in JSON.
如果您希望 spring 自动从 JSON 转换为您的对象,则必须使用@RequestBody
. 如果您不使用它,则不会像您在 JSON 中发送时描述的那样绑定值并且所有参数都为空。
If you use @RequestBody
: Behind the scenes the conversion is done using MessageConverters, as described in the spring documentation: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-requestbody
如果您使用@RequestBody
:在幕后使用 MessageConverters 完成转换,如 spring 文档中所述:http: //static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html #mvc-ann-requestbody
You are correctly configuring the MappingHymansonHttpMessageConverter
, which does the translation from JSON to your object.
您正在正确配置MappingHymansonHttpMessageConverter
,它可以将 JSON 转换为您的对象。
What is missing is a translation from form data to your object:
You have a FormHttpMessageConverter
registered, but according to the documentation this does not what you expect it to do. It translates a request using x-www-form-urlencode to a MultiValueMap<String, String>
and not to your custom object.
缺少的是从表单数据到您的对象的转换:您已FormHttpMessageConverter
注册,但根据文档,这不是您期望的。它将使用 x-www-form-urlencode 的请求转换为 aMultiValueMap<String, String>
而不是您的自定义对象。
My current understanding is that you would have to write something similar to the MappingHymansonHttpMessageConverter
but only capable of handling form data.
我目前的理解是,您必须编写类似于MappingHymansonHttpMessageConverter
但只能处理表单数据的内容。