SpringBoot 自定义方法参数解析器HandlerMethodArgumentResolver

      最近在做php接口的迁移工作,在迁移过程中发现php接口中定义的参数都是下划线的格式,所以在写Rest服务接口时非常别扭,因为需要兼容之前的接口,所以在接收参数是还是需要和原来保持一致。所以就想能不能写一个参数解析器,将参数下滑线形式转换为Java常用的驼峰形式,这样在参数映射是就保持了Java的驼峰命名习惯,在参考了一些资料后,发现其实springMVC提供了HandlerMethodArgumentResolver接口,所以大致思路是:自定义方法参数解析器实现HandlerMethodArgumentResolver接口,将带有下滑线的参数通过正则替换为驼峰形式,这样就可以映射到对应实体类上的属性了。话不多说,上代码。首先是自定义方法参数解析器UnderlineToCamelArgumentResolver

public class UnderlineToCamelArgumentResolver implements HandlerMethodArgumentResolver {
    /**
     * 匹配下划线的格式
     */
    private static Pattern pattern = Pattern.compile("_(\\w)");

    private static String underLineToCamel(String source) {
        Matcher matcher = pattern.matcher(source);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

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


    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        return handleParameterNames(parameter, webRequest);
    }

    private Object handleParameterNames(MethodParameter parameter, NativeWebRequest webRequest) {
        Object obj = BeanUtils.instantiate(parameter.getParameterType());
        BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
        Iterator<String> paramNames = webRequest.getParameterNames();
        while (paramNames.hasNext()) {
            String paramName = paramNames.next();
            Object o = webRequest.getParameter(paramName);
            try {
                wrapper.setPropertyValue(underLineToCamel(paramName), o);
            } catch (BeansException e) {

            }
        }
        return obj;
    }


}

    该类需要实现HandlerMethodArgumentResolver接口,其中注意到supportsParameter方法中出现了ParamModel注解,它的作用就是为了注明哪些参数处理,在handleParameterNames方法中去实现参数名的转换,underLineToCamel就是将下划线转成驼峰的形式。下面是自定义@ParamModel注解:

/**
 * 实体映射注解
 * 配置该注解的参数会使用UnderlineToCamelArgumentResolver类完成装载
 */
@Target(value = ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamModel {

}

        只是自定义了HandlerMethodArgumentResolver了还不够,还需要将我们自定义的解析器添加到配置中去,首先,需要定义一个WebConfig配置类需要继承WebMvcConfigurerAdapter,使用@Configuration注解,并重写addArgumentResolvers方法,将自定义解析器加入到argumentResolvers的List中去。

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    /**
     * 添加参数解析,将参数的形式从下划线转化为驼峰
     * @param argumentResolvers
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        super.addArgumentResolvers(argumentResolvers);
        argumentResolvers.add(new UnderlineToCamelArgumentResolver());
    }
}

     以上配置完成后,在Controller中使用就可以@ParamModel注解进行参数的转换了,下面是controller部分代码:

    @PostMapping("/updateCarSource/{car_id}")
    public ResultData updateCarSource(@ParamModel CarSource carSource, @PathVariable("car_id") Integer carId) {
      
        if (!validateCarSourceParam(carSource)) {
            return resultError(StatusCodeConfig.PARAM_ERROR);
        }
        .....
        return resultSuccess(StatusCodeConfig.PARAM_ERROR);
    }

例如前台传入参数clue_id,就可以映射到CarSource类中的clueId字段了。至此,我们就完成了自定义的方法参数解析器了,如果是在一些接口迁移或者一些跨语言的迁移,这样就可以减少很多代码转换的逻辑了,不用每个参数都使用@RequestParam注解去解析参数了,特别是对于一些参数很多的接口,这样无疑极大的减少了很多冗余的代码,让代码看起来比较清爽,但是如果只是Java接口的开发,可能就不涉及到参数转换了,因为之前开发比较少设计类似的配置,所以mark一下,希望对小伙伴们有所启发和帮助。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值