【问题标题】:What is the best practice to return dynamic type from a REST API in SpringMVC从 SpringMVC 中的 REST API 返回动态类型的最佳实践是什么
【发布时间】:2016-11-16 08:45:10
【问题描述】:

我已经用 springMVC+Jackson+hibernate 实现了一些 REST API。 我需要做的就是从数据库中检索对象,将其作为列表返回,到 JSON 的转换是隐式的。

但是有一个问题。如果我想在返回/响应之前向这些对象添加更多信息。例如,我要返回“商店”对象的列表,但我想添加现在正在参加的人的姓名。 JAVA 没有动态类型(我如何在 C# 中解决这个问题)。那么,我们如何在 JAVA 中解决这个问题呢?

我想过这个问题,并想出了一些不太优雅的解决方案。 1.使用工厂模式,定义另一个包含该人姓名的类。 2. 将对象隐蔽存储为JSON对象(来自jackson的ObjectNode),将新属性放入json对象,返回json对象。 3.使用反射注入新的属性来存储对象,返回对象,也许SpringMVC转换会正确生成JSON?

选项 1 看起来很糟糕,最终会产生很多没有真正用处的样板类。选项 2 看起来不错,但这是我们可以用 springMVC 做的最好的事情吗?

【问题讨论】:

    标签: java json rest spring-mvc


    【解决方案1】:

    选项 1 实际上,您的 JSON 域与您的核心域不同。我会将它们解耦并为您的 JSON 对象创建一个单独的域,因为这是一个单独的问题,您不想混合它。然而,这可能需要大量的一对一映射。这是您的选项 1,带有样板。有一些框架可以帮助您处理样板文件(例如 dozer、MapStruct),但使用通用反射的框架总是会降低性能。

    选项 2、3 如果您真的坚持要破解它,因为它只是少数例外而不是常见模式,我当然不会更改 JSON 节点或使用反射(您的选项 2 和 3)。这肯定不是在 Java 中实现的方式。

    选项 4 [hack] 您可以做的是扩展您的核心域,使用包含额外信息的新类型,并在后处理步骤中用新域对象替换旧对象:

     UnaryOperator<String> toJsonStores = domainStore -> toJsonStore(domainStore);
     list.replaceAll(toJsonStores);
    

    JSONStore 扩展域 Store 和 toJsonStore 通过添加人名将域 Store 映射到 JSONStore 对象。

    这样您就可以保持类型安全并保持代码库的全面性。但如果在少数特殊情况下你必须做更多的事情,你应该改变策略。

    【讨论】:

    • 您能详细解释一下 UnaryOperator 吗?如果 domainStore 是超类,有没有办法将所有属性从 domainStore 复制到 jsonStore? JAVA 8 中的 Lambda 会隐含地做到这一点吗?
    • 不,你必须自己映射它,要么实现映射逻辑,要么使用我在选项 1 中描述的框架之一
    【解决方案2】:

    您是否正在寻找一种返回对象列表的休息服务,该列表不仅包含一种类型,而且包含多种类型的对象?如果是这样,您是否尝试过将该服务方法的返回类型设置为List&lt;Object&gt;? 我建议创建一个抽象类BaseRestResponse,它将被列表中您希望通过您的休息服务方法返回的所有项目扩展。 然后将返回类型设为List&lt;BaseRestResponse&gt;。 BaseRestResponse 应该具有所有通用属性,并且自定义对象可以具有属性 name 如您所说

    【讨论】:

    • 我不是这个意思。在返回/响应之前,我需要为 1 种类型的对象添加一些额外的属性。
    猜你喜欢
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 2019-10-21
    • 2021-05-12
    • 1970-01-01
    • 2017-11-04
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多