【发布时间】:2019-03-09 14:51:00
【问题描述】:
以下只是上下文的示例,而不是实际的实现。使用 Spring MVC,我有以下 Model,它具有基于注释的验证。
@Entity
public class Customer {
@Id private int id;
@NotNull private String name;
}
下面的DTO用来映射Controller的createNewCustomer函数中请求正文中接收到的数据。
public class CustmerDTO{
private String name;
}
在我的 Controller 中,我使用 modelMapper 将 customerDTO 转换为新的域模型 Customer 对象。根据 @NotNull 注释,如果接收对象 (customerDTO) 的 name 属性为空,则抛出 ConstraintViolationException。 p>
public class CustomerController {
@Autowired private CustomerService customerService;
@Autowired private ModelMapper modelMapper;
@PostMapping(value = "/customer")
public Customer createNewCustomer (@RequestBody CustomerDTO customerDTO) {
try {
Customer newCustomer = modelMapper.map(customerDTO, Customer.class);
return customerService.saveCustomer(newCustomer);
}
catch (ConstraintViolationException e) {
throw new CustomerMissingInformation();
}
}
}
正如您在此处看到的,我在 Controller 中处理 Customer 的验证,根据定义,这不是一个好习惯,因为 Controllers在 MVC 中是 表示层 的一部分,应该不知道如何执行数据验证,而且我想让我的控制器尽可能轻。
我可以保留这个设计吗,或者有什么好的方法可以在 Service 层中移动我的验证,同时保留验证注释并允许 Controller 能够接收表示对象(DTOs)并将其转换为领域模型?
【问题讨论】:
-
您可以创建一个额外的类来验证您的约束,如图所示here... 甚至还有一个验证器接口:
org.springframework.validation.Validator; -
尝试休眠验证器参考tutorialspoint.com/springmvc/springmvc_hibernate_validator.htm。您可以在模型类本身中定义验证。
-
为什么不在服务类中进行验证,这就是逻辑应该在的地方,控制器应该只控制数据流入和流出应用程序。
-
@AmanJ 因为在客户属性上具有验证注释(例如,在名称属性上的 NotNull),当我在控制器中映射收到的 DTO 到新客户对象(customerDTO -> newCustomer)时,如果DTO 中缺少标题会引发错误
-
@AdrianBrad 在服务类中接收 CustomerDTO 并在那里进行转换
标签: java validation spring-mvc model-view-controller