值对象在Spring MVC应用中的实际应用



在我用Hibernate和Spring MVC编写的应用程序中,我有简单的类,代表客户,他的主要办公室地址和他其余办公室的位置列表。有一个表单允许添加和编辑客户的数据,然后Spring MVC将其映射到DTO,验证,发送到服务,将其转换为(略有不同的)实体并保存。

我考虑过使用值对象来表示和隐式验证某些对象 - 即电话号码,地址,但我真的不知道如何在这些框架中使用它们 - 即使我认为我理解价值对象概念和不变性。

如果我在表示层中使用的 DTO 中使用它们,那么我就不能依赖 Spring 机制将字段从表单映射到对象 - 因为没有二传手。我必须在控制器或服务中手动进行映射。

我应该在实体中使用值对象(嵌入它们)吗?或者,也许这种情况太简单而无法使用值对象?

您的问题主要不是关于值对象,而是您的主要关注点(如果我理解正确的话)是如何从 Web 表单发送数据、验证数据并将数据保存在实体中。

创建一个表单对象,例如MyForm,其中包含用户可以在屏幕中输入的所有字段。表单对象用于将数据传输到服务器,例如:

class MyForm {
    @NotBlank
    private String name;
    @NotBlank
    private String phoneNumber;
    @NotBlank
    private String address;
    // getters and setters
}

在服务器端控制器验证、转换和存储数据:

@Controller
class GuestbookController {
    @RequestMapping(value = "/guestbook", method = RequestMethod.GET)
    String myget(Model model, MyForm form) {
        // put data on model
    }
    @RequestMapping(value = "/mysubmit", method = RequestMethod.POST)
    String mysubmit(@Valid MyForm form, Errors errors, Model model) {
        if (errors.hasErrors()) {
            return myget(model, form);
        }
        myrepository.save(new MyEntity(form.getName(), form.getPhoneNumber(), form.getAddress()));
        return "redirect:/myview";
    }
}

您可能需要有关地址的更多详细信息,而不是单个字符串中的内容。然后,是的,使用包含所有地址详细信息的值对象就可以了。

这是我的拙劣回应。

  • DTO 是没有逻辑的简单数据容器,
  • 和值对象相反,封装逻辑。

有趣的是,DTO过去在Java中被称为值对象。

查看它的一种方法(正如我所读的)是让值对象封装实体的所有逻辑,这些实体只处理标识

DTO 允许将域模型与 UI(或任何其他端口/适配器)分离。

值对象应该在域层之外使用吗?我不知道,但我个人不这样做。在我的设置中,它们由应用层和域内部使用,但在应用层之外只有 DTO。

我有 Spring 可以处理的 DTO 和数据映射器来进行转换(dto 在 UI/应用程序层边界建模)。DTO通常可以有二传手(根据某些人的说法,事件公共财产)。

现在,如果要使用框架映射的不可变对象,解决方案取决于您使用的技术。当我使用 JSON(和杰克逊)做 Web 服务时,我直接使用构造函数上的注释映射不可变命令对象@JsonCreator但我将我的 pojos 与杰克逊耦合。为避免这种情况,您还可以将客户序列化程序添加到框架中,使其围绕控制器方法参数自动转换数据结构。

否则,始终可以使用数据映射器或工厂方法进行映射。(我相信你写了一篇关于这个的帖子...

相关内容

  • 没有找到相关文章

最新更新