【问题标题】:MVC design - Can I have domain model validation in the Controller class?MVC 设计 - 我可以在 Controller 类中进行域模型验证吗?
【发布时间】: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 中,我使用 modelMappercustomerDTO 转换为新的域模型 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 的验证,根据定义,这不是一个好习惯,因为 ControllersMVC 中是 表示层 的一部分,应该不知道如何执行数据验证,而且我想让我的控制器尽可能轻。

我可以保留这个设计吗,或者有什么好的方法可以在 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


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 2021-08-26
    • 2015-09-24
    • 1970-01-01
    • 2015-10-21
    相关资源
    最近更新 更多