[特殊字符]SpringBoot魔法:让请求参数自动从“下划线蛇精病“变身“驼峰绅士“!
·
大家好!今天我要带大家见识一个SpringBoot的隐藏技能——如何让接口接收的参数像变魔术一样,自动把数据库风格的user_name转换成Java风格的userName!是不是光听就觉得很酷?那就让我们开始这场编程界的"变形记"吧!
一、问题背景:程序员的痛
作为后端开发者,我们经常遇到这样的场景:
- 数据库字段:
user_name,create_time - Java实体类:
userName,createTime
每次手动转换都让人头大,特别是当参数很多的时候...(扶额)难道就没有优雅的解决方案吗?
二、解决方案:自定义ServletRequestDataBinder
SpringMVC中的ServletRequestDataBinder就是处理请求参数绑定的幕后英雄!我们可以自定义它来实现自动转换。
1.转换配置
public class SnakeToCamelRequestDataBinder extends ServletRequestDataBinder {
private final Pattern underLinePattern = Pattern.compile("_(\\w)");
public SnakeToCamelRequestDataBinder(Object target) {
super(target);
}
@Override
protected void addBindValues(MutablePropertyValues mpv, ServletRequest request) {
List<PropertyValue> pvs = mpv.getPropertyValueList();
List<PropertyValue> adds = new LinkedList<>();
for (PropertyValue pv : pvs) {
String name = pv.getName();
String camel = this.underLineToCamel(name);
if (!name.equals(camel)) {
adds.add(new PropertyValue(camel, pv.getValue()));
}
}
pvs.addAll(adds);
}
/**
* 下划线转驼峰方法
* @param value 要转换的下划线字符串
* @return 驼峰体字符串
*/
private String underLineToCamel(final String value) {
if(!value.contains("_")) return value;
final StringBuffer sb = new StringBuffer();
Matcher m = this.underLinePattern.matcher(value);
while (m.find()){
m.appendReplacement(sb, m.group(1).toUpperCase());
}
m.appendTail(sb);
return sb.toString();
}
}
public class SnakeToCamelAttributeProcessor extends ServletModelAttributeMethodProcessor {
public SnakeToCamelAttributeProcessor(boolean annotationNotRequired) {
super(annotationNotRequired);
}
/**
* 请求参数的对象需要新增 UTCModelAttribute 注解 才能生效
*
* @param parameter 参数
* @return boolean
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(SnakeToCamel.class);
}
//绑定参数
@Override
protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
Assert.state(servletRequest != null, "No ServletRequest");
ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
new SnakeToCamelRequestDataBinder(servletBinder.getTarget()).bind(servletRequest);
}
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SnakeToCamel {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean binding() default true;
}
2.添加web mvc 配置
@Configuration
public class AppWebMvcConfig implements WebMvcConfigurer {
/**
* 添加参数解析器
*
* @param resolvers 解析 器
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new SnakeToCamelAttributeProcessor(true));
}
}
public class UserDTO {
private String userName;
private Integer userAge;
private String createTime;
// getters and setters...
}
@PostMapping("/user")
public String createUser(@SnakeToCamel UserDTO user) {
// 这里直接使用驼峰命名的属性,无需手动转换
System.out.println("Received user: " + user.getUserName());
return "Success! User name is: " + user.getUserName();
}
3.前端请求
// 前端发送的JSON(数据库风格命名)
fetch('/user', {
method: 'GET',
body: JSON.stringify({
user_name: "张三",
user_age: 25,
create_time: "2023-01-01"
})
})
三、总结:优雅的编程艺术
通过以上方法,我们实现了:
1.自动转换:请求参数自动从下划线转驼峰
2.零侵入:业务代码完全不需要关心命名风格差异
3.高性能:只在必要时进行转换,不影响性能
更多推荐
所有评论(0)