环境 :
Spring 4 REST
Spring MVC
过冬
问题 :
我们正在开发一个低于堆栈的应用程序.
Spring REST Web服务将为客户端公开API,它将在UI(ASP .NET)上显示它.响应以JSON格式发送.
考虑以下情况:
客户端调用REST api以获取具有ID的用户.dao层提取用户实体并将被提交给客户端.
以下场景的问题/观察:
由于用户可以使用与Hibernate映射相关的其他实体(例如userRoles使用oneToMany),因此还需要获取这些实体,否则抛出LazyInitialization异常,因为UI尝试通过User对象访问这些集合.
并非响应中需要User对象中的所有属性(例如:某些请求不需要用户拥有的角色).
考虑到上面的图片,通过Spring REST向客户端发送User对象(或响应)的最佳设计方法是什么?
创建一个模拟实体对象的中间对象层(如DTO).根据要求在服务层中填充此DTO.由于服务层在交易中运行,因此将解决第1号问题.但这需要在实体和DTO之间进行额外的复制
在Hibernate实体/查询级别处理问题编号1/2(连接获取查询或修改映射)并通过注释排除响应中不需要的属性,如:@JsonIgnore.但是这种方法不灵活,需要非常仔细地设计实体类
任何人都可以对此发表评论吗?还有更好的选择吗?
我强烈建议使用DTO级别,原因如下:
在某些时候,您的REST表示将无法完全匹配DAO实体。以下是一些示例:
您需要返回应用程序移动版本的轻量级用户信息的完整列表(仅用户的姓氏和名字)
您要提供从DAO加载的用户信息以及一些从单独的服务检索的付款帐户信息。
您希望将来自两个单独的DAO实体的信息合并到一个服务调用中
等等
使用某些第三方库(EhCache,Hazelcast等)或简单的类似Map的结构来缓存数据-Hibernate实体的自定义序列化对于具有复杂关系的实体可能会成为一个大麻烦。
使用DTO级别,您可以将服务接口/ DTO作为与其他组件集成的接口/客户端库。而且您仍然可以安全地修改/完全重新设计DAO层实现,甚至可以切换到例如No SQL解决方案。
结论是-在REST API中使用休眠实体对于诸如应用程序之类的简单“ Hello World”效果很好,不适用于大多数现实生活中的解决方案。