springMVC Controller接收 多物件的json資料
阿新 • • 發佈:2019-01-30
第一種方法,用包裝類封裝物件
實體類物件
public class User { private int id; private String userName; private String realName; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } @Override public String toString() { return "User{" + "id=" + id + ", userName='" + userName + '\'' + ", realName='" + realName + '\'' + '}'; } } public class Info { private int id; private String address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Info{" + "id=" + id + ", address='" + address + '\'' + '}'; } } public class RequestParam { private User user; private Info info; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Info getInfo() { return info; } public void setInfo(Info info) { this.info = info; } }
定義了三個實體 RequestParam裡面又封裝了User類和Info類
JAVA程式碼
@RequestMapping(value = "/show",method = RequestMethod.POST)
public String show(@RequestBody RequestParam param){
User user = param.getUser();
Info info = param.getInfo();
return user.toString();
}
前臺程式碼
$("#ok2").click(function(){ var json = {"user":{"id":9527,"userName":"zcy","realName":"鋼鐵俠"},"info":{"id":998,"address":"紐約"}}; $.ajax({ url:"http://localhost:8080/more/show", type:"post", cache:false, contentType:"application/json", data:JSON.stringify(json), success:function(data){ alert(data); } }); });
可以成功接收到物件,但是顯得沒有那麼優雅,每次請求資料不同都要另外寫一個包裝類,顯得很麻煩。
第二種方法,用Map物件接收 更加簡單粗暴
JAVA程式碼
@RequestMapping(value = "/show") public String test(@RequestBody Map<String,Object> map){ // 拿到Object之後 再做轉換為實體即可 可以用FastJson Object user = map.get("user"); Object info = map.get("info"); return "success"; }
也不夠方便 每個物件還要再做一次轉換
第三種方法,使用自定義的HandlerMethodArgumentResolver
自定義註解 加在控制器的引數前作為標記
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JsonObject {
}
自定義處理類 實現HandlerMethodArgumentResolver介面
public class JsonObjectArgResolverHandler implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(JsonObject.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory) throws Exception {
// 獲取Controller中的引數名
String name = methodParameter.getParameterName();
// 獲取Controller中引數的型別
Class clazz = methodParameter.getParameterType();
Object arg = null;
// 獲取該引數實體的所用屬性
Field[] fields = clazz.getDeclaredFields();
// 例項化
Object target = clazz.newInstance();
// 建立WebDataBinder物件 反射 遍歷fields給屬性賦值
WebDataBinder binder = webDataBinderFactory.createBinder(nativeWebRequest,null,name);
for (Field field:fields){
field.setAccessible(true);
String fieldName = field.getName();
Class<?> fieldType = field.getType();
// 在request中 多物件json資料的key被解析為 user[id] user[realName] info[address] 的這種形式
String value = nativeWebRequest.getParameter(name + "[" + fieldName + "]");
arg = binder.convertIfNecessary(value,fieldType,methodParameter);
field.set(target,arg);
}
return target;
}
}
註冊自己寫的處理類
@Component
public class MyWebAppConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
// 配置自定義接收引數
WebMvcConfigurer.super.addArgumentResolvers(resolvers);
resolvers.add(new JsonObjectArgResolverHandler());
}
}
Controller
@RequestMapping(value = "/custom")
public String custom(@JsonObject User user, @JsonObject Info info){
System.out.println(user.toString());
System.out.println(info.toString());
return "success";
}
前臺程式碼
$("#ok2").click(function(){
var json = {"user":{"id":9527,"userName":"zcy","realName":"鋼鐵俠"},"info":{"id":998,"address":"紐約"}};
$.ajax({
url:"http://localhost:8080/more/custom",
type:"post",
cache:false,
// 直接傳josn物件 這裡與上文不同
data:json,
success:function(data){
alert(data);
}
});
});
第三種方式相對比較好 但我有幾點還是沒明白
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory)這個方法中的 ModelAndViewContainer和webDataBinderFactory 這兩個物件的作用,怎樣寫能夠優雅,歡迎大家不吝賜教。