Home > Net >  JacksonXML: Resolve inconventional json field name without annotation
JacksonXML: Resolve inconventional json field name without annotation

Time:01-22

I have a java project where one of my packages contain a lot of dataclasses. These classes are used with deserialization. Currently the package depends on fasterXML only because one of my classes has this field:

String eMail;

I would like to remove the dependency to fasterXML but I have the following problem.

val mapper = new ObjectMapper();
  
// Produces UnrecognizedPropertyException: Unrecognized field "eMail" 
// because by default it expects eMail with a lower case 'm'
val res1 = mapper.readValue("{\"eMail\":\"asd\"}", PP.class);
  
// BTW this Produces '{"email":"asd"}'  --> 'm' in eMail is lower case!
val res2 = mapper.writeValueAsString(new PP() {{setEMail("asd");}});

Where the PP class is

@Getter
@Setter
private static class PP {
    private String eMail;
}

I CANNOT change the json format!

Is it possible to somehow correctly readValue(PP) without using the JsonProperty annotation? Maybe configuring the objectMapper somehow? The only field I have problem is this one. :(

Thanks!

CodePudding user response:

You could make an intermediate class

@Getter
@Setter
private static class IntermediatePP {
    private String email;

    public PP convert() {
        PP output = new PP();
        output.setEMail(this.email);
        return output
    }
}

Then change your code to

val res1 = mapper.readValue("{\"eMail\":\"asd\"}",
                     IntermediatePP.class).convert();

CodePudding user response:

It is possible to correctly read the JSON by configuring the ObjectMapper object. One way to do this is by using the setPropertyNamingStrategy method to set a custom PropertyNamingStrategy that maps the JSON field eMail to the class field eMail.

Here is an example:

ObjectMapper mapper = new ObjectMapper();

mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
    @Override
    public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
        if (field.getFullName().equals("com.example.PP.eMail")) {
            return "eMail";
        }
        return super.nameForField(config, field, defaultName);
    }
});

String json = "{\"eMail\":\"asd\"}";
PP res1 = mapper.readValue(json, PP.class);
System.out.println(res1.getEMail()); // prints "asd"

This example creates a custom PropertyNamingStrategy that checks if the field is the eMail field in the com.example.PP package, and if so, returns "eMail" as the field name. For all other fields, it uses the default naming strategy.

  • Related