在我的Spring Boot应用程序中,我遇到了一个场景,多个服务相互交互,并且需要验证它们之间传递的对象。目前,我在控制器中使用
@Valid
来验证传入的请求。但是,当需要在服务层中再次验证相同的对象时,我担心冗余和开销。
@Valid
注释放置在服务层而不是控制器层是否可以通过避免冗余验证来提高性能?UserDTO
验证传入的 @Valid
对象。UserService
可能会调用OtherService
,这也需要验证相同的UserDTO
对象。@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<UserDTO> createUser(@RequestBody UserDTO userDTO) {
UserDTO createdUser = userService.createUser(userDTO);
return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
}
}
@Service
@Validated
public class UserService {
@Autowired
private Validator validator;
public UserDTO createUser(@Valid UserDTO userDTO) {
validate(userDTO);
// Business logic
return new UserDTO();
}
private <T> void validate(T object) {
Set<ConstraintViolation<T>> violations = validator.validate(object);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
}
考虑到这种情况,在 Spring Boot 应用程序中处理验证的推荐方法是什么?
服务验证
虽然看起来更安全、万无一失,但你可以这样想: 如果您控制(编码和维护)内部(即模块范围)服务 A 和服务 B,为什么您不确定它们的交互?或者如果我换个说法:为什么服务 A 会向服务 B 发送错误数据?您知道运行时之前发生了什么,并且您可以通过测试来检查它。
控制器中的验证
这就是为什么控制器更受欢迎的地方
@Valid
,此时您无法控制这些数据(如用户输入)。在服务层你做的。