简体   繁体   English

与Jackson不对称的名称/属性映射,更优雅的解决方案?

[英]Asymmetric name/property mapping with Jackson, more elegant solution?

we consume an API with our backend that outputs camelCased properties, map this to POJOs, to apply some business logic and then output it with our API to some apps. 我们使用后端输出一个API来输出camelCased属性,将其映射到POJO,应用一些业务逻辑,然后将我们的API输出到某些应用程序。 The format we want to output is snake_case properties. 我们要输出的格式是snake_case属性。

This test describes what we want to do: 该测试描述了我们想要做的事情:

@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);
}

At the moment the model class looks like this: 目前模型类看起来像这样:

@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;
    }
}

It works but I think it's not very elegant since our input is always camelcase and the output is always snakecase. 它可以工作,但我认为它不是很优雅,因为我们的输入始终是camelcase,输出总是蛇形。 Is there a way to globally set JSON serialization to snakecase and deserialization to camelcase for jackson? 有没有办法全局设置JSON序列化为snakecase和反序列化为camelcase为jackson? (we are using it together with RestTemplate in Spring, if that makes any difference) (我们在Spring中将它与RestTemplate一起使用,如果这有任何区别的话)

Cheers 干杯

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

Use a separately configured ObjectMapper for your output: 使用单独配置的ObjectMapper作为输出:

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

Using that for writing the output ensures that properties are always written in snake case. 使用它来编写输出可确保始终以蛇形表示属性。

Or if you need to use only a single ObjectMapper instance, create your own forwarding ProptertyNamingStrategy : 或者,如果您只需要使用一个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);
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM