I have implemented some REST API with springMVC+Jackson+hibernate. All I needed to do is retrieve objects from database, return it as a list, the conversion to JSON is implicit.
我用springMVC+Jackson+hibernate实现了一些REST API。我所需要做的就是从数据库中检索对象,将其作为列表返回,将其转换为JSON是隐式的。
But there is one problem. If I want to add some more information to those object before return/response. For example I am returning a list of "store" object, but I want to add a name of the person who is attending right now. JAVA does not have dynamic type (how I solve this problem in C#). So, how do we solve this problem in JAVA?
但有一个问题。如果我想在返回/响应之前向这些对象添加更多的信息。例如,我正在返回一个“store”对象的列表,但是我想添加一个当前正在出席的人的名字。JAVA没有动态类型(我如何在c#中解决这个问题)。那么,我们如何用JAVA来解决这个问题呢?
I thought about this, and have come up with a few not so elegant solution. 1. use factory pattern, define another class which contain the name of that person. 2. covert store object to JSON objects (ObjectNode from jackson), put a new attribute into json objects, return json objects. 3. use reflection to inject a new property to store object, return objects, maybe SpringMVC conversion will generate JSON correctly?
我考虑过这个问题,并提出了一些不那么优雅的解决方案。1。使用工厂模式,定义另一个类,其中包含该人员的名称。2。将对象隐藏到JSON对象(来自jackson的ObjectNode)中,将一个新属性放入JSON对象中,返回JSON对象。3所示。使用反射注入一个新的属性来存储对象,返回对象,也许SpringMVC转换会正确地生成JSON ?
option 1 looks bad, will end up with a lot of boiler plate class which doesn't really useful. option 2 looks ok, but is this the best we could do with springMVC?
选项1看起来很糟糕,最后会出现很多不实用的锅炉板类。选项2看起来不错,但是这是我们使用springMVC所能做的最好的吗?
2 个解决方案
#1
1
option 1 Actually your JSON domain is different from your core domain. I would decouple them and create a seperate domain for your JSON objects, as this is a seperate concern and you don't want to mix it. This however might require a lot of 1-to-1 mapping. This is your option 1, with boilerplate. There are frameworks that help you with the boilerplate (such as dozer, MapStruct), but you will always have a performance penalty with frameworks that use generic reflection.
选项1实际上JSON域与core域不同。我将解耦它们并为JSON对象创建一个分隔域,因为这是一个分离的关注点,您不希望混合它。然而,这可能需要很多1到1的映射。这是您的选项1,带有样板文件。有一些框架可以帮助您处理样板文件(如dozer、MapStruct),但是使用泛型反射的框架总是会带来性能损失。
option 2, 3 If you really insist on hacking it in because it's only a few exceptions and not a common pattern, I would certainly not alter the JSON nodes or use reflection (your option 2 and 3). This is certainly not the way to do it in Java.
选项2,如果你真的坚持要对它进行黑客攻击,因为它只是几个例外,而不是一个常见的模式,我肯定不会改变JSON节点或者使用反射(你的选项2和3)。
option 4 [hack] What you could do is extend your core domain with new types that contain the extra information and in a post-processing step replace the old objects with the new domain objects:
选项4 [hack]你能做的就是用包含额外信息的新类型扩展你的核心域,在一个后处理步骤中将旧对象替换为新的域对象:
UnaryOperator<String> toJsonStores = domainStore -> toJsonStore(domainStore);
list.replaceAll(toJsonStores);
where the JSONStore
extends the domain Store
and toJsonStore
maps the domain Store
to the JSONStore
object by adding the person name.
JSONStore扩展域存储,toJsonStore通过添加person名称将域存储映射到JSONStore对象。
That way you preserve type safety and keep the codebase comprehensive. But if you have to do it more then in a few exceptional cases, you should change strategy.
这样,您就可以保持类型安全性并保持代码基的通用性。但如果你必须在一些特殊情况下做得更多,你应该改变策略。
#2
0
Are you looking for a rest service that return list of objects that contain not just one type, but many type of objects? If so, Have you tried making the return type of that service method to List<Object>
? I recommend to create a abstract class BaseRestResponse
that will be extended by all the items in the list which you want return by your rest service method. Then make return type as List<BaseRestResponse>
. BaseRestResponse should have all the common properties and the customized object can have the property name as you said
您是否正在寻找一个rest服务,它返回的对象列表不仅包含一种类型,还包含多种类型的对象?如果是,您是否尝试过让该服务方法的返回类型列出
#1
1
option 1 Actually your JSON domain is different from your core domain. I would decouple them and create a seperate domain for your JSON objects, as this is a seperate concern and you don't want to mix it. This however might require a lot of 1-to-1 mapping. This is your option 1, with boilerplate. There are frameworks that help you with the boilerplate (such as dozer, MapStruct), but you will always have a performance penalty with frameworks that use generic reflection.
选项1实际上JSON域与core域不同。我将解耦它们并为JSON对象创建一个分隔域,因为这是一个分离的关注点,您不希望混合它。然而,这可能需要很多1到1的映射。这是您的选项1,带有样板文件。有一些框架可以帮助您处理样板文件(如dozer、MapStruct),但是使用泛型反射的框架总是会带来性能损失。
option 2, 3 If you really insist on hacking it in because it's only a few exceptions and not a common pattern, I would certainly not alter the JSON nodes or use reflection (your option 2 and 3). This is certainly not the way to do it in Java.
选项2,如果你真的坚持要对它进行黑客攻击,因为它只是几个例外,而不是一个常见的模式,我肯定不会改变JSON节点或者使用反射(你的选项2和3)。
option 4 [hack] What you could do is extend your core domain with new types that contain the extra information and in a post-processing step replace the old objects with the new domain objects:
选项4 [hack]你能做的就是用包含额外信息的新类型扩展你的核心域,在一个后处理步骤中将旧对象替换为新的域对象:
UnaryOperator<String> toJsonStores = domainStore -> toJsonStore(domainStore);
list.replaceAll(toJsonStores);
where the JSONStore
extends the domain Store
and toJsonStore
maps the domain Store
to the JSONStore
object by adding the person name.
JSONStore扩展域存储,toJsonStore通过添加person名称将域存储映射到JSONStore对象。
That way you preserve type safety and keep the codebase comprehensive. But if you have to do it more then in a few exceptional cases, you should change strategy.
这样,您就可以保持类型安全性并保持代码基的通用性。但如果你必须在一些特殊情况下做得更多,你应该改变策略。
#2
0
Are you looking for a rest service that return list of objects that contain not just one type, but many type of objects? If so, Have you tried making the return type of that service method to List<Object>
? I recommend to create a abstract class BaseRestResponse
that will be extended by all the items in the list which you want return by your rest service method. Then make return type as List<BaseRestResponse>
. BaseRestResponse should have all the common properties and the customized object can have the property name as you said
您是否正在寻找一个rest服务,它返回的对象列表不仅包含一种类型,还包含多种类型的对象?如果是,您是否尝试过让该服务方法的返回类型列出