Java Spring Boot 保存一个 JSON 字段至两个 Java 字段,无需使用 setter 方法。

huangapple go评论72阅读模式
英文:

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 `&quot;data&quot;` to two fields `&quot;fixData&quot;` and `&quot;rawData&quot;` 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 `&quot;data&quot;`.

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(&quot;another&quot;)
    public String anotherField;
    @JsonAlias(&quot;yet&quot;)
    public Integer yetAnotherField;
    @JsonAlias(&quot;onemore&quot;)
    public Double oneMoreField;

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

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

Then the following JSONs could be read successfully:

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

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

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

Output:

Setter raw: &#39;1abc&#39;, input: &#39;abc&#39;
set: {
  &quot;data&quot; : &quot;abc&quot;
}
Setter raw: &#39;2abc&#39;, input: &#39;abc&#39;
set: {
  &quot;anotherField&quot; : &quot;an&quot;,
  &quot;yetAnotherField&quot; : 100500,
  &quot;oneMoreField&quot; : 3.14,
  &quot;data&quot; : &quot;abc&quot;
}
Setter raw: &#39;3abc&#39;, input: &#39;abc&#39;
set: {
  &quot;anotherField&quot; : &quot;2VALS&quot;,
  &quot;data&quot; : &quot;abc&quot;
}

&quot;rawData&quot; or &quot;fixData&quot; will not be parsed in JSON.

huangapple
  • 本文由 发表于 2020年10月3日 02:12:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/64176404.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定