最近在做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一下,希望对小伙伴们有所启发和帮助。