背景:
最近项目中使用SpringMVC,需要从前端接收JSON格式的请求,在后端自动转成一个与JSON格式相同的对象。
由于是一个老项目,Spring的版本是3.2.7。
问题:POST or GET
这个请求,是一个计算类型的请求,不涉及数据的修改,从意义上来说的角度应该是一个 GET 请求。
但是请求报文设计时要求高度的灵活性,传递的属性都是以 kind-value 形式,如:
{
"kind":"premium",
"value":"1000"
}
而不是传统的模式:
{
"premium":"1000"
}
所以报文的长度会显得非常的长。
以下是最初的后端 Controller 设计:
1 @Controller 2 @RequestMapping(value = "/PMS/Groovy") 3 public class GetGroovyValueController { 4 5 @RequestMapping(value = "/Discount", method = RequestMethod.POST) 6 @ResponseBody 7 public ResponseVO<String> getDiscount(LiabilityVO liabilityVO) { 8 // 具体代码不详述了 9 } 10 }
会出现一个和特殊的情况:
1. GET 请求接收的报文长度,根据浏览器的不同,是有限制的,而客户要求的 IE 浏览器所支持的长度有限。
2. 报文传递的 JSON 格式,与 LiabilityVO 这个模型是匹配的,但是数据并不能完整的传递到后台。(这种情况在使用第二种JSON格式的时候不会出现)
针对以上2个情况,研究出的解决方案如下:
1. 改用 POST 请求,这么做虽然与设计的意义有些违背,在安全性上考虑也略显欠缺,但是这是目前想到的最佳解决方案,在不改变模型的情况下。
2. 分别作出如下修改:
- AJAX 请求格式,增加 contentType: "application/json"。
- webmvc-config.xml 文件中 MappingJackson2HttpMessageConverter 的配置。
- Controller 中参数增加 @RequestBody注解。
话不多说,直接上代码:
1 @Controller 2 @RequestMapping(value = "/PMS/Groovy") 3 public class GetGroovyValueController { 4 5 @RequestMapping(value = "/Discount", method = RequestMethod.POST) 6 @ResponseBody 7 public ResponseVO<String> getDiscount(@RequestBody LiabilityVO liabilityVO) { 8 // 具体代码不详述了 9 } 10 }
1 <property name="messageConverters"> 2 <list> 3 <bean id="utf8StringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"> 4 <property name="supportedMediaTypes"> 5 <list> 6 <value>text/plain;charset=UTF-8</value> 7 </list> 8 </property> 9 </bean> 10 <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 11 <!-- 解决 HttpMediaTypeNotAcceptableException: Could not find acceptable representation --> 12 <property name="supportedMediaTypes"> 13 <list> 14 <value>text/html;charset=UTF-8</value> 15 <!-- 以下2个是新增的 --> 16 <value>application/x-www-form-urlencoded;charset=UTF-8</value> 17 <value>application/json;charset=UTF-8</value> 18 </list> 19 </property> 20 </bean> 21 </list> 22 </property>
1 $.ajax({ 2 type: 'POST', 3 url: "${pageContext.request.contextPath}/PMS/Groovy/Discount.jspx", 4 data: JSON.stringify(str), 5 dataType: 'json', 6 contentType: "application/json", 7 cache: false, 8 success: function (res) { 9 10 }, 11 error: function (data) { 12 alert('失败'); 13 } 14 });
Over,问题解决!