前言
今天说下如何用Spring写自己的一个参数处理器,相信大家在开发接口的时候都会遇到前端传递的参数是下划线的,但是我们后端的规范确是用驼峰格式的,那么这就需要一个参数绑定了,如果大家用过了这个jersey+ws(javax.ws.core)框架的开发restful接口,那么这就不需要自己去实现这个功能了,但是你如果是spring boot/mvc的话就没用这个功能了,spring暂时不支持参数绑定的,那么久需要自己定义一个处理器了
如何处理?
一、jersey+ws框架
1、首先写一个controller接口
@POST
@Path("/login")
@Consumes(MediaType.APPLICATION_JSON)
public Response login(@BeanParam UserForm form) {
Map<String, String> map = server.login(form);
return Tools.returnSuccess(map);
}
2、创建UserForm接收参数
public class UserForm {
@QueryParam(“user_name”)
private String userName;
@QueryParam(“password”)
private Date startTime;
ok,如果使用ws框架的话就使用@BeanParam和@QueryParam就可以实现参数绑定了,像@POST,@Path,@Consumes等都是ws里的注解,这里其他的一些注解为就不写了,感兴趣的可以请自己查阅资料
二、Spring MVC框架
这里才是本章的重点,如果使用spring mvc作为restful接口来写一个自己处理下划线转驼峰的处理器
ok,其实挺简单的也只需要几步就行了
1、创建controller
@RequestMapping(value = "/indexPage", method = RequestMethod.POST)
public String login(@LineConvertHump UserDto UserDto){
}
2、创建@UnderLineConvertHump
@Target(value = ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LineConvertHump {
}
3、创建@LineConvertHump的处理器LineToHumpHandler
public class LineToHumpHandler implements HandlerMethodArgumentResolver{
private static MappingJackson2HttpMessageConverter converter;
static {
converter = new MappingJackson2HttpMessageConverter();
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(LineConvertHump.class);
}
private String underLineToCamel(String str) {
Matcher matcher = Pattern.compile("_(\\w)").matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
}
matcher.appendTail(sb);
return sb.toString();
}
@Override
public Object resolveArgument (
MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory
)
throws Exception
{
HttpServletRequest servletRequest = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);
Object result =null;
try {
Type genericParameterType = methodParameter.getGenericParameterType();
String contentType = servletRequest.getContentType();
if(MediaType.APPLICATION_JSON_VALUE.equals(contentType)){
result = converter.read(Class.forName(genericParameterType.getTypeName()), inputMessage);
}else{
Object obj = BeanUtils.instantiate(methodParameter.getParameterType());
BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
Map<String, String[]> parameterMap = nativeWebRequest.getParameterMap();
for(Map.Entry<String, String[]> map : parameterMap.entrySet()){
String paramName = map.getKey();
String[] paramValue = map.getValue();
Field[] declaredFields = ReflectUtil.getAllFields(obj);
for (Field declaredField : declaredFields) {//如果pojo里有带下划线则直接设置
if(declaredField.getName().contains("_")&¶mName.equals(declaredField.getName())){
wrapper.setPropertyValue(paramName, paramValue);
break;
}
String underLineParamName =underLineToCamel(paramName);
if(declaredField.getName().equals(underLineParamName)){
wrapper.setPropertyValue(underLineParamName, paramValue);
break;
}
}
}
result = obj;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
4、交给spring管理参数处理器,这里作用是项目启动时候加载到spring中,在controller方法上加了@LineConvertHump就会走上面LineToHumpHandler处理器
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new UnderlineToHumpHandler());
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new FastJsonHttpMessageConverter());
super.configureMessageConverters(converters);
}
}
搞定了,觉得有用的点个赞,都是实战中会用到的,持续更新中...