如何使用jackson序列化java bean并自定义映射键名?

时间:2015-10-09 09:32:24

标签: java jackson

我需要从java bean创建一个Map,这样键的前缀是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"}

我如何实现这一目标?

2 个答案:

答案 0 :(得分:2)

如果您启用了jackson-annotations:

public class Address{
    @JsonProperty("address.city")
    String city;
    @JsonProperty("address.state")
    String state;

    //setters and getters
}

在此处详细了解:https://github.com/FasterXML/jackson-annotations

答案 1 :(得分:0)

可以通过注册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;
    }
}