springboot自定义注解转换controller接收的参数类型

最近公司有个代码规范变动。

原本接口是这样的

后台接口是这样接受的

 

修改后为

 

 原本开发的好好的,结果因为接口规范变动,导致所有接口动用不了,本来想在实体类上做继承公共的分页类,结果发现实体类上已经继承了其他类,而且对代码改动量较大遂放弃。

于是乎想到能不能利用spring web中的拦截器做文章,在参数还未开始解析成实体类前就将参数提前转换好。

 1.声明参数注解类

/**
 * @author weijunzhe
 * @Description: <BASE64注解>
 * @Date: 2022/10/23/22:16
 **/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditions {
    /**
     * 是否转为BASE64
     * */
    boolean value() default true;

    Class<?> type() default Object.class;
}

2. 编写参数解析器

/**
 * 参数解析器
 * @author weijunzhe
 */
public class ConditionHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    private static final String POINT = ".";
    private static final String LEFT_PARENTHESIS = "[";
    private static final String RIGHT_PARENTHESIS = "]";
    private static final String PARENTHESIS = "[]";
    private static final String CONTENT_TYPE = "application/json";


    private final Logger logger = LoggerFactory.getLogger(ConditionHandlerMethodArgumentResolver.class);

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(Conditions.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory){
        //获取JSON字符串
        String jsonStr;
        //判断content-type是否是application/json 的数据类型
        String contentType = nativeWebRequest.getHeader("content-type");
        Conditions methodAnnotation = methodParameter.getParameterAnnotation(Conditions.class);
        if (StringUtils.isNotBlank(contentType) && contentType.contains(CONTENT_TYPE)){
            jsonStr = getJSONParam(nativeWebRequest);
        }else {
            jsonStr = parseParamToJSONStr(nativeWebRequest);
        }
        try {
            PageQuery pageQuery = JSONUtil.toBean(jsonStr, PageQuery.class);
            pageQuery.setConditions(JSONUtil.toBean(jsonStr, methodAnnotation.type()));
            return pageQuery;
        }catch (JSONException e){
            logger.error("resolveArgument中JSON.parseObject方法出错:"+e.getMessage(),e);
            return null;
        }
    }

    /**
     *@Description 获取JSON字符串中的数据
     *@author  weijunzhe
     */
    private String getJSONParam(NativeWebRequest request){
        StringBuilder stringBuilder = new StringBuilder();
        try {
            //1.获取输入流
            BufferedReader stramReader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(request.getNativeRequest(HttpServletRequest.class)).getInputStream()));
            //2.写入数据到StringBuilder
            String line;
            while ((line = stramReader.readLine()) != null){
                stringBuilder.append(line);
            }
        }catch (Exception e){
            logger.error("获取JSON字符串中的数据错误:"+e.getMessage(),e);
        }
        return stringBuilder.toString();
    }

    /**
     *@Description 将user.id=1这种形式的数据转为{user:{id:1}}形式
     *@author  weijunzhe
     */
    private String parseParamToJSONStr(NativeWebRequest request){
        Map<String,String [] > conditionMap = request.getParameterMap();
        JSONObject jsonObject = new JSONObject();
        Iterator<String> names = request.getParameterNames();
        while (names.hasNext()){
            String name = names.next();
            String [] value = conditionMap.get(name);
            if (value != null){
                parseHavePointParamToJSON(jsonObject,name,value);
            }
        }
        return jsonObject.toString();
    }

    /**
     *@Description 处理带有点的参数
     *@author  weijunzhe
     */
    private void parseHavePointParamToJSON(JSONObject jsonObject,String name,String [] value){
        //处理中括号
        if (name.contains(LEFT_PARENTHESIS)){
            name = name
                    .replace(PARENTHESIS,"")
                    .replace(LEFT_PARENTHESIS,POINT)
                    .replace(RIGHT_PARENTHESIS,"");

        }
        if (!name.contains(POINT)){
            //如果没有小数点,证明已经是最后一个了
            //判断是否是已经设置过值
            if (value.length>1){
                //如果是组数,则以数组的形式存放数据
                JSONArray jsonArray = new JSONArray();
                jsonArray.addAll(Arrays.asList(value));
                jsonObject.put(name,jsonArray);
            }else {
                jsonObject.put(name,value[0]);
            }
        }else {
            //如果还有小数点
            int pointIndex = name.indexOf(POINT);
            String tempName = name.substring(0,pointIndex);
            String subName = name.substring(name.indexOf(POINT)+1,name.length());
            JSONObject subJSONObject;
            //判断是否已经有对应的属性了
            if (jsonObject.getJSONObject(tempName) == null){
                //如果没有
                subJSONObject = new JSONObject();
            }else {
                //如果有
                subJSONObject = jsonObject.getJSONObject(tempName);
            }
            jsonObject.put(tempName,subJSONObject);
            //递归处理
            parseHavePointParamToJSON(subJSONObject,subName,value);
        }

    }
}

3. 将自定义参数解析器添加到spring web中

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new ConditionHandlerMethodArgumentResolver());
    }
}

4. 最后在方法的参数上添加该注解

    /**
     * 修改用户
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PostMapping
    public AjaxResult updateProfile(@Conditions(type = SysUser.class) PageQuery<SysUser> pageQuery)
    {
        System.err.println(pageQuery.getConditions());
        return AjaxResult.success(pageQuery);
    }

测试后发现一切正常,不用再去动实体类代码= =。

 

 大功告成,下班!!!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值