Jackson自定义序列化器,用于抑制空值。

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

Jackson custom serializer with null values to be suppressed

问题

I have a custom serializer to treat String with blank values as null and also to trim trailing blank spaces. Follwoing is the code for the same. -

public class StringSerializer extends JsonSerializer<String> {

	@Override
	public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
		String finalValue = null;
		if (value != null) {
			finalValue = value.trim();
			if (finalValue.isEmpty()) {
				finalValue = null;
			}
		}
		gen.writeObject(finalValue);
	}
}

In the main bean definition, the attribute definition is as follows -

public class SampleBean {
    private Long id;

    @JsonSerialize(using = StringSerializer.class)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String attribute1;

    @JsonSerialize(using = StringSerializer.class)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String attribute2;

    // Getters and setters
}

In the cases where the custom serializer kicks in, the not null values aren't ignored.

For example:

SampleBean bean = new SampleBean();
bean.setId(1L);
bean.setAttribute1("abc");
bean.setAttribute2(" ");
new ObjectMapper().writeValueAsString(bean);

The output of writeValueAsString:
{"id": 1, "attribute1": "abc", "attribute2": null}

Expected output, since you have @JsonInclude(JsonInclude.Include.NON_NULL) in attribute 2, is as below:

{"id": 1, "attribute1": "abc"}

Is there any way to achieve this?

英文:

I have a custom serializer to treat String with blank values as null and also to trim trailing blank spaces. Follwoing is the code for the same. -

public class StringSerializer extends JsonSerializer&lt;String&gt; {

	@Override
	public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
		String finalValue = null;
		if (value != null) {
			finalValue = value.trim();
			if (finalValue.isEmpty()) {
				finalValue = null;
			}
		}
		gen.writeObject(finalValue);

	}

}

In the main bean definition, the attribute definition is as follows -

public class SampleBean {
    private Long id;

    @JsonSerialize(using = StringSerializer.class)
	@JsonInclude(Include.NON_NULL)
	private String attribute1;

    @JsonSerialize(using = StringSerializer.class)
	@JsonInclude(Include.NON_NULL)
	private String attribute2;

    //Getters and setters
}

In the cases where the custom serializer kicks in, the not null values aren't ignored.

For example:

SampleBean bean = new SampleBean();
bean.setId(1L);
bean.setAttribtute1(&quot;abc&quot;);
bean.setAttribtute2(&quot; &quot;);
new ObjectMapper().writeValueAsString(bean);

The output of writeValueAsString:
{"id": 1, "attribute1": "abc", "attribute2": null}

Expected output since i have @JsonInclude(Include.NON_NULL) in attribute 2, is as below.
{"id": 1, "attribute1": "abc"}

Is there anyway to achieve this?

答案1

得分: 1

I had exactly the same problem as you. It is true that JsonInclude.Include.NON_EMPTY and JsonInclude.Include.NON_NULL stops working with a custom Serializer.

我遇到了和你完全相同的问题。JsonInclude.Include.NON_EMPTY 和 JsonInclude.Include.NON_NULL 确实在使用自定义序列化器时停止工作。

I ended up creating a custom filter and used it together with the custom serializer.

最终,我创建了一个自定义过滤器,并与自定义序列化器一起使用它。

Note that the example in the link https://www.logicbig.com/tutorials/misc/jackson/json-include-customized.html is wrong. In the equals() method, you should return true if you DON'T want to include the field, and return false if you want to include the field in the serialized output. This is the opposite of the example.

请注意,链接 https://www.logicbig.com/tutorials/misc/jackson/json-include-customized.html 中的示例是错误的。在 equals() 方法中,如果你不想包含该字段,应返回 true,如果想要在序列化输出中包含该字段,则应返回 false。这与示例相反。

Some sample code:

一些示例代码:

/**
 * Custom Jackson Filter used for @JsonInclude. When the keywords string is empty don&#39;t include keywords in the
 * JSON serialization.
 */
public class KeywordsIncludeFilter {

    @Override
    public boolean equals(Object obj) {
        if(obj == null) return true;
        if(obj instanceof String &amp;&amp; &quot;&quot;.equals((String) obj)) return true;
        return false;
    }
}
英文:

I had exactly the same problem as you. It is true that JsonInclude.Include.NON_EMPTY and JsonInclude.Include.NON_NULL stops working with a custom Serializer.

I ended up creating a custom filter and used it together with the custom serializer.

Note that the example in the link https://www.logicbig.com/tutorials/misc/jackson/json-include-customized.html is wrong. In the equals() method, you should return true if you DON'T want to include the field, and return false if you want to include the field in the serialized output. This is the opposite of the example.

Some sample code:

/**
 * Custom Jackson Filter used for @JsonInclude. When the keywords string is empty don&#39;t include keywords in the
 * JSON serialization.
 */
public class KeywordsIncludeFilter {

    @Override
    public boolean equals(Object obj) {
        if(obj == null) return true;
        if(obj instanceof String &amp;&amp; &quot;&quot;.equals((String) obj)) return true;
        return false;
    }
}

答案2

得分: 1

尝试将以下内容添加到您的 StringSerializer 中:

@Override
public boolean isEmpty(SerializerProvider provider, String value) {
    if (value != null) {
        String finalValue = value.trim();
        if (finalValue.isEmpty()) {
            return true;
        }
    }

    return false;
}

然后在相关字段上添加 "non empty" 注解,例如:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String attribute2;

这将设置可抑制的值为 "non empty",您可以通过 isEmpty() 覆盖来定义它。

英文:

Try adding the following to your StringSerializer:

@Override
public boolean isEmpty(SerializerProvider provider, String value) {
    if (value != null) {
        String finalValue = value.trim();
        if (finalValue.isEmpty()) {
            return true;
        }
    }

    return false;
}

Then add the "non empty" annotation to the field in question, e.g.:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String attribute2;

This sets the suppressible value to be "non empty" which you can then define via the isEmpty() override.

答案3

得分: 0

Try NON_EMPTY which should take care of empty and null string.

@JsonSerialize(using =
StringSerializer.class)
@JsonInclude(Include.NON_EMPTY)

If this does not meet your requirement, look here to create a Custom filter and then use it in the valueFilter

https://www.logicbig.com/tutorials/misc/jackson/json-include-customized.html

英文:

Try NON_EMPTY which should take care of empty and null string.

@JsonSerialize(using = 
StringSerializer.class)
@JsonInclude(Include.NON_EMPTY)

If this does not meet your requirement, look here to create a Custom filter and then use it in the valueFilter

https://www.logicbig.com/tutorials/misc/jackson/json-include-customized.html

huangapple
  • 本文由 发表于 2020年7月23日 04:13:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/63042464.html
匿名

发表评论

匿名网友

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

确定