在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.
Apache Tomcat/7.0.52