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

时间:2013-09-30 17:34:22

标签: spring validation spring-mvc service dto

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

  some DTO from browser

            v

Spring @Controller method

            v

  Spring @Service method

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

  • 我知道@Valid注释在@Controller方法中非常有用。
  • 为什么@Valid @Service方法中工作?

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


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

MyDTO.java:

public class MyDTO {
   @NotNull
   public String required
   @Min(18)
   public int age;
}

MyServiceImpl.java:

public MyDomainObject foo(MyDTO myDTO) {
  // persist myDTO
  // and return created domain object
}

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);
}

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

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

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

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

2 个答案:

答案 0 :(得分:13)

我的回答?两者。

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

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

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

该服务还以无UI的方式了解业务逻辑违规。它需要进行验证以确保用例得到适当的实现。

双袋;做到这两点。

答案 1 :(得分:3)

请参阅我的其他答案:Check preconditions in Controller or Service layer

如果您真的想在服务层中进行类似于Spring MVC的错误处理验证,可以使用javax.validation和AspectJ(建议验证方法)这是我的工作,因为我喜欢做反射做工作和声明性编程(注释)。

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

最后,对于您的MVC代码,您应该知道@Valid是非正式弃用的。相反,请考虑@Validated,它将利用更多javax.validation功能。