SpringMVC - @RequestJson之HandlerMethodArgumentResolver 从入门到青铜(六)

简介: SpringMVC - @RequestJson之HandlerMethodArgumentResolver 从入门到青铜(六)

解决方案

1、第一种方案

在服务启动时,动态替换掉MapMethodProcessor#supportsParameter的字节码。

@Override
public boolean supportsParameter(MethodParameter parameter) {
  if(parameter.hasParameterAnnotation(RequestJson.class))
  {
    return false;
  }
  return Map.class.isAssignableFrom(parameter.getParameterType());
}

使用javassist可以实现这一点,但是这样去做,代码复杂性较高。“任何一个功能的实现,都要想办法降低代码复杂性”。


第二种方案


首先删除WebConfig,让spring不再自动的将自定义解析器加到RequestMappingHandlerAdapter的解析器容器中;然后我们通过下面的方式手动的将RequestJsonHandlerMethodArgumentResolver加载到RequestMappingHandlerAdapter的解析容器中。(通过这样的方式,我们可以任意的指定解析器的顺序)。


@Configuration
public class MethodArgumentResolver {
    @Autowired
    private RequestMappingHandlerAdapter adapter;
    @PostConstruct
    public void injectSelfMethodArgumentResolver() {
        List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>();
        argumentResolvers.add(new RequestJsonHandlerMethodArgumentResolver());
        argumentResolvers.addAll(adapter.getArgumentResolvers());
        adapter.setArgumentResolvers(argumentResolvers);
    }
}

Ps:XML配置的话,思路类似,但是会出现一个问题,极有可能会影响其它参数解析原本并不冲突的解析器,导致这个功能OK了,另一个功能又崩了的局面,所以还有最后一种方案(推荐)。


第三种方案


此处我们封装一个类似JSONObject的实体类MapWrapper来替代Map原型解决,可以通过MapWrapper.getMapWrapper()拿到我们需要的Map

package com.luxsuen.requestjson.util;
import com.alibaba.fastjson.JSONObject;
public class MapWrapper {
    private JSONObject jsonObject;
    public MapWrapper(JSONObject jsonObject) {
        this.jsonObject = jsonObject;
    }
    public JSONObject getMapWrapper() {
        return jsonObject;
    }
}

五、测试项目

package com.luxsuen.requestjson.entity;
import java.util.Date;
public class User {
    private Integer userId;
    private String userAccount;
    private String userPassword;
    private String userRemark;
    private Byte userDel;
    private Date userCreatetime;
    private Date userUpdatetime;
    public User(Integer userId, String userAccount, String userPassword, String userRemark, Byte userDel, Date userCreatetime, Date userUpdatetime) {
        this.userId = userId;
        this.userAccount = userAccount;
        this.userPassword = userPassword;
        this.userRemark = userRemark;
        this.userDel = userDel;
        this.userCreatetime = userCreatetime;
        this.userUpdatetime = userUpdatetime;
    }
    public User() {
        super();
    }
    public Integer getUserId() {
        return userId;
    }
    public void setUserId(Integer userId) {
        this.userId = userId;
    }
    public String getUserAccount() {
        return userAccount;
    }
    public void setUserAccount(String userAccount) {
        this.userAccount = userAccount == null ? null : userAccount.trim();
    }
    public String getUserPassword() {
        return userPassword;
    }
    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword == null ? null : userPassword.trim();
    }
    public String getUserRemark() {
        return userRemark;
    }
    public void setUserRemark(String userRemark) {
        this.userRemark = userRemark == null ? null : userRemark.trim();
    }
    public Byte getUserDel() {
        return userDel;
    }
    public void setUserDel(Byte userDel) {
        this.userDel = userDel;
    }
    public Date getUserCreatetime() {
        return userCreatetime;
    }
    public void setUserCreatetime(Date userCreatetime) {
        this.userCreatetime = userCreatetime;
    }
    public Date getUserUpdatetime() {
        return userUpdatetime;
    }
    public void setUserUpdatetime(Date userUpdatetime) {
        this.userUpdatetime = userUpdatetime;
    }
}
package com.luxsuen.requestjson.web;
import com.luxsuen.jsonutil.util.JsonUtil;
import com.luxsuen.requestjson.entity.User;
import com.luxsuen.requestjson.annotation.RequestJson;
import com.luxsuen.requestjson.util.MapWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/user/")
public class UserController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * @Author Lux Sun
     * @Description: 测试(以大括号开始) @PathVariable & @RequestJson + 一步获取分参后的value
     * @Param: [userId, userDel, userAccount, scoreArray, money, user1, user2, user3, userList, mapWrapper1, mapWrapper2]
     * @Return: java.lang.Object
     */
    @RequestMapping(value = "info/{userId}", method = RequestMethod.POST)
    @ResponseBody
    public Object checkRequestJsonByBeginBigBrace(
                                                @PathVariable(value = "userId") Integer userId,
                                                @RequestJson(value = "userDel") Boolean userDel,
                                                @RequestJson(value = "userAccount") String userAccount,
                                                @RequestJson(value = "scoreArray") Double[] scoreArray,
                                                @RequestJson(value = "money") BigDecimal money,
                                                @RequestJson(value = "user1") User user1,
                                                @RequestJson(value = "user2") User user2,
                                                @RequestJson(value = "user3") User user3,
                                                @RequestJson(value = "userList") List<User> userList,
                                                @RequestJson(value = "mapWrapper1") MapWrapper mapWrapper1,
                                                @RequestJson(value = "mapWrapper2") MapWrapper mapWrapper2)
    {
        // 获取实体类 & 实体类数组
        Object user = JsonUtil.getJsonEntityByKeyArray(mapWrapper1.getMapWrapper(), User.class, "k8");
        Object userlist = JsonUtil.getJsonEntityListByKeyArray(mapWrapper1.getMapWrapper(), User.class, "k9");
        // 获取普通类型 & 集合
        Object integer = JsonUtil.getJsonValueByKeyArray(mapWrapper1.getMapWrapper(), Integer.class, "k9", "0", "userId");
        Object string = JsonUtil.getJsonValueByKeyArray(mapWrapper1.getMapWrapper(), String.class, "k2");
        Object bool = JsonUtil.getJsonValueByKeyArray(mapWrapper1.getMapWrapper(), Boolean.class, "k3");
        Object array1 = JsonUtil.getJsonValueByKeyArray(mapWrapper1.getMapWrapper(), List.class, "k4");
        Object map1 = JsonUtil.getJsonValueByKeyArray(mapWrapper1.getMapWrapper(), Map.class, "k5");
        Object map2 = JsonUtil.getJsonValueByKeyArray(mapWrapper1.getMapWrapper(), Map.class, "k6");
        Object array2 = JsonUtil.getJsonValueByKeyArray(mapWrapper1.getMapWrapper(), List.class, "k7");
        return null;
    }
    /**
     * @Author Lux Sun
     * @Description: 测试(以中括号开始)
     * @Param: [mapWrapper3]
     * @Return: java.lang.Object
     */
    @RequestMapping(value = "info", method = RequestMethod.POST)
    @ResponseBody
    public Object checkRequestJsonByBeginMidBrace(@RequestJson(value = "mapWrapper3") MapWrapper mapWrapper3)
    {
        return null;
    }
    /**
     * @Author Lux Sun
     * @Description: 测试(只有大括号)
     * @Param: [arr]
     * @Return: java.lang.Object
     */
    @RequestMapping(value = "onlyBigBrace", method = RequestMethod.POST)
    @ResponseBody
    public Object checkRequestJsonByOnlyBigBrace(@RequestJson(value = "name") String name)
    {
        return null;
    }
    /**
     * @Author Lux Sun
     * @Description: 测试(只有中括号)
     * @Param: [arr]
     * @Return: java.lang.Object
     */
    @RequestMapping(value = "onlyMidBrace", method = RequestMethod.POST)
    @ResponseBody
    public Object checkRequestJsonByOnlyMidBrace(@RequestJson(value = "arr") Integer[] arr)
    {
        return null;
    }
}

测试案例

// 以大括号开始嵌套
{
  "userId": 1,
  "userDel": false,
  "userAccount": "Admin",
  "scoreArray": [
    98.5,
    89,
    120
  ],
  "money": 123.45678987654321,
  "user1": {
    "userId": 1,
    "userAccount": "Bob1",
    "userPassword": "abc123456",
    "userRemark": "",
    "userDel": 0,
    "userCreatetime": "2019-03-07 16:52:46",
    "userUpdatetime": "2019-03-07 16:52:46"
  },
  "user2": {
    "userId": 2,
    "userAccount": "Bob2",
    "userPassword": "abc123456",
    "userRemark": "",
    "userDel": 0,
    "userCreatetime": "2019-03-07 16:52:46",
    "userUpdatetime": "2019-03-07 16:52:46",
    "more": "!@#$%^&*"
  },
  "user3": {
    "userId": 3,
    "userAccount": "Bob3",
    "userPassword": "abc123456",
    "userRemark": "用户",
    "userCreatetime": "2019-03-07 16:52:46",
    "userUpdatetime": "2019-03-07 16:52:46"
  },
  "userList": [
    {
      "userId": 2,
      "userAccount": "Alice",
      "userPassword": "abc789",
      "userRemark": "大学生",
      "userDel": 1,
      "userCreatetime": "2019-03-08 16:52:46",
      "userUpdatetime": "2019-03-08 16:52:46"
    },
    {
      "userId": 3,
      "userAccount": "Tom",
      "userPassword": "[{}]147@#",
      "userRemark": "学生",
      "userDel": 0,
      "userCreatetime": "2007-03-08 16:52:46",
      "userUpdatetime": "2007-03-08 16:52:46"
    }
  ],
  "mapWrapper1": {
    "k1": 123,
    "k2": "abc",
    "k3": true,
    "k4": [
      1,
      2,
      3
    ],
    "k5": {
      "k5-1": "qwer",
      "k5-2": 90.6
    },
    "k6": {"k6-1": [
      "qaz",
      "wsx"
    ]},
    "k7": [
      {"k7-1": 456},
      {"k7-2": "asdf"}
    ],
    "k8": {
      "userId": 3,
      "userAccount": "Bob3",
      "userPassword": "abc123456",
      "userRemark": "用户",
      "userCreatetime": "2019-03-07 16:52:46",
      "userUpdatetime": "2019-03-07 16:52:46"
    },
    "k9": [
      {
        "userId": 2,
        "userAccount": "Alice",
        "userPassword": "abc789",
        "userRemark": "大学生",
        "userDel": 1,
        "userCreatetime": "2019-03-08 16:52:46",
        "userUpdatetime": "2019-03-08 16:52:46"
      },
      {
        "userId": 3,
        "userAccount": "Tom",
        "userPassword": "[{}]147@#",
        "userRemark": "学生",
        "userDel": 0,
        "userCreatetime": "2007-03-08 16:52:46",
        "userUpdatetime": "2007-03-08 16:52:46"
      }
    ]
  },
  "mapWrapper2": [
    1,
    "2",
    {
      "k1": 123,
      "k2": "abc",
      "k3": true,
      "k4": [
        1,
        2,
        3
      ],
      "k5": {
        "k5-1": "qwer",
        "k5-2": 90.6
      },
      "k6": {"k6-1": [
        "qaz",
        "wsx"
      ]},
      "k7": [
        {"k7-1": 456},
        {"k7-2": "asdf"}
      ]
    },
    {
      "k8": 456,
      "k9": "def",
      "k10": false,
      "k11": [
        4,
        5,
        6
      ],
      "k12": {
        "k12-1": "qwer",
        "k12-2": 90.6
      },
      "k13": {"k13-1": [
        "qaz",
        "wsx"
      ]},
      "k14": [
        {"k14-1": 456},
        {"k14-2": "asdf"}
      ]
    }
  ]
}
// 以中括号开始嵌套
[
  1,
  "2",
  {
    "k1": 123,
    "k2": "abc",
    "k3": true,
    "k4": [
      1,
      2,
      3
    ],
    "k5": {
      "k5-1": "qwer",
      "k5-2": 90.6
    },
    "k6": {"k6-1": [
      "qaz",
      "wsx"
    ]},
    "k7": [
      {"k7-1": 456},
      {"k7-2": "asdf"}
    ]
  },
  {
    "k8": 456,
    "k9": "def",
    "k10": false,
    "k11": [
      4,
      5,
      6
    ],
    "k12": {
      "k12-1": "qwer",
      "k12-2": 90.6
    },
    "k13": {"k13-1": [
      "qaz",
      "wsx"
    ]},
    "k14": [
      {"k14-1": 456},
      {"k14-2": "asdf"}
    ]
  }
]
// 只有大括号
{
  "name": "Admin"
}
// 只有中括号
[
  1, 2, 3
]
// required
{
}

Ps:如果在JsonPath执行报错时,当找不到“key”引起的话,这是正常现象,并不是程序的BUG噢~

目录
相关文章
|
6月前
|
JSON 前端开发 Java
Spring MVC入门必读:注解、参数传递、返回值和页面跳转(下)
Spring MVC入门必读:注解、参数传递、返回值和页面跳转(下)
65 0
|
5月前
SpringMVC常见组件之HandlerMethodArgumentResolver解析-2
SpringMVC常见组件之HandlerMethodArgumentResolver解析-2
29 0
|
5月前
|
算法 Java API
SpringMVC常见组件之HandlerMethodArgumentResolver解析-1
SpringMVC常见组件之HandlerMethodArgumentResolver解析-1
51 0
|
6月前
|
XML JSON 前端开发
SpringMVC入门的注解、参数传递、返回值和页面跳转---超详细教学
SpringMVC入门的注解、参数传递、返回值和页面跳转---超详细教学
82 1
|
6月前
|
JSON 前端开发 Java
Spring MVC入门必读:注解、参数传递、返回值和页面跳转(上)
Spring MVC入门必读:注解、参数传递、返回值和页面跳转(上)
44 0
|
7月前
|
前端开发 Java Maven
“深入探究SpringMVC的工作原理与入门实践“
“深入探究SpringMVC的工作原理与入门实践“
32 0
|
9月前
|
设计模式 JSON 前端开发
2021-08-11Spring MVC,入门项目搭建及流程,springMVC的适配器和映射器,基于注解的controller,映射请求,方法返回值,requestmapping注解
2021-08-11Spring MVC,入门项目搭建及流程,springMVC的适配器和映射器,基于注解的controller,映射请求,方法返回值,requestmapping注解
41 0
|
10月前
|
SQL XML 前端开发
Java高级期末复习:Java EE框架整合开发入门到实战——Spring+Spring MVC+MyBatis微课版
Java高级期末复习:Java EE框架整合开发入门到实战——Spring+Spring MVC+MyBatis微课版
265 0
QGS
|
XML JSON 前端开发
手搭手入门SpringMVC
关于Tomcat服务器的目录 bin: 该目录是Tomcat服务器的命令文件存放的目录,打开关闭Tomcat conf: 该目录是Tomcat服务器的配置文件存放目录。(Server.xml文件中可以配置端口号,默认Tomcat端口是8080)
QGS
64 0
QGS
|
存储 调度 数据安全/隐私保护
入门SpringMVC之Interceptor拦截器
SpringMVC中的Interceptor拦截器,它的主要作用是拦截指定的用户需求,并进行相应的预处理与后处理。
QGS
67 0