英文:
Java sprintboot saving one JSON field to two Java fields without setters
问题
public class Source {
@NotNull
@JsonProperty("ambian1")
public String ambian1;
@JsonAlias("ambian1")
public String raw_ambian1;
@NotNull
public String xebian1;
// Other fields...
}
英文:
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?
答案1
得分: 0
问题不在于设置器。
如果您的模型中有所有公共字段,您根本不需要担心多个getter/setter,因为Jackson在序列化/反序列化时会自动处理它们。
然而,如果您想要将单个JSON属性"data"的相同/类似值分配给两个字段"fixData"和"rawData",只需实现一个带有@JsonProperty标记的setter,将这两个字段标记为一个setter。
可能还应该实现一个getter来获取特定属性"data"。
如果必须隐藏空字段,应使用@JsonInclude来包含非空值。
```java
@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;
this.fixData = data.replaceAll("^(\\d+)", "");
}
@JsonProperty("data")
public String getFixData() {
return this.fixData;
}
}
然后可以成功读取以下JSON:
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);
}
输出:
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"或"fixData"将不会在JSON中解析。
<details>
<summary>英文:</summary>
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.
```java
@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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论