为了能够在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