第一種方法,用包裝類封裝對象
實體類對象
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 這兩個對象的作用,怎樣寫能夠優雅,歡迎大家不吝賜教。