springMVC Controller接收 多對象的json數據

第一種方法,用包裝類封裝對象

實體類對象

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 這兩個對象的作用,怎樣寫能夠優雅,歡迎大家不吝賜教。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章