解决方案
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噢~