服务或控制器中的Spring DTO验证?

Ben*_*n M 11 validation service spring spring-mvc dto

我正在使用Spring构建一个直接的AJAX/JSON Web服务.常见的数据流是:

  some DTO from browser

            v

Spring @Controller method

            v

  Spring @Service method
Run Code Online (Sandbox Code Playgroud)

我正在寻找处理数据验证的最简单方法.

  • 我知道@Valid注释在@Controller方法中很有效.
  • 为什么@Valid 不在@Service方法中工作?

我的意思是:服务方法可以被任何其他服务和控制器使用.那么在@Service级别验证会不会更有意义?


我们来看一个这个简单的例子:

MyDTO.java:

public class MyDTO {
   @NotNull
   public String required
   @Min(18)
   public int age;
}
Run Code Online (Sandbox Code Playgroud)

MyServiceImpl.java:

public MyDomainObject foo(MyDTO myDTO) {
  // persist myDTO
  // and return created domain object
}
Run Code Online (Sandbox Code Playgroud)

MyController.java:

@Autowired
MyService myService;

@Autowired     // some simple bean mapper like Dozer or Orika
Mapper mapper; // for converting domain objects to DTO

@RequestMapping(...)
public MyDomainObjectDTO doSomething(@RequestBody MyDTO myDTO) {
  mapper.map(myService.foo(myDTO), MyDomainObjectDTO.class);
}
Run Code Online (Sandbox Code Playgroud)

通常的做法是服务方法收到DTO吗?

  • 如果yes:在服务方法中验证DTO的最佳做法是什么?
  • 如果no:控制器是否应该操作Domain对象并让服务保存该对象?(这对我来说似乎没用)

在我看来,服务应该只负责数据的一致性.

你是如何解决这个问题的?

duf*_*ymo 15

我的答案?都.

该服务必须检查自己的合同是否有效.

控制器是UI的一部分.它应该验证并绑定以获得更好的用户体验,但服务不应该依赖它.

该服务无法知道它是如何被调用的.如果将其包装为REST服务怎么办?

该服务还以无UI的方式了解业务逻辑违规.它需要验证以确保适当地满足用例.

双包呢; 做到这两点.


Ada*_*ent 6

请参阅我的其他答案:检查控制器或服务层中的前提条件

如果你真的想在你的服务层中进行类似于 Spring MVC 的错误处理之类的验证,你可以使用javax.validationAspectJ(建议验证方法),这就是我所做的,因为我喜欢让反射完成工作和声明式编程(注释) .

Spring MVC 不需要执行 AspectJ/AOP 来进行错误处理,因为这些方法是通过反射(url 路由/调度)调用的。

最后,对于您的 MVC 代码,您应该知道这@Valid是非官方弃用的。而是考虑@Validated哪个将利用更多的javax.validation功能。