简体   繁体   中英

Custom PropertyNamingStrategy not working in jackson

I have json string with property in Snake_Case as "Country_Code":"US","Group_Member_Code":null

to which I have to map to an object which has property in camelCase as

class Output{

    @JsonProperty("countryCode")
    private String countryCode;
    @JsonProperty("groupMemberCode")
    private String groupMemberCode;

} 

To do this as suggested in other thread i created custom PropertyNamingStratergy as

public class CustomCase extends PropertyNamingStrategy.PropertyNamingStrategyBase {

    public CustomCase() {
    }

    public String translate(String input) {
        if (input == null) {
            return input;
        } else {
            char[] arr = input.toCharArray();
            StringBuilder result = new StringBuilder();
            result.append(Character.toLowerCase(arr[0]));

            for (int i = 1; i < arr.length; i++) {
                if (arr[i] == '_') {
                    result.append(Character.toUpperCase(arr[i + 1]));
                    i++;
                } else {
                    result.append(arr[i]);
                }
            }
            return result.toString();
        }

    }
}

And I am setting it my Class in which I am deserializing as below

 JAXBContext jaxbContext =     JAXBContext.newInstance(InstinctFraudCheckXMLStringResponse.class);
 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
 InstinctFraudCheckXMLStringResponse fraudResponse = (InstinctFraudCheckXMLStringResponse)
         unmarshaller.unmarshal(new ByteArrayInputStream(response.getBytes()));

 XmlMapper xmlMapper = new XmlMapper();
 JsonNode node = xmlMapper.readTree(fraudResponse.getInstinctFraudCheckXMLStringResult().getBytes());

 ObjectMapper mapper = new ObjectMapper();
 mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
 mapper.setPropertyNamingStrategy(new CustomCase());
 fraudDecision = mapper.writeValueAsString(node);
 FraudResponse fraudResponse1 = mapper.readValue(fraudDecision,FraudResponse.class);
 System.out.println(fraudResponse1);

But it seems like that mu NamingStratergy is not working and it is not able to convert the snake_case to camel case and map it to Object , Since my FraudResponse is coming NUll always.

Please help me find out what I am missing why NamingStratgery is not working.

First of all, change your Output class as follows

class  Output {
        // Value from JsonProperty annotation removed. Will handle in naming strategy
        @JsonProperty
        private String countryCode;

        @JsonProperty
        private String groupMemberCode;

    }

Then add naming strategy to your ObjectMapper

//For jackson < 2.7
objectMapper.setPropertyNamingStrategy(
            PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);


//For jackson >= 2.7
objectMapper.setPropertyNamingStrategy(
                PropertyNamingStrategy.PropertyNamingStrategy.SNAKE_CASE);

Example

ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
    Output output = new Output();
    output.countryCode="US";
    output.groupMemberCode = "ABC";

    System.out.println(objectMapper.writeValueAsString(output));

Prints

{"country_code":"US","group_member_code":"ABC"}

I think you can try this solution (working in my case):

  1. remove @JsonProperty annotation.

  2. specify strategy with objectMapper:

     mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); 

Working example:

class Output {

    private String countryCode;

    public String getCountryCode() {
        return countryCode;
    }

    public void setCountryCode(String countryCode) {
        this.countryCode = countryCode;
    }

}

String data = "{\"Country_Code\":\"US\"}";

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

mapper.readValue(data, Output.class);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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