主题切换
请求参数去空格使用指南
📖 概述
@TrimParam
是一个用于自动去除字符串参数空格的注解,支持字段级别和方法参数级别的字符串去空格处理。通过 AOP 切面自动拦截请求,对标记的字段和参数进行空格处理,提升数据质量和用户体验。
✨ 核心特性
🎯 灵活应用
- 字段级别:在对象字段上添加注解,适用于
@RequestBody
参数 - 参数级别:在 Controller 方法参数上添加注解,适用于
@RequestParam
、@PathVariable
等 - 嵌套支持:支持嵌套对象和集合中的字符串字段处理
- 全局配置:支持全局模式,无需逐个添加注解
🔧 处理类型
- 前后空格:去除字符串前后的空白字符(默认)
- 前置空格:只去除字符串前面的空白字符
- 后置空格:只去除字符串后面的空白字符
- 所有空格:去除字符串中所有的空白字符
🛡️ 安全特性
- 空值处理:支持将空字符串转换为 null
- 排除机制:支持排除特定字段和参数
- 性能优化:智能判断,避免不必要的处理
🚀 快速开始
基础用法
1. 字段级别使用
java
@Data
public class UserDto {
@TrimParam
private String username; // 自动去除前后空格
@TrimParam(type = TrimParam.TrimType.ALL)
private String phoneNumber; // 去除所有空格
@TrimParam(emptyToNull = true)
private String email; // 去除空格并将空字符串转为null
private String password; // 不处理
}
2. 参数级别使用
java
@RestController
@RequestMapping("/api/user")
public class UserController {
@GetMapping("/search")
public Result<List<User>> searchUsers(
@TrimParam @RequestParam String keyword, // 自动去除前后空格
@TrimParam(type = TrimParam.TrimType.ALL) @RequestParam String phone,
@RequestParam Integer page) {
// keyword 和 phone 会自动去除空格
return userService.searchUsers(keyword, phone, page);
}
@GetMapping("/{id}")
public Result<User> getUser(
@TrimParam @PathVariable String id) { // 路径参数也支持
return userService.getUserById(id);
}
@PostMapping("/create")
public Result<User> createUser(@RequestBody UserDto userDto) {
// UserDto 中标记了 @TrimParam 的字段会自动处理
return userService.createUser(userDto);
}
}
📋 注解属性详解
核心属性
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
enabled | boolean | true | 是否启用去空格功能 |
type | TrimType | BOTH | 去空格类型 |
emptyToNull | boolean | false | 是否将空字符串转换为null |
去空格类型 (TrimType)
类型 | 说明 | 示例 |
---|---|---|
BOTH | 去除前后空格(默认) | " hello " → "hello" |
LEADING | 只去除前面空格 | " hello " → "hello " |
TRAILING | 只去除后面空格 | " hello " → " hello" |
ALL | 去除所有空格 | " h e l l o " → "hello" |
⚙️ 全局配置
配置文件
yaml
# application.yml
wueasy:
trim-string:
enabled: true # 全局开关
global-enabled: false # 是否启用全局模式
global-type: BOTH # 全局默认去空格类型
global-empty-to-null: false # 全局默认是否空字符串转null
global-process-params: true # 是否处理请求参数
global-process-fields: true # 是否处理请求体字段
global-exclude-fields: # 排除的字段名
- password
- token
global-exclude-params: # 排除的参数名
- timestamp
- signature
💡 实用示例
1. 用户注册表单处理
java
@Data
public class UserRegisterDto {
@TrimParam // 用户名去除前后空格
@NotBlank(message = "用户名不能为空")
private String username;
@TrimParam(emptyToNull = true) // 邮箱去空格,空字符串转null
@Email(message = "邮箱格式不正确")
private String email;
@TrimParam(type = TrimParam.TrimType.ALL) // 手机号去除所有空格
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phoneNumber;
@TrimParam // 真实姓名去除前后空格
private String realName;
// 密码不处理空格,保持原样
@NotBlank(message = "密码不能为空")
private String password;
@TrimParam(emptyToNull = true) // 地址去空格,可为空
private String address;
}
@PostMapping("/register")
public ResultVo<User> register(@Valid @RequestBody UserRegisterDto dto) {
// dto 中的字符串字段会自动处理空格
return userService.register(dto);
}
2. 搜索接口参数处理
java
@GetMapping("/search")
public ResultVo<PageInfo<Product>> searchProducts(
@TrimParam @RequestParam(required = false) String keyword, // 关键词去空格
@TrimParam @RequestParam(required = false) String category, // 分类去空格
@TrimParam(type = TrimParam.TrimType.ALL) @RequestParam(required = false) String code, // 商品编码去所有空格
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size) {
SearchCriteria criteria = SearchCriteria.builder()
.keyword(keyword)
.category(category)
.code(code)
.page(page)
.size(size)
.build();
return productService.searchProducts(criteria);
}
3. 嵌套对象处理
java
@Data
public class OrderDto {
@TrimParam
private String orderNo; // 订单号去空格
@Valid
private CustomerInfo customer; // 嵌套对象
@Valid
private List<OrderItem> items; // 集合中的对象
}
@Data
public class CustomerInfo {
@TrimParam
private String name; // 客户姓名去空格
@TrimParam(type = TrimParam.TrimType.ALL)
private String phone; // 客户电话去所有空格
@TrimParam(emptyToNull = true)
private String email; // 客户邮箱去空格,空转null
}
@Data
public class OrderItem {
@TrimParam
private String productCode; // 商品编码去空格
@TrimParam(emptyToNull = true)
private String remark; // 备注去空格,空转null
private Integer quantity; // 数量不处理
}
4. 全局模式使用
yaml
# 启用全局模式
wueasy:
trim-string:
enabled: true
global-enabled: true # 启用全局模式
global-type: BOTH # 全局去除前后空格
global-empty-to-null: false # 全局不转null
global-exclude-fields: # 排除特定字段
- password
- token
- signature
global-exclude-params: # 排除特定参数
- timestamp
- nonce
java
// 全局模式下,即使不添加注解也会处理
@Data
public class SimpleDto {
private String name; // 会自动去除前后空格
private String email; // 会自动去除前后空格
private String password; // 在排除列表中,不会处理
private Integer age; // 非字符串类型,不会处理
}
@GetMapping("/simple")
public Result<String> simpleMethod(
@RequestParam String keyword, // 会自动去除前后空格
@RequestParam String timestamp, // 在排除列表中,不会处理
@RequestParam Integer page) { // 非字符串类型,不会处理
return Result.success("处理完成");
}
5. 特殊场景处理
java
@Data
public class AdvancedDto {
// 禁用处理
@TrimParam(enabled = false)
private String rawData; // 保持原样,不处理空格
// 只去除前面空格
@TrimParam(type = TrimParam.TrimType.LEADING)
private String leadingTrimmed;
// 只去除后面空格
@TrimParam(type = TrimParam.TrimType.TRAILING)
private String trailingTrimmed;
// 去除所有空格并转null
@TrimParam(type = TrimParam.TrimType.ALL, emptyToNull = true)
private String allTrimmedToNull;
// 嵌套Map中的字符串也会处理
private Map<String, Object> metadata;
}
🎯 最佳实践
1. 性能优化
java
// ✅ 推荐:只在需要的字段上使用注解
@Data
public class OptimizedDto {
@TrimParam // 用户输入的字段需要处理
private String userInput;
// ❌ 避免:系统生成的字段不需要处理
// @TrimParam
private String systemGenerated;
@TrimParam(enabled = false) // 明确禁用
private String sensitiveData;
}
2. 安全考虑
java
@Data
public class SecurityDto {
@TrimParam // 用户名可以去空格
private String username;
// ✅ 推荐:密码等敏感信息不要处理空格
private String password;
// ✅ 推荐:令牌等不要处理
private String accessToken;
@TrimParam(type = TrimParam.TrimType.ALL) // 手机号去所有空格
private String phoneNumber;
}
3. 数据验证配合
java
@Data
public class ValidatedDto {
@TrimParam
@NotBlank(message = "用户名不能为空") // 先去空格,再验证
@Size(min = 3, max = 20, message = "用户名长度必须在3-20之间")
private String username;
@TrimParam(emptyToNull = true)
@Email(message = "邮箱格式不正确") // 空字符串转null后,@Email不会报错
private String email;
@TrimParam(type = TrimParam.TrimType.ALL)
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phoneNumber;
}
❗ 注意事项
性能影响
- 字符串处理在每次请求时执行,大量字符串字段时注意性能
- 建议只在用户输入的字段上使用,避免对系统生成的字段处理
- 全局模式会影响所有字符串字段,谨慎使用
数据完整性
- 某些场景下空格可能有业务意义,需要谨慎处理
- 密码、令牌等敏感信息建议不要处理空格
- 格式化的数据(如JSON、XML)不建议处理
类型兼容性
- 只处理 String 类型的字段和参数
- 支持嵌套对象、集合、Map 中的字符串
- null 值不会被处理
异常处理
- 处理异常会被捕获并记录日志,返回原始值
- 建议在开发环境启用调试日志
- 可通过配置调整异常处理策略
💡 提示:建议在开发环境中充分测试去空格效果,确保不会影响业务逻辑后再部署到生产环境。