- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一个与后端微服务通信的 REST API 规范,它返回以下值:
关于“Collection ”响应(例如 GET/users):
{
users: [
{
... // single user object data
}
],
links: [
{
... // single HATEOAS link object
}
]
}
关于“单一对象”响应(例如 GET /users/{userUuid}
):
{
user: {
... // {userUuid} user object}
}
}
选择这种方法是为了使单个响应可以扩展(例如,如果 GET /users/{userUuid}
在 ?detailedView=true
处获得额外的查询参数,我们将获得额外的请求信息)。
从根本上说,我认为这是一种可以最大限度地减少 API 更新之间的重大更改的方法。然而,将这个模型转化为代码非常困难。
假设对于单个响应,我为单个用户提供以下 API 模型对象:
public class SingleUserResource {
private MicroserviceUserModel user;
public SingleUserResource(MicroserviceUserModel user) {
this.user = user;
}
public String getName() {
return user.getName();
}
// other getters for fields we wish to expose
}
这种方法的优点是我们可以仅公开内部使用的模型中的字段,我们有公共(public)getter,但不能公开其他字段。然后,对于集合响应,我将有以下包装类:
public class UsersResource extends ResourceSupport {
@JsonProperty("users")
public final List<SingleUserResource> users;
public UsersResource(List<MicroserviceUserModel> users) {
// add each user as a SingleUserResource
}
}
对于单个对象响应,我们将有以下内容:
public class UserResource {
@JsonProperty("user")
public final SingleUserResource user;
public UserResource(SingleUserResource user) {
this.user = user;
}
}
这会产生 JSON
根据本文顶部的 API 规范格式化的响应。这种方法的好处是我们只公开那些我们想要公开的字段。严重的缺点是我有一个 ton 的包装类飞来飞去,除了被 Jackson 读取以产生正确格式的响应之外,它们没有执行任何可识别的逻辑任务。
我的问题如下:
我怎样才能概括这种方法?理想情况下,我想要一个 BaseSingularResponse
我的所有模型都可以扩展的类(也许是 BaseCollectionsResponse extends ResourceSupport
类),但是看到 Jackson 似乎如何从对象定义中派生 JSON 键,我将不得不使用类似 Javaassist
的东西在运行时向基本响应类添加字段 - 我希望尽可能远离人类的肮脏黑客行为。
有没有更简单的方法来做到这一点?不幸的是,一年后我的响应中可能会有数量可变的顶级 JSON 对象,所以我不能使用 jackson 的 SerializationConfig.Feature.WRAP_ROOT_VALUE
之类的东西。因为这会将 所有内容 包装到单个根级对象中(据我所知)。
可能有类似 @JsonProperty
的东西吗?对于类级别(而不仅仅是方法和字段级别)?
最佳答案
有几种可能。
您可以使用 java.util.Map
:
List<UserResource> userResources = new ArrayList<>();
userResources.add(new UserResource("John"));
userResources.add(new UserResource("Jane"));
userResources.add(new UserResource("Martin"));
Map<String, List<UserResource>> usersMap = new HashMap<String, List<UserResource>>();
usersMap.put("users", userResources);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(usersMap));
您可以使用 ObjectWriter
来包装您可以使用的响应,如下所示:
ObjectMapper mapper = new ObjectMapper();
ObjectWriter writer = mapper.writer().withRootName(root);
result = writer.writeValueAsString(object);
这是一个概括这种序列化的命题。
处理简单对象的类:
public abstract class BaseSingularResponse {
private String root;
protected BaseSingularResponse(String rootName) {
this.root = rootName;
}
public String serialize() {
ObjectMapper mapper = new ObjectMapper();
ObjectWriter writer = mapper.writer().withRootName(root);
String result = null;
try {
result = writer.writeValueAsString(this);
} catch (JsonProcessingException e) {
result = e.getMessage();
}
return result;
}
}
处理集合的类:
public abstract class BaseCollectionsResponse<T extends Collection<?>> {
private String root;
private T collection;
protected BaseCollectionsResponse(String rootName, T aCollection) {
this.root = rootName;
this.collection = aCollection;
}
public T getCollection() {
return collection;
}
public String serialize() {
ObjectMapper mapper = new ObjectMapper();
ObjectWriter writer = mapper.writer().withRootName(root);
String result = null;
try {
result = writer.writeValueAsString(collection);
} catch (JsonProcessingException e) {
result = e.getMessage();
}
return result;
}
}
还有一个示例应用程序:
public class Main {
private static class UsersResource extends BaseCollectionsResponse<ArrayList<UserResource>> {
public UsersResource() {
super("users", new ArrayList<UserResource>());
}
}
private static class UserResource extends BaseSingularResponse {
private String name;
private String id = UUID.randomUUID().toString();
public UserResource(String userName) {
super("user");
this.name = userName;
}
public String getUserName() {
return this.name;
}
public String getUserId() {
return this.id;
}
}
public static void main(String[] args) throws JsonProcessingException {
UsersResource userCollection = new UsersResource();
UserResource user1 = new UserResource("John");
UserResource user2 = new UserResource("Jane");
UserResource user3 = new UserResource("Martin");
System.out.println(user1.serialize());
userCollection.getCollection().add(user1);
userCollection.getCollection().add(user2);
userCollection.getCollection().add(user3);
System.out.println(userCollection.serialize());
}
}
你也可以在类级别使用Jackson注解@JsonTypeInfo
@JsonTypeInfo(include=As.WRAPPER_OBJECT, use=JsonTypeInfo.Id.NAME)
关于java - Spring 启动 : Wrapping JSON response in dynamic parent objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41880572/
我创建了一个包含社交图标的列表。这些图标应该环绕在小屏幕上。 我使用 flex-wrap: wrap; 它在 Firefox 和 Chrome 中完美运行: 但是 Internet Explorer
我很惊讶地发现我的 white-space: pre-wrap;文本在 > 换行和 "人物。我以为它只会换行,- , 以及一个或多个空格之后。 这是一个fiddle . 它在" 之后换行, 在
我被分配了重新创建以下网站的任务:https://plantanapp.com/learn 我做了一些事情,但是每次我解决一个问题时,都会出现另外两个问题。 我是HTML和CSS的新手,并不真正了解元
我偶然发现了 jQuery 的 wrap() 函数。 当我试图包装两个 div 标签时,它们之间有一些文本,而不是两个 div 之间没有文本时,它的行为不知何故不同。 j查询: var wrapper
我正在尝试在 w3c css 验证器上验证一个 css 文件。当它被测试时,它返回一个错误,指出 “属性 flex-wrap- 不存在:wrap”。这是我 css 验证器认为错误的部分。 .row {
这个问题在这里已经有了答案: Flex items create space between them when they wrap [duplicate] (1 个回答) 关闭 6 年前。 我正在
我正在制作一个网页,其中的标题有一个主要主题和一个描述符,每个都包含在标签中。 我已经查找了 标签,它似乎只在你有长字符串时才有效没有空格。但是我在文本中断断续续地有空格。 我需要的是我可以在两个元
我听到很多关于 wrap 面板加载速度较慢的消息,因此我们需要一个虚拟化面板。 有人可以给我一个小的环绕面板示例,它可以证明加载速度较慢等它需要一个虚拟面板。 我设置了一个环绕面板作为列表框的面板控件
我需要用 sinon 多次包装一个方法,以便能够根据参数返回不同的对象。我该怎么做? 我要测试的 Controller 看起来像这样: const servicePackagesOfferingRep
我在运行测试时收到了上述错误消息。下面是我的代码(我正在使用 Backbone JS 和 Jasmine 进行测试)。有谁知道为什么会这样? $(function() { describe("Ca
问题是关于.text-wrapper,它有display:flex; flex-wrap:wrap 应用于它。使用 flex-wrap:wrap 的原因是,否则 .text-wrapper 和 .ta
我有三个带有 Bootstrap 3 的 DIV 容器,其中前两个在第一行,第三个在下一行,直到浏览器宽度直到 991 px。高于 992 px,所有三个容器应排成一行。每行容器的高度应该是最高的 (
(我使用的是 Chrome v.39+) 我正在尝试使用 flex-wrap 属性水平和垂直堆叠子 div,但我看到了一些非常奇怪的行为。例如,如果有 3 个子 div,最后一个的宽度为 100%(使
我必须这样做。适用于宽屏、中屏和小屏 https://pp.vk.me/c629328/v629328337/21bd7/izp9QG8Qcg4.jpg 这是我的代码 .section-items-c
我想要一个每行 3 个元素的容器 flex div,问题是当我添加第四个元素时(它应该自动换行到第二行),而不是它停留在一行并缩小其他元素。我启用了 flex-wrap: wrap; 这是我的代码:
假设我正在使用一个带有 flex-direction:row 和 flex-wrap:wrap 的 flexbox 容器。 根据浏览器窗口的大小,每行中可能有 2、3、4 或更多项。 我想在每隔一行的
我已经添加了所有属性。当我更改浏览器宽度时,它们开始相互粘连,这是因为我有太多图像而无法正常工作? 无法将图像换行: #skills>div { margin-top: 80px; displ
我想制作一个网格,其中每行有两张图片。我正在使用 flex-wrap: wrap;它在 android 4.4+ 上运行良好,但不适用于低于 android 4.4 的系统。我想在不使用 flex-w
我的网站出现异常行为。我最近在网站管理员工具上发现,它发现我网站上的许多网页都出现抓取错误 404。我无法理解这些页面是如何创建的,因为所有 404 页面最后都包含这几个字 wrap-function
我正在使用 MongoDB C# 驱动程序构建一些更新语句。 The C# API在 Builder 命名空间中包括 Wrapped 和“Un-Wrapped”方法。 从表面上看,这些似乎因泛型不同而
我是一名优秀的程序员,十分优秀!