SpringMVC接收多个对象参数

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

发布了28 篇原创文章 · 获赞 28 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/xujinggen/article/details/104565425
今日推荐