【问题标题】:Jackson insisting in throwing confusing exception when deserializing a POJOJackson 在反序列化 POJO 时坚持抛出令人困惑的异常
【发布时间】:2021-12-22 21:18:01
【问题描述】:

即使一切正常,我也找不到为什么我从 Jacksoin 收到异常。

我有以下 Json

      {
        "id": "8a599509-994a-4cff-ad6d-c3f770e8d159",
        "action": "0",
        "code": "13",
        "device_id": "0BC813D9-37FE-4FAB-9FA0-05F85CBAE777",
        "branch_id": "0BC813D9-37FE-4FAB-9FA0-05F85CBAE999",
        "description": "Sergio sei uno stra-figo",
        "date": "2021-11-09T10:22:45",
        "severity": 1
      }

我需要将 Json 反序列化为的类:

@JsonIgnorePropenter code hereerties(ignoreUnknown = true)
public class LogMdto {

private String id;

public String getId() {
    return id;
}

@JsonProperty(value = "object_id")
private String objectId;

@Size(max = Log.objectNameSize, message = "size may not by bigger than " + Log.objectNameSize)
@JsonProperty(value = "object_name")
private String objectName;

@JsonProperty("device_id")
private String deviceId;

@NotNull(message = "may not be null")
private String description;

@NotNull(message = "may not be null")
@Size(max = Log.codeSize, 
        message = "size may not by bigger than " + Log.codeSize)
private String code;

private Integer action;

private String id;

private int severity;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss")
private Timestamp date;


public Timestamp getDate() {
    return date;
}

public void setDate(String date) {
    DateTimeFormatter dft = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
    this.date = Timestamp.valueOf(LocalDateTime.from(dft.parse(date)));
}

public String getObjectId() {
    return objectId;
}

public void setObjectId(String objectId) {
    this.objectId = objectId;
}

public String getObjectName() {
    return objectName;
}

public void setObjectName(String objectName) {
    this.objectName = objectName;
}

public String getDeviceId() {
    return deviceId;
}

public void setDeviceId(String deviceId) {
    this.deviceId = deviceId;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getCode() {
    return code;
}

public void setCode(String code) {
    this.code = code;
}

public Integer getAction() {
    return action;
}

public void setAction(Integer action) {
    this.action = action;
}

public void setId(String id) {
    this.id = id;
}

public int getSeverity() {
    return severity;
}

public void setSeverity(int severity) {
    this.severity = severity;
}

}

当我打电话给ObjectMapper().readValue(json, LogMdto.class) 时,我得到以下异常;

无法识别的字段“device_id”(com.plintech.LorikeetNestSpring.models.dto.mobile.LogMdto 类),未标记为可忽略

我不明白为什么会出现这个异常。 deviceId 字段是用@JsonProperty("device_id") 映射的,我有setter 和getter 但还是报错。

更新

我做了以下改动:

//Removed the annotation
private String deviceId;

.... ....

改变了setter和getter如下:

@JsonProperty(value = "device_id")
public String getDeviceId() {
    return deviceId;
}

@JsonProperty(value = "device_id")
public void setDeviceId(String deviceId) {
    this.deviceId = deviceId;
}

但结果总是相同的异常,我不明白我的代码有什么问题,我想不出还有什么可以尝试确保没有其他隐藏问题。

【问题讨论】:

    标签: java spring-boot jackson


    【解决方案1】:

    好的,谢谢大家的帮助,但答案有点微妙。代码没有问题,问题是mapper不对,是误导入了

    org.codehaus.jackson

    版本而不是

    更快的xml

    ....更改了导入指令...一切都很好了。

    【讨论】:

      【解决方案2】:

      苏珊的回答是正确的。

      您必须将 @JsonProperty("device_id") 添加到您的 getter 和 setter。

      为避免此类错误,您始终可以使用AnySetter 来保留无法正确映射的数据。

      例如:

      public class LogMdto {
      ....
      
          private Map<String, Object> additionalProperties = new HashMap<>(); // This Map holds all the properties that were not found.
          // You could check what is wrong with the names that this POJO receives from your JSON
      
          @JsonAnyGetter
          public Map<String, Object> getAdditionalProperties() {
              return this.additionalProperties;
          }
      
          @JsonAnySetter
          public void setAdditionalProperty(String name, Object value) {
              this.additionalProperties.put(name, value);
          }
      
      ....
      

      【讨论】:

      • 我试过了……没办法……同样的问题……看看更新。它仅在我声明公共 device_id (与 json 中的名称相同)时才有效。看起来@JsonProperty 被忽略了,因为我还必须更改名称,否则它不起作用。
      【解决方案3】:

      如果我没记错的话,既然是私有字段,那么就不用Field@JsonProperty注解本身,而是用Getter/Setter。

      Getter/Setter 将用于序列化/反序列化,在这两种情况下它们都不匹配 device_id 名称;

      修复它:将 @JsonProperty 添加到您的 Getter/Setter。

      另一方面,如果它是一个公共变量,那么下面没有 Getter/Setter 的情况就可以正常工作:

      @JsonProperty("device_id")
      public String deviceId;
      

      === 测试代码 ===

      @JsonIgnoreProperties(ignoreUnknown = true)
      public class LogMdto {
      
          private String id;
      
          @JsonProperty(value = "object_id")
          private String objectId;
      
          @JsonProperty(value = "object_name")
          private String objectName;
      
          private String deviceId;
      
          @NotNull(message = "may not be null")
          private String description;
      
          @NotNull(message = "may not be null")
          private String code;
      
          private Integer action;
      
          private int severity;
      
          @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
          private Timestamp date;
      
      
          public String getId() {
              return id;
          }
      
          public Timestamp getDate() {
              return date;
          }
      
          public void setDate(String date) {
              DateTimeFormatter dft = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
              this.date = Timestamp.valueOf(LocalDateTime.from(dft.parse(date)));
          }
      
          public String getObjectId() {
              return objectId;
          }
      
          public void setObjectId(String objectId) {
              this.objectId = objectId;
          }
      
          public String getObjectName() {
              return objectName;
          }
      
          public void setObjectName(String objectName) {
              this.objectName = objectName;
          }
          @JsonProperty("device_id")
          public String getDeviceId() {
              return deviceId;
          }
          @JsonProperty("device_id")
          public void setDeviceId(String deviceId) {
              this.deviceId = deviceId;
          }
      
          public String getDescription() {
              return description;
          }
      
          public void setDescription(String description) {
              this.description = description;
          }
      
          public String getCode() {
              return code;
          }
      
          public void setCode(String code) {
              this.code = code;
          }
      
          public Integer getAction() {
              return action;
          }
      
          public void setAction(Integer action) {
              this.action = action;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      
          public int getSeverity() {
              return severity;
          }
      
          public void setSeverity(int severity) {
              this.severity = severity;
          }
      }
      

      public static void main(String[] args) throws Exception{
          String jsonTest = "{\n" +
                  "        \"id\": \"8a599509-994a-4cff-ad6d-c3f770e8d159\",\n" +
                  "        \"action\": \"0\",\n" +
                  "        \"code\": \"13\",\n" +
                  "        \"device_id\": \"0BC813D9-37FE-4FAB-9FA0-05F85CBAE777\",\n" +
                  "        \"branch_id\": \"0BC813D9-37FE-4FAB-9FA0-05F85CBAE999\",\n" +
                  "        \"description\": \"Sergio sei uno stra-figo\",\n" +
                  "        \"date\": \"2021-11-09T10:22:45\",\n" +
                  "        \"severity\": 1\n" +
                  "      }";
      
          LogMdto logMdto = new ObjectMapper().readValue(jsonTest, LogMdto.class);
      
          System.out.println(logMdto.getDeviceId());
      }
      

      日志:

      0BC813D9-37FE-4FAB-9FA0-05F85CBAE777
      

      【讨论】:

      • 将@JsonProperty("device_id") @JsonGetter("device_id") 和@JsonSetter("device_id") ...分别添加到getter和setter ...同样的错误
      • 请查看更新的代码@Sergiob 这是您的确切代码。如果某些东西不起作用,那么可能与您的杰克逊依赖关系有关。如果可能,请确保您拥有最新版本。 (请参阅属性是私有的)。我不喜欢公共领域:)
      • 如果我宣布公共财产有效,但这不是我需要的。它必须保持私有,并且 getter setter 不起作用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多