使用Jackson的非对称名称/属性映射,更优雅的解决方案?

时间:2017-01-30 10:14:33

标签: java spring jackson

我们使用后端输出一个API,输出camelCased属性,将其映射到POJO,应用一些业务逻辑,然后将我们的API输出到某些应用程序。我们想要输出的格式是snake_case属性。

此测试描述了我们想要做的事情:

@Test
public void mappingTest() throws IOException {
    String input = "{ \"merchantId\": 23, \"contactName\": \"foobar\" }";

    ObjectMapper mapper = new ObjectMapper();
    Merchant merch = mapper.readValue(input, Merchant.class);

    String output = mapper.writeValueAsString(merch);

    String expectedOutput = "{ merchant_id: 23, contact_name: 'foobar' }";
    assertEquals("", expectedOutput, output);
}

目前模型类看起来像这样:

@JsonInclude(Include.NON_NULL)
public class Merchant {

    private String merchantId;
    private String contactName;

    public Merchant() {
    }

    public Merchant(final String merchantId, final String contactName) {
        this.merchantId = merchantId;
        this.contactName = contactName;
    }

    @JsonProperty("contact_name")
    public String getContactName() {
        return contactName;
    }

    @JsonProperty("contactName")
    public void setContactName(final String contactName) {
        this.contactName = contactName;
    }

    @JsonProperty("merchant_id")
    public String getMerchantId() {
        return merchantId;
    }

    @JsonProperty("merchantId")
    public void setMerchantId(final String merchantId) {
        this.merchantId = merchantId;
    }
}

它有效,但我认为它不是很优雅,因为我们的输入始终是camelcase,输出总是蛇形。有没有办法全局设置JSON序列化为snakecase和反序列化为camelcase为jackson? (我们将它与Spring中的RestTemplate一起使用,如果这有任何区别的话)

干杯

2 个答案:

答案 0 :(得分:2)

您可以实现并注册自己的PropertyNamingStrategy,分别为public String nameForGetterMethod(...)public String nameForSetterMethod(...)方法定义不同的逻辑。

答案 1 :(得分:0)

为输出使用单独配置的ObjectMapper

ObjectMapper outputMapper = new ObjectMapper();
outputMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

使用它来编写输出可确保始终以蛇形式写入属性。

或者,如果您只需要使用一个ObjectMapper个实例,请创建自己的转发ProptertyNamingStrategy

PropertyNamingStrategy myStrategy = new PropertyNamingStrategy() {
    @Override
    public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        return PropertyNamingStrategy.SNAKE_CASE.nameForGetterMethod(config, method, defaultName);
    }

    @Override
    public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        return PropertyNamingStrategy.LOWER_CAMEL_CASE.nameForSetterMethod(config, method, defaultName);
    }
};