爲了能夠在controller中獲取多個對象,我定義了兩個@RequestBody的參數,結果報錯:
I/O error while reading input message; nested exception is java.io.IOException: Stream closed
只用一個@RequestBody參數,另外一個參數用@RequestParam,則controller接收到的參數都爲null。
於是引出了接下來的話題,SpringMVC如何接收多個對象參數?
1、定義包裝類,使用包裝類對象
定義三個類,其中一個爲包裝類
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;
}
}
controller方法
@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);
}
});
});
2、使用Map對象接收
@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";
}
3、使用自定義的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);
}
});
});
轉載自:
https://blog.csdn.net/pozhenzi9010/article/details/80559186