MVC设计-我可以在Controller类中进行域模型验证吗?

时间:2018-10-04 09:00:26

标签: java validation spring-mvc model-view-controller

以下仅是上下文的示例,不是实际的实现。使用Spring MVC,我有以下模型,该模型具有基于注释的验证。

@Entity
public class Customer {
   @Id private int id;
   @NotNull private String name;
}

以及以下 DTO 用于在 Controller的 createNewCustomer函数中映射在请求正文中接收到的数据。

public class CustmerDTO{
    private String name;
}

在我的 Controller 中,我正在使用modelMappercustomerDTO转换为新的域模型 Customer 对象。基于 @NotNull 批注,如果接收到的对象(customerDTO)的 name 属性为空,则会引发 ConstraintViolationException

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)并将其转换为域模型?

1 个答案:

答案 0 :(得分:0)

进一步研究,我得出以下结论。持久化对象的验证应尽快在属性级别进行,因为您不希望持久层或可能正在使用的任何映射器在意外发生时处理 null 。超出属性验证的所有内容,都应从contextual validation perspective处理,并传递给保存给定上下文的逻辑的方法。

  

此订单有效吗?该客户是否可以有效入住酒店。因此,与其使用isValid之类的方法,不如使用isValidForCheckIn之类的方法。