本文目录导读:

我来系统介绍Java参数接收的规整方法,涵盖请求参数、方法参数、校验和转换等各个方面。
基础参数接收规整
Controller层参数接收规范
@RestController
@RequestMapping("/api/users")
public class UserController {
// 1. 路径参数
@GetMapping("/{id}")
public Result<User> getUserById(@PathVariable Long id) {
// 使用@PathVariable
}
// 2. 查询参数
@GetMapping("/list")
public Result<List<User>> listUsers(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) String keyword) {
// 使用@RequestParam
}
// 3. 表单参数/JSON体
@PostMapping
public Result<User> createUser(@Valid @RequestBody UserCreateDTO dto) {
// 使用@RequestBody
}
// 4. 混合参数
@PutMapping("/{id}")
public Result<User> updateUser(
@PathVariable Long id,
@Valid @RequestBody UserUpdateDTO dto) {
// 组合使用
}
}
DTO(数据传输对象)设计
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserCreateDTO {
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 50, message = "用户名长度2-50个字符")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 20, message = "密码长度6-20个字符")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
@Min(value = 0, message = "年龄不能小于0")
@Max(value = 150, message = "年龄不能大于150")
private Integer age;
@Future(message = "过期时间必须是将来的时间")
private LocalDateTime expireTime;
}
参数校验增强
分组校验
// 定义分组接口
public interface CreateGroup {}
public interface UpdateGroup {}
// DTO使用分组
@Data
public class UserDTO {
@Null(groups = CreateGroup.class)
@NotNull(groups = UpdateGroup.class)
private Long id;
@NotBlank(groups = CreateGroup.class)
@Size(min = 2, max = 50)
private String username;
@NotBlank(groups = CreateGroup.class)
private String password;
@NotNull(groups = UpdateGroup.class)
private Integer status;
}
// Controller使用分组
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public Result<User> create(@Validated(CreateGroup.class) @RequestBody UserDTO dto) {
// 创建时的校验
}
@PutMapping("/{id}")
public Result<User> update(
@PathVariable Long id,
@Validated(UpdateGroup.class) @RequestBody UserDTO dto) {
// 更新时的校验
}
}
自定义校验注解
// 自定义注解
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MobileValidator.class)
public @interface Mobile {
String message() default "手机号格式不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
// 校验器实现
public class MobileValidator implements ConstraintValidator<Mobile, String> {
private static final Pattern MOBILE_PATTERN =
Pattern.compile("^1[3-9]\\d{9}$");
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true; // 是否为空由@NotNull控制
}
return MOBILE_PATTERN.matcher(value).matches();
}
}
// 使用自定义注解
@Data
public class UserDTO {
@Mobile
private String phone;
}
全局异常处理统一返回
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<Map<String, String>> handleValidationExceptions(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage()));
return Result.error(400, "参数校验失败", errors);
}
@ExceptionHandler(ConstraintViolationException.class)
public Result<Map<String, String>> handleConstraintViolation(
ConstraintViolationException ex) {
Map<String, String> errors = new HashMap<>();
ex.getConstraintViolations().forEach(violation ->
errors.put(
violation.getPropertyPath().toString(),
violation.getMessage()
));
return Result.error(400, "参数校验失败", errors);
}
}
参数转换与处理
通用转换器
@Component
public class StringToLocalDateConverter
implements Converter<String, LocalDate> {
private static final DateTimeFormatter FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Override
public LocalDate convert(String source) {
if (source == null || source.trim().isEmpty()) {
return null;
}
return LocalDate.parse(source, FORMATTER);
}
}
// 配置转换器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToLocalDateConverter());
}
}
参数脱敏处理
// 自定义序列化注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveSerializer.class)
public @interface Sensitive {
SensitiveType type() default SensitiveType.PHONE;
}
enum SensitiveType {
PHONE, EMAIL, ID_CARD, NAME
}
// 脱敏处理器
public class SensitiveSerializer extends JsonSerializer<String> {
@Override
public void serialize(String value,
JsonGenerator gen,
SerializerProvider serializers) throws IOException {
if (value == null) {
gen.writeNull();
return;
}
String masked = mask(value);
gen.writeString(masked);
}
private String mask(String value, SensitiveType type) {
switch (type) {
case PHONE:
return value.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
case EMAIL:
return value.replaceAll("(.{2}).+(@.+)", "$1****$2");
case ID_CARD:
return value.replaceAll("(.{4}).+(.{4})", "$1********$2");
case NAME:
return value.replaceAll("(.{1}).+", "$1**");
default:
return value;
}
}
}
// 使用
@Data
public class UserVO {
@Sensitive(type = SensitiveType.PHONE)
private String phone;
@Sensitive(type = SensitiveType.EMAIL)
private String email;
}
最佳实践总结
参数接收规范
// 推荐:使用DTO统一接收
@PostMapping("/batch")
public Result<List<User>> batchCreate(
@Valid @RequestBody List<@Valid UserCreateDTO> dtos) {
// 集合参数校验
}
// 推荐:查询参数使用对象封装
@GetMapping("/search")
public Result<PageResult<User>> searchUsers(
@Validated UserSearchDTO searchDTO,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size) {
// 复杂查询参数
}
参数校验顺序
// 1. 基础类型校验(框架自动) // 2. @Valid/@Validated 注解校验(JSR-303) // 3. 业务逻辑校验(自定义校验器) // 4. 幂等性校验(防止重复提交)
完整示例
@RestController
@RequestMapping("/api/orders")
@Validated // 类级别校验
public class OrderController {
@PostMapping
public Result<OrderVO> createOrder(
@Valid @RequestBody OrderCreateDTO dto,
@RequestHeader("X-Request-Id") String requestId) {
// 1. 幂等性校验
if (idempotentService.isDuplicate(requestId)) {
return Result.error("重复提交");
}
// 2. 业务参数校验
validateBusinessParams(dto);
// 3. 执行业务
Order order = orderService.createOrder(dto);
// 4. 返回结果
return Result.success(convertToVO(order));
}
private void validateBusinessParams(OrderCreateDTO dto) {
// 复杂业务逻辑校验
if (dto.getTotalAmount().compareTo(dto.getPayAmount()) < 0) {
throw new BusinessException("支付金额不能大于总金额");
}
// 其他业务校验...
}
}
通过以上规整方式,可以实现:
- 统一性:所有参数接收格式统一
- 可维护性:校验逻辑集中管理,便于修改
- 安全性:防XSS、SQL注入等
- 可读性:代码结构清晰,易于理解
- 复用性:DTO和校验规则可复用
这样即使团队多人协作,也能保持代码风格一致,减少沟通成本。