【问题标题】:How do I serialize a java bean using jackson and customize map key name?如何使用 jackson 序列化 java bean 并自定义映射键名称?
【发布时间】:2015-10-09 09:32:23
【问题描述】:

我需要从 java bean 创建一个映射,以便键以 java bean 变量的名称为前缀。我为此使用杰克逊。示例如下:

public class Address{
        String city;
        String state;

        //setters and getters
    }   

Address address = new Address();
address.setCity("myCity");
address.setState("myState");

我正在使用以下方法创建地图:

ObjectMapper objectMapper = new ObjectMapper();
Map map = objectMapper.convertValue(address, HashMap.class);

这给了我以下输出:

{"city":"myCity", "state":"myState"}

我需要在键中添加类变量名,如下所示:

{"address.city":"myCity", "address.state":"myState"}

我如何做到这一点?

【问题讨论】:

    标签: java jackson


    【解决方案1】:

    如果您启用了 jackson-annotations:

    public class Address{
        @JsonProperty("address.city")
        String city;
        @JsonProperty("address.state")
        String state;
    
        //setters and getters
    }
    

    在此处了解更多信息:https://github.com/FasterXML/jackson-annotations

    【讨论】:

    • 我不能修改类。另外,我需要使用不同的类,所以我不能全部修改。
    • 您可以创建一个扩展Address或接口的桥类并对其进行注释
    【解决方案2】:

    可以通过注册 BeanSerializerModifier 来自定义 bean 序列化。这特别支持通过将 NameTransformer 应用于每个 BeanPropertyWriter 来重命名属性。

    @Test
    public void prepend_class_name_to_property_keys() throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        Function<Class<?>, String> classPrefix = clazz -> clazz.getSimpleName().toLowerCase() + ".";
        mapper.registerModule(new Module() {
            @Override
            public String getModuleName() {
                return "Example";
            }
    
            @Override
            public Version version() {
                return Version.unknownVersion();
            }
    
            @Override
            public void setupModule(SetupContext context) {
                context.addBeanSerializerModifier(new BeanSerializerModifier() {
                    @Override
                    public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
                            BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
                        String prefix = classPrefix.apply(beanDesc.getBeanClass());
                        return beanProperties.stream().map(prop -> prop.rename(new NameTransformer() {
                            @Override
                            public String transform(String name) {
                                return prefix + name;
                            }
    
                            @Override
                            public String reverse(String transformed) {
                                return transformed.substring(prefix.length());
                            }
                        })).collect(toList());
                    }
                });
            }
        });
        assertThat(mapper.writeValueAsString(new Address("somewhere", "someplace")),
                equivalentTo("{ 'address.line1' : 'somewhere', 'address.line2' : 'someplace'}"));
    }
    
    public static final class Address {
        public final String line1;
        public final String line2;
    
        public Address(String line1, String line2) {
            this.line1 = line1;
            this.line2 = line2;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多