我正在使用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对象并让服务保存该对象? (这对我来说似乎没用)在我看来,服务应该只负责数据的一致性。
你是如何解决这个问题的?
答案 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
功能。