当前位置: 首页 > 知识库问答 >
问题:

带有Jersey和Jackson的地图的序列化和反序列化

孙洋
2023-03-14

我有一个Pojo对象,由Jersey使用jackson序列化:

public class BookOfFriendsAnswer {
private Map<String, List<BookSummary>> books;

public BookOfFriendsAnswer() {

}

public BookOfFriendsAnswer(Map<String, List<BookSummary>> books) {
    this.books = books;
}

public Map<String, List<BookSummary>> getBooks() {
    return books;
}

public void setBooks(Map<String, List<BookSummary>> books) {
    this.books = books;
}
}

序列化产生了一个像这样的Json:

{
  "books": {
    "entry": [
      {
        "key": "54567bbce4b0e0ef9379993e",
        "value": "BookSummary{id='54567bbde4b0e0ef9379993f', title='title 1', authors=[Steve,James] } BookSummary{id='54567bd9e4b0e0ef93799940', title='Title 2', authors=[Simon, Austin]}"
      }
    ]
  }
}

但是,当我尝试像这样反序列化来自客户端的消息时:

mapper.readValue(json, clazz)

我得到以下错误:

无法识别的字段“键”(类com.example.server.api.书摘),未标记为可忽略

我不知道问题是来自服务器生成的JSOn还是来自客户端的反序列化。

您知道问题是什么以及如何纠正吗?

非常谢谢。

共有2个答案

严昀
2023-03-14

我认为您应该创建特定的Map类型并将其提供到反序列化过程中:

TypeFactory typeFactory = mapper.getTypeFactory();
MapType mapType = typeFactory.constructMapType(HashMap.class, String.class, ArrayList.class);
HashMap<String, List<BookSummary>> map = mapper.readValue(json, mapType);
孙琨
2023-03-14

所以经过一点测试之后:

  • 球衣1.18.1(带有球衣-json-1.18.1用于JSON支持)
  • 球衣2.13(带有球衣-媒体-json-jackson-2.13用于JSON支持)
  • 球衣2.13(带有球衣-媒体-moxy-2.13用于JSON支持)

最后一个测试(jersey-media-moxy-2.13)是唯一一个产生这个精确输出的测试

{
  "books": {
    "entry": [
      {
        "key": "54567bbce4b0e0ef9379993e",
        "value": "BookSummary{id='54567bbde4b0e0ef9379993f', title='title 1', authors=[Steve,James] } BookSummary{id='54567bd9e4b0e0ef93799940', title='Title 2', authors=[Simon, Austin]}"
      }
    ]
  }
}

话虽如此,我会假设您使用的是泽西岛 2.x 版本。我不确定 MOXy 中是否有任何配置可以更好地支持此用例,但为了使事情变得简单,只需添加以下依赖项,然后摆脱 MOXy

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>${jersey-version}</version>
</dependency>

这样,您将得到正确的JSON输出

{ //  BookOfFriendsAnswer object
    "books": {  // Map<String, List<BookSummary>> books
        "randomKey": [  // String (key) , List<BookSummary> (value)
            {  // BookSummary object
                "id": "54567bbde4b0e0ef9379993f",
                "title": "Title 1",
                "authors": ["Steve", "James"]
            }
        ]
    }
}

资源法

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getResponse() {
    BookOfFriendsAnswer books = new BookOfFriendsAnswer();
    String id = "randomKey";  <===== Not sure if you want the key to be 
                                     the BookSummary id
    BookSummary summary = new BookSummary();
    summary.setId(id);
    summary.setTitle("Title 1");
    summary.getAuthors().add("Steve");
    summary.getAuthors().add("James");
    List<BookSummary> summaries = new ArrayList<>();
    summaries.add(summary);
    books.getBooks().put("randomKey", summaries);
    return Response.ok(books).build();
}

使用 ObjectMapper 进行测试

@Test
public void testGetIt() throws Exception {
    String responseMsg = target.path("book").request().get(String.class);
    ObjectMapper mapper = new ObjectMapper();
    BookOfFriendsAnswer books = mapper.readValue(
            responseMsg, BookOfFriendsAnswer.class);
    System.out.println(books);
}

不使用 ObjectMapper 进行测试 - 使用自动配置的 Jackson 提供程序

@Test
public void testGetIt() throws Exception {
    BookOfFriendsAnswer responseMsg
            = target.path("book").request().get(BookOfFriendsAnswer.class);
    System.out.println(responseMsg);
}
 类似资料:
  • 问题内容: 我无法找出使用杰克逊实现自定义序列化/反序列化的正确方法。我有很多类(〜50),它们带有应被序列化/反序列化而不是原始的原始字段。喜欢: 所有序列化和反序列化都非常相似,我只需要在整数之后添加一个后缀(C,页面,米等)。 一种简单的方法是在每个这样的字段中添加一对/ 注释并实现它们。但是我最终会得到100个 非常相似的 序列化器/反序列化器。 我想到了添加自定义注释的各个领域,说或,这

  • 可以序列化/反序列化< code >映射吗 在这种特殊情况下,我知道总是,和 - 第三方类(我有序列化器和反序列化器),其他值是盒装原语。 有可能和杰克逊做这样的事吗?使用MapSerializer/MapDeserializer可以做到这一点吗?(我找不到任何例子)

  • 我使用的是JAVA 1.6和Jackson 1.9.9我有一个枚举 我添加了一个@jsonValue,这似乎完成了它将对象序列化为:

  • 问题内容: 我正在使用JAVA 1.6和Jackson 1.9.9我有一个枚举 我添加了一个@JsonValue,这似乎可以将对象序列化为: 但是当我尝试反序列化时,我得到了 我在这里想念什么? 问题答案: 如果你希望将枚举类与其JSON表示完全脱钩,则@xbakesx指出的序列化器/反序列化器解决方案是一个很好的解决方案。 另外,如果你喜欢一个独立的解决方案,则基于·和·注释的实现会更方便。 因

  • 序列化和反序列化的方式不同于 我已经创建了两个序列化程序 和 我用Jackson查看了序列化/反序列化映射 ,但找不到解决方案。

  • I'va是一个OID接口,可以由许多具体类型实现: 现在我有一个具有两个字段的对象,一个使用抽象接口类型(OID)定义,另一个使用具体类型(MyOID)定义 我想使用jackson以不同的方式序列化/反序列化字段,无论它们是使用抽象接口类型还是具体类型定义的: 注意,被序列化,包括类型信息(多态序列化),而被序列化为文本 为此,我将OID接口注释为: 并为每个具体类型分配了类型id: 最后,对容器