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

jackson desearlization:根上有两个键。我如何打开一个而忽略另一个?

蓝慈
2023-03-14

使用杰克逊2. x

json响应如下所示:

{
 "flag": true,
 "important": {
   "id": 123,
   "email": "foo@foo.com"
 }
}

“标志”键不提供任何有用信息。我想忽略“flag”键,并将“important”值展开为important的一个实例。

public class Important {

    private Integer id;
    private String email;

    public Important(@JsonProperty("id") Integer id,
                     @JsonProperty("email") String email) {
        this.id = id;
        this.email = email;
    }

    public String getEmail() { this.email }

    public Integer getId() { this.id }
}

当我尝试向important添加@JsonRootName(“important”)并使用反序列化功能配置ObjectMapper时。UNWRAP\u ROOT\u值我收到一个JsonMappingException:

根名称“flag”与类型的预期(“important”)不匹配。。。

当我从JSON中删除“flag”键/值时,数据绑定工作得很好。如果我将@JsonIgnoreProperties(“flag”)添加到Important,我也会得到同样的结果。

更新

@JsonRootName("important")
public static class Important {
    private Integer id;
    private String email;

    @JsonCreator
    public Important(@JsonProperty("id") Integer id,
                     @JsonProperty("email") String email) {
        this.id = id;
        this.email = email;
    }

    public String getEmail() { return this.email; }

    public Integer getId() { return this.id; }
}

实际测试:

@Test
public void deserializeImportant() throws IOException {
    ObjectMapper om = new ObjectMapper();
    om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    om.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
    Important important = om.readValue(getClass().getResourceAsStream("/important.json"), Important.class);

    assertEquals((Integer)123, important.getId());
    assertEquals("foo@foo.com", important.getEmail());
}

结果:

通用域名格式。fasterxml。杰克逊。数据绑定。JsonMappingException:根名称“flag”与类型[simple type,class TestImportant$important]的预期('important')不匹配

共有1个答案

钱和平
2023-03-14

正是因为Jackson中JSON解析的流性质,恐怕没有简单的方法来处理此类情况。

在我看来,用某种包装更容易做到。

考虑以下代码:

public static class ImportantWrapper {
    @JsonProperty("important")
    private Important important;

    public Important getImportant() {
        return important;
    }
}

和实际测试:

@Test
public void deserializeImportant() throws IOException {
    ObjectMapper om = new ObjectMapper();
    //note: this has to be present
    om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    Important important = om.readValue(getClass().getResourceAsStream("/important.json"), ImportantWrapper.class)
                                .getImportant();

    assertEquals((Integer)123, important.getId());
    assertEquals("foo@foo.com", important.getEmail());
}

注意,@JsonRootName(“important”)是冗余的,在这种情况下可以删除。

这看起来有点难看,但只需相对较小的努力就可以完美地工作。这种“包装”也可以泛化,但这更像是架构的东西。

 类似资料:
  • 问题内容: 我有一个JFrame和JPanel, 里面装满了 带有 动作监听器的Jsomethings 。当用户单击一个对象时,我想打开另一个JFrame。这是我所做的: (RejectApp调用一个新的JFrame。)因此,另一个JFrame在屏幕上打开,带有更多选项。它可以正常工作(到目前为止),但是我想知道这个标准吗?我的意思是这样调用main方法?另一个问题是,不使用cardlayout(

  • 下面是fiddle http://jsfiddle.net/sgtrx/中的代码(应该在早些时候完成,对不起) 好的,我的导航栏在Div包装器内,在标题下,在内容区域(主体)的顶部。 我是个新手,所以请原谅我可能犯的任何错误。 当我添加边框来分隔每个块(按钮或文本)时,它很好地分隔了按钮,然而,它在导航栏的末尾(右侧)留下了一个小空格。 包装器Div是1000px,我有5个按钮,每个200px,因

  • 当另一个手风琴打开时,我必须关闭手风琴。我一次只能显示一个手风琴打开。目前,手风琴允许您一次打开多个面板。如果我打开一个选项卡,然后打开另一个选项卡,两个选项卡将同时打开。我只能显示一个。你能帮我吗?

  • 我正在开发一个REST API,使用Spring Boot启动数据Rest。我想与JPA同步的一个类是User类,其中包含有关用户的信息,包括谁被允许访问API。 不幸的是,拥有用户和UserRepository意味着我的用户类在API中公开。我能够删除Id(在configureRepositoryRestConfiguration函数中)、用户名和密码(通过向我的用户类的每个变量添加@JsonI

  • 我知道我可以这样用一个根上下文写两个dispatchers servlet: @override public void onStartup(ServletContext ServletContext)抛出ServletException{ } 但是我如何使用AbstractAnnotationConfigDispatcherServletInitializer来实现这一点呢?如果不可能--为什么

  • 问题内容: 除了脚本自己的控制台 (不执行任何操作)之外, 我想打开两个控制台并打印变量,并在不同的控制台中,如何实现此目的。 我不知道如何实现这一目标,并花了几个小时尝试使用诸如但没有运气的模块来实现这一目标。顺便说一下,我在窗户上。 请问模块做的工作?还是需要? 问题答案: 如果您不想重新考虑问题并使用@Kevin回答中的GUI,则可以使用module同时启动两个新控制台,并在打开的窗口中显示