在SpringMVC中使用@RequestBody和@ModelAttribute注解时遇到了很多问题,现记录下来。
@ModelAttribute这个注解主要是将客户端请求的参数绑定参数到一个对象上,不用将很多参数@RequestParam或是@PathVariable。
但是在使用过程中遇到了问题,
第一次Html端请求代码如下,请求方式1
// 简单键值对 var data = { productTypeIds : vproducttypeid, channelTypeId : vchanneltypeid, userId : 1, }; // 提交保存 $.ajax({ "type" : "POST", "url" : chainelUtil.URL.ACTION_IMPORT, "data" : data, "success" : function(data) { bootbox.alertTimeout("创建成功!"); }, "error" : function(data) { bootbox.alertTimeout("创建失败!"); } });
Controller代码如下:
@RequestMapping(value = "/importstorestore", method = RequestMethod.POST) @ResponseBody public Object importStoreToStoreTree(@ModelAttribute StoreStoreRelationVO storeRelationVO ) { }
StoreStoreRelationVO代码如下:
@Component public class StoreStoreRelationVO implements Serializable{ /** * */ private static final long serialVersionUID = 1L; // 渠道关系实体 private StoreStoreEntity storeStoreEntity; // 渠道类型Id private String channelTypeId; // 商品分类Id字符串以","分割 private String productTypeIds; // 商品分类Id List private List<String> productTypeIdList; // 区域Id,目前版本可能用不上 private String regionId; // 当前登陆用户 private String userId; // 省略getter setter }
StoreStoreEntity如下:
@Entity @Table(name = "base_store_store") public class StoreStoreEntity implements Serializable{ /** * */ private static final long serialVersionUID = 1L; @Id @Column @GenericGenerator(name = "idGenerator", strategy = "increment") @GeneratedValue(generator = "idGenerator") private Long id; // 上级id private Long upstoreid; // 下级id private Long downstoreid; // 所属渠道id private Long channelid; // 省略getter 和 setter }
如上的请求没问,服务器端可以接受到数据。
但是如果将请求的参数修改为如下,对象中组合对象,因为StoreStoreRelationVO 有个属性是StoreStoreEntity
// StoreStoreEntity
var storeStore = { upstoreid : vupstoreid, downstoreid:vcurrentstoreid, channelid:1, }; // StoreStoreRelationVO var data = { storeStoreEntity:storeStore, productTypeIds : vproducttypeid, channelTypeId : vchanneltypeid, userId : 1, };
如果用请求方式1请求,直接报错
HTTP Status 404 -
type Status report
message
description The requested resource is not available.
Apache Tomcat/7.0.52
我将Ajax请求参数改为Json,如下,请求方式2
// 提交保存 $.ajax({ "type" : "POST", "dataType" : 'json', "contentType" : "application/json;charset=UTF-8", "url" : chainelUtil.URL.ACTION_IMPORT,"data" : JSON.stringify(data), "success" : function(data) { var messagetext = $('#message'); messagetext.html("已经向系统成功提交申请,创建成功!"); bootbox.alertTimeout("创建成功!"); }, "error" : function(data) { var messagetext = $('#message'); messagetext.html("服务器繁忙,请重新提交!"); bootbox.alertTimeout("创建失败!"); } });
服务器端不变,这样不报错了,但是storeRelationVO却接收不到数据,不能自动装载。
我将Controller中的@ModelAttribute修改为@RequestBody
storeRelationVO可以正常接受到数据。
----------------------------------------------------------------------
为什么Json就能正确成功呢,我又将Ajax改回到最初格式,参数格式不设定
$.ajax({ "type" : "POST", "url" : chainelUtil.URL.ACTION_IMPORT, "data" : data, "success" : function(data) { bootbox.alertTimeout("创建成功!"); }, "error" : function(data) { bootbox.alertTimeout("创建失败!"); } });
结果不出所料,报错,415 Unsupported Media Type
HTTP Status 415 -
type Status report
message
description The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.
Apache Tomcat/7.0.52
看来用@RequestBody,需要传Json数据
----------------------------------
我将请求参数稍微改了一下,其余不变
var storeStore = { upstoreid : vupstoreid, downstoreid:vcurrentstoreid, channelid:1, }; var data = { storeStoreEntity:storeStore, productTypeIds : vproducttypeid, channelTypeId : vchanneltypeid, userid : 1, };
结果报错,这个错我找了好久啊,最后发现一个大小写错误,userid应该对应实体中的userId,一个i应该是大写,所以请求参数不区分大小写!
HTTP Status 400 -
type Status report
message
description The request sent by the client was syntactically incorrect.