Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带额外字段的Jackson序列化映射_Java_Json_Jackson - Fatal编程技术网

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等)。如果你们中有人想回答这个问题,我会接受的。