java - 使用 Jackson 反序列化 Json 时如何对所有值应用转换

标签 java jackson

我想用 Jackson 解析一个 JSON 文档并在所有节点上应用一些转换。例如,假设我希望所有值在反序列化后都为大写。

实际用例有点复杂:

  • 转换比较复杂,transformer类需要注入(inject)一些配置,我希望它是一个可配置的实例
  • 必须对所有属性进行转换,我希望能够不在每个反序列化类的每个属性上添加注释。

Jackson 中有足够的配置选项/ Hook ,所以我相当确定这是可能的,我只是找不到解决办法。

下面的测试显示了我正在努力实现的目标:

public class JsonValueFilterTest {

    private ObjectMapper mapper;

    @Before
    public void setupObjectMapper() {
        mapper = new ObjectMapper();
        // TODO: configure mapper to upper case all values
    }

    @Test
    public void printJson() throws IOException {
        Entity myEntity = new Entity("myName");
        mapper.writeValue(System.out, myEntity); // prints: {"name":"myName"}
    }

    @Test
    public void valuesAreUpperCasedWhenLoaded() throws IOException {
        Entity myEntity = mapper.readValue("{\"name\":\"myName\"}", Entity.class);
        assertThat(myEntity.getName()).isEqualTo("MYNAME"); // fails
    }

    public static class Entity {
        private final String name;

        @JsonCreator
        public Entity(@JsonProperty("name") String name) { this.name = name; }

        public String getName() { return name; }

        @Override
        public String toString() { return "name='" + name + "'"; }
    }
}

最佳答案

对于这种简单的情况,您可以使用转换器来不实现自定义解串器。我不知道为什么,但它不适用于创建者构造函数。因此,您将不得不使用非最终字段。

public class JsonValueFilterTest {

    private ObjectMapper mapper;

    @BeforeTest
    public void setupObjectMapper() {
        mapper = new ObjectMapper();
    }

    @Test
    public void printJson() throws IOException {
        Entity myEntity = new Entity("myName");
        mapper.writeValue(System.out, myEntity); // prints: {"name":"myName"}
    }

    @Test
    public void valuesAreUpperCasedWhenLoaded() throws IOException {
        Entity myEntity = mapper.readValue("{\"name\":\"myName\"}", Entity.class);
        Assert.assertEquals(myEntity.getName(), "MYNAME"); // fails
    }

    public static class UpCaseConverter extends StdConverter<String, String> {
        public String convert(String value) {
            return value==null ? null : value.toUpperCase();
        }
    }

    public static class Entity {

        private String name;

        public Entity() {}

        public Entity(String name) {
            this.name = name;
        }

        @JsonDeserialize(converter = UpCaseConverter.class)
        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return "name='" + name + "'";
        }
    }
}

关于java - 使用 Jackson 反序列化 Json 时如何对所有值应用转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34833328/

相关文章:

java:如果总是在锁释放之前调用 notify(),等待的线程如何获得同一个锁?

java - GregorianCalendar 无法添加 97 天?

java - Jackson 自定义序列化器

java - 升级库版本后Eclipse编译器错误

java - 如何在自己的自定义反序列化器中使用一些 Jackson 反序列化器?

java - 正则表达式不包含两个或多个连续的逗号或连字符,并且数字之间最多有一个连字符

java - JDBC MySql连接池实践避免连接池耗尽

java - 使用 Jackson(Joda-Time 模块)进行 DateTime 反序列化的默认时区

java - 获取对象键并将其用作 Jackson 中的属性

java - Struts2 和 OpenCSVWriter 中的相对路径