Java 带额外字段的Jackson序列化映射
如果一个类扩展了一个映射并包含一些额外的字段。例如,最后修改的日期,杰克逊似乎忽略了任何不属于地图属性的东西 我有一个类,看起来像下面这样:Java 带额外字段的Jackson序列化映射,java,json,jackson,Java,Json,Jackson,如果一个类扩展了一个映射并包含一些额外的字段。例如,最后修改的日期,杰克逊似乎忽略了任何不属于地图属性的东西 我有一个类,看起来像下面这样: import java.io.IOException; import java.time.OffsetDateTime; import java.util.HashMap; import java.util.Objects; import com.fasterxml.jackson.databind.ObjectMapper; public class
import java.io.IOException;
import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.Objects;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Foo extends HashMap<String, String> {
private OffsetDateTime lastModifiedTime;
public Foo() {
super();
lastModifiedTime = OffsetDateTime.now();
}
public void setLastModifiedTime(OffsetDateTime newTime) {
this.lastModifiedTime = newTime;
}
public OffsetDateTime getLastModifiedTime() {
return this.lastModifiedTime;
}
public static void main(String[] args) throws IOException {
Foo f = new Foo();
f.put("hello", "world");
ObjectMapper om = new ObjectMapper();
om.findAndRegisterModules();
String result = om.writeValueAsString(f);
if(f.equals(om.readValue(result, Foo.class))) {
System.out.println("Wooo");
} else {
System.out.println("Booo: " + result);
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Foo)) {
return false;
}
if (!super.equals(obj)) {
return false;
}
Foo foo = (Foo) obj;
return Objects.equals(getLastModifiedTime(), foo.getLastModifiedTime());
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), getLastModifiedTime());
}
}
import java.io.IOException;
导入java.time.OffsetDateTime;
导入java.util.HashMap;
导入java.util.Objects;
导入com.fasterxml.jackson.databind.ObjectMapper;
公共类Foo扩展HashMap{
private OffsetDateTime lastModifiedTime;
公共食物({
超级();
lastModifiedTime=OffsetDateTime.now();
}
public void setLastModifiedTime(OffsetDateTime newTime){
this.lastModifiedTime=newTime;
}
public OffsetDateTime getLastModifiedTime(){
返回此.lastModifiedTime;
}
公共静态void main(字符串[]args)引发IOException{
Foo f=新的Foo();
f、 放置(“你好”,“世界”);
ObjectMapper om=新的ObjectMapper();
om.findAndRegisterModules();
字符串结果=om.writeValueAsString(f);
if(f.equals(om.readValue(result,Foo.class))){
系统输出打印项次(“Wooo”);
}否则{
System.out.println(“Booo:+result”);
}
}
@凌驾
公共布尔等于(对象obj){
if(this==obj){
返回true;
}
如果(!(对象实例Foo)){
返回false;
}
如果(!super.equals(obj)){
返回false;
}
Foo-Foo=(Foo)obj;
返回Objects.equals(getLastModifiedTime(),foo.getLastModifiedTime());
}
@凌驾
公共int hashCode(){
返回Objects.hash(super.hashCode(),getLastModifiedTime());
}
}
当它运行时,它输出booo:{“hello”:“world”}
,其中不包括上次修改的日期
我尝试向属性和getter添加@JsonInclude
注释,但这不会导致它包含额外字段
让Jackson包含此额外字段的正确方法是什么?默认情况下,您的地图将落入。您可以注册序列化程序修改器以添加自定义属性,但最好将映射嵌套为
Foo
的属性并将其展开:
@JsonUnwrapped
private HashMap<String, String> fooMap;
@JsonUnwrapped
私有HashMap-fooMap;
扩展HashMap通常被认为是不好的做法。相反,您应该创建一个具有贴图的类,以及附加字段
这将解决您的问题,但也有其他好处:
- 您将能够封装规则(比如防止添加一些键/值等)
- 如果需要,您将能够更改映射实现(LinkedHashMap、同步映射、并发映射)
- 您可以像这样使用
@JsonAnyGetter
和@JsonAnySetter
而不是@jsonunrapped
:
public class Foo {
private OffsetDateTime lastModifiedTime;
private HashMap<String, String> additionalProperties = new HashMap<String, String>();
public Foo() {
super();
lastModifiedTime = OffsetDateTime.now();
}
public void setLastModifiedTime(OffsetDateTime newTime) {
this.lastModifiedTime = newTime;
}
public OffsetDateTime getLastModifiedTime() {
return this.lastModifiedTime;
}
@JsonAnyGetter
public Map<String, String> any() {
return this.additionalProperties;
}
@JsonAnySetter
public void set(String name, String value) {
this.additionalProperties.put(name, value);
}
}
公共类Foo{
private OffsetDateTime lastModifiedTime;
私有HashMap additionalProperties=新HashMap();
公共食物({
超级();
lastModifiedTime=OffsetDateTime.now();
}
public void setLastModifiedTime(OffsetDateTime newTime){
this.lastModifiedTime=newTime;
}
public OffsetDateTime getLastModifiedTime(){
返回此.lastModifiedTime;
}
@JsonAnyGetter
公共地图任意(){
返回此。附加属性;
}
@JSONANYSETER
公共无效集(字符串名称、字符串值){
this.additionalProperties.put(名称、值);
}
}
不要扩展HashMap。创建一个具有映射和额外字段的类,而不是扩展HashMap。@JBNizet-Ah。希望有一个注释,以避免需要实现许多额外的方法(Size、empty等)。如果你们中有人想回答这个问题,我会接受的。