简体   繁体   中英

Java sprintboot saving one JSON field to two Java fields without setters

I am using sprintboot and I have a model like:

public class Source {

    @NotNull
    @NSDash
    @ValidStandardRulePluritent
    @ValidStandardRuleIPS
    @ValidStandardRuleLasto
    @ValidStandardRuleSomact
    @ValidStandardRuleSotipo
    @NotCompatibleForAlg
    @NotCompatibleForAdaq
    @RuleXioISO
    @JsonDeserializer(using=XioDeserializer.class)
    public String ambian1;
    
    public String raw_ambian1;

    @NotNull
    @NSDash
    @ValidStandardRuleIPS
    @ValidStandardRuleLasto
    @ValidStandardRuleSotipo
    @NotCompatibleForAlg
    @NotCompatibleForAdaq
    public String xebian1;

    public String raw_xebian1;

    # i have more than 100+ other field use this:
    
}

I want to parse this data into a fixed version, but still retain the original raw version.

{"ambian1":"a--1.1-bc.8i", "xebian1":"x--2.1-za.5t", and rest of data}

The ambian1 data can't start with a number.

  • "a--1.1-bc.8i" would be valid
  • "1a--1.1-bc.8i" would be invalid

So I want my java class to get parsed as:

ambian1 = a--1.1-bc.8i raw_ambian1 = 1a--1.1-bc.8i

I tried to use @JsonAlias but it didn't work. I also tried to use @JsonProperty but I got error: Multiple fields representing property .

public class Source {

    @NotNull
    # other
    @JsonProperty("ambian1");
    public String ambian1;
    
    @JsonAlias("ambian1");
    public String raw_ambian1;

    @NotNull
    # other
    public String xebian1;

    # i have more than 100+ other field use this:
    
}

How can I decode the json value into two fields?

The issue is not in the setters.

If you have all public fields in your model you should not be worried about multiple getters/setters at all as Jackson will handle them automatically when serializing/deserializing.

However, if you want to assign the same/similar value from a single JSON property "data" to two fields "fixData" and "rawData" it would be ok to implement just one setter for these two fields and mark it as @JsonProperty .

Possibly, a getter should be implemented as well to get specific property "data" .

If null fields must be hidden, @JsonInclude should be used to include non-null values.

@JsonInclude(JsonInclude.Include.NON_NULL)
class Source {

    @NotNull
    public String rawData;
    @NotNull
    public String fixData;

    @JsonAlias("another")
    public String anotherField;
    @JsonAlias("yet")
    public Integer yetAnotherField;
    @JsonAlias("onemore")
    public Double oneMoreField;

    @JsonProperty("data")
    public void setRawData(String data) {
        this.rawData = data;  // setting into raw
        this.fixData = data.replaceAll("^(\\d+)", ""); // removing digits at the start
    }

    @JsonProperty("data")
    public String getFixData() {
        return this.fixData; // getting fixed valid value
    }
}

Then the following JSONs could be read successfully:

String[] jsons = {
        "{\"data\":\"1abc\"}",
        "{\"data\":\"2abc\", \"another\":\"an\", \"yet\":100500, \"onemore\":3.14}",
        "{\"data\":\"3abc\", \"anotherField\":\"2VALS\"}"
};

ObjectMapper mapper = new ObjectMapper();
for (String json: jsons) {
    Source set = mapper.readValue(json, Source.class);
    System.out.printf("Setter raw: '%s', input: '%s'%n", set.rawData, set.fixData);

    String serialized = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(set);
    System.out.println("set: " + serialized);
}

Output:

Setter raw: '1abc', input: 'abc'
set: {
  "data" : "abc"
}
Setter raw: '2abc', input: 'abc'
set: {
  "anotherField" : "an",
  "yetAnotherField" : 100500,
  "oneMoreField" : 3.14,
  "data" : "abc"
}
Setter raw: '3abc', input: 'abc'
set: {
  "anotherField" : "2VALS",
  "data" : "abc"
}

"rawData" or "fixData" will not be parsed in JSON.

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