Spring Boot 应用程序中验证的最佳实践

问题描述 投票:0回答:1

在我的Spring Boot应用程序中,我遇到了一个场景,多个服务相互交互,并且需要验证它们之间传递的对象。目前,我在控制器中使用

@Valid
来验证传入的请求。但是,当需要在服务层中再次验证相同的对象时,我担心冗余和开销。

问题:

  1. 最佳实践:在服务调用其他服务的 Spring Boot 应用程序中处理验证的最佳实践是什么?
  2. 性能注意事项:将
    @Valid
    注释放置在服务层而不是控制器层是否可以通过避免冗余验证来提高性能?
  3. 架构原则:将验证逻辑移至服务层如何与关注点分离和单一责任等原则保持一致?

示例:

  • Controller:使用
    UserDTO
    验证传入的
    @Valid
    对象。
  • Service
    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);
        }
    }
}

总结:

  • 控制器中的验证:确保 HTTP 请求的快速反馈。
  • 服务验证:确保所有服务交互都经过验证。

考虑到这种情况,在 Spring Boot 应用程序中处理验证的推荐方法是什么?

java spring spring-boot validation
1个回答
0
投票

服务验证

虽然看起来更安全、万无一失,但你可以这样想: 如果您控制(编码和维护)内部(即模块范围)服务 A 和服务 B,为什么您不确定它们的交互?或者如果我换个说法:为什么服务 A 会向服务 B 发送错误数据?您知道运行时之前发生了什么,并且您可以通过测试来检查它。

控制器中的验证

这就是为什么控制器更受欢迎的地方

@Valid
,此时您无法控制这些数据(如用户输入)。在服务层你做的。

© www.soinside.com 2019 - 2024. All rights reserved.