【问题标题】:Json string to java object mapping failed with jacksonJson 字符串到 java 对象的映射因杰克逊而失败
【发布时间】:2017-08-15 11:32:34
【问题描述】:

我正在尝试使用 Jackson 将我的 json 映射到 POJO 类,但我收到的是空值。 如果我删除 @JsonIgnoreProperties 注释,那么它会抛出无法识别的属性异常

json:

{
   "TileLevel":[

   ],
   "SystemLevel":[
      {
         "Title":"Test System Level Alert",
         "Description":"<div class=\"ExternalClassA5AAC8F74C874A2D9DB8337EB6685B2A\"><p>​Test System Level Alert​<br></p><p>check the url http&#58;//www.google.com<br></p><p><span style=\"font-size&#58;32px;\">formatting tested</span><br></p></div>",
         "AnnouncementType":"System Level",
         "ActiveF":null,
         "TileName":null
      }
   ],
   "Announcements":[
      {
         "Title":"Test Announcement",
         "Description":"<div class=\"ExternalClass16980D07D2FB4AB58A2E97C16B7626D3\"><p>​Testing.....&#160;<img src=\"/sites/salesbk-CN/SiteCollectionImages/Salesbook%20Announcements/AllItems/00007-confiz-test-doc7.png\" alt=\"00007-confiz-test-doc7.png\" style=\"margin&#58;5px;\" /><br></p></div>",
         "AnnouncementType":"Announcement",
         "ActiveF":null,
         "TileName":null
      }
   ]
}

我将此 json 作为字符串获取,然后尝试将此字符串转换为 java 对象。

这是我的 POJO 课程:

public class SPOAnnouncement {

    @JsonIgnoreProperties
    private Map<String, List<List<SPOAnnouncements_Properties>>> TileLevel;
    private Map<String, List<List<SPOAnnouncements_Properties>>> SystemLevel;
    private Map<String, List<List<SPOAnnouncements_Properties>>> Announcements;

    public Map<String, List<List<SPOAnnouncements_Properties>>> getTileLevel() {
        return TileLevel;
    }

    public void setTileLevel(Map<String, List<List<SPOAnnouncements_Properties>>> tileLevel) {
        TileLevel = tileLevel;
    }

    public Map<String, List<List<SPOAnnouncements_Properties>>> getSystemLevel() {
        return SystemLevel;
    }

    public void setSystemLevel(Map<String, List<List<SPOAnnouncements_Properties>>> systemLevel) {
        SystemLevel = systemLevel;
    }

    public Map<String, List<List<SPOAnnouncements_Properties>>> getAnnouncements() {
        return Announcements;
    }

    public void setAnnouncements(Map<String, List<List<SPOAnnouncements_Properties>>> announcements) {
        Announcements = announcements;
    }
}

public class SPOAnnouncements_Properties {


    private String Title;
    private String Description;
    private String AnnouncementType;
    private String ActiveF;
    private String TileName;

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getDescription() {
        return Description;
    }

    public void setDescription(String description) {
        Description = description;
    }

    public String getAnnouncementType() {
        return AnnouncementType;
    }

    public void setAnnouncementType(String announcementType) {
        AnnouncementType = announcementType;
    }

    public String getActiveF() {
        return ActiveF;
    }

    public void setActiveF(String activeF) {
        ActiveF = activeF;
    }

    public String getTileName() {
        return TileName;
    }

    public void setTileName(String tileName) {
        TileName = tileName;
    }

}

我的验证结果是否已经映射到json对象的测试方法:

@Test
public void convertJsonToObject() throws IOException {

    ObjectMapper mapper = new ObjectMapper();
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    SPOAnnouncement spoAnnouncement = mapper.readValue(response, SPOAnnouncement.class);
    System.out.print(spoAnnouncement);
} 

【问题讨论】:

  • 无关:请阅读有关 java 命名约定的信息。字段名称也采用驼峰命名法。你使用大写的习惯让其他人感到困惑。
  • 然后:阅读minimal reproducible example。显示一个最小示例。为什么要建立一个 3 层嵌套示例,而可能更简单的东西可以做到?
  • 神圣的鳄梨酱。请编辑您的问题并将所有类字段设为驼峰式。现在很难看出什么是类,什么是字段。
  • 看看你的 JSON:它是一个有 3 个属性的对象。每个属性的值都是一个数组。每个数组都包含对象,这些对象有 5 个字符串类型的属性。所以你的 POJO 根本没有正确的结构:它有三个属性(OK),应该映射到 JSON 数组,所以应该是数组或 Lists(不OK,它们是 Maps),以及里面对象的类型list 不应该是其他列表,而是 SPOAnnouncements_Properties。
  • @JB Nizet:非常感谢您的及时指导。您能否在我尝试过但未成功时提出代码。这是我尝试过的: private Map> TileLevel;

标签: java json jackson deserialization pojo


【解决方案1】:

您的 POJO 结构无效。查看http://www.jsonschema2pojo.org - 一个从 JSON 生成 Java POJO 的在线工具。

您的类应该大致如下所示,但您需要将 ActiveFTileName 字段替换为首选类型。

-----------------------------------com.example.Announcement.java-----------------------------------

package com.example;

import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "Title",
        "Description",
        "AnnouncementType",
        "ActiveF",
        "TileName"
})
public class Announcement {

    @JsonProperty("Title")
    private String title;
    @JsonProperty("Description")
    private String description;
    @JsonProperty("AnnouncementType")
    private String announcementType;
    @JsonProperty("ActiveF")
    private Object activeF;
    @JsonProperty("TileName")
    private Object tileName;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("Title")
    public String getTitle() {
        return title;
    }

    @JsonProperty("Title")
    public void setTitle(String title) {
        this.title = title;
    }

    @JsonProperty("Description")
    public String getDescription() {
        return description;
    }

    @JsonProperty("Description")
    public void setDescription(String description) {
        this.description = description;
    }

    @JsonProperty("AnnouncementType")
    public String getAnnouncementType() {
        return announcementType;
    }

    @JsonProperty("AnnouncementType")
    public void setAnnouncementType(String announcementType) {
        this.announcementType = announcementType;
    }

    @JsonProperty("ActiveF")
    public Object getActiveF() {
        return activeF;
    }

    @JsonProperty("ActiveF")
    public void setActiveF(Object activeF) {
        this.activeF = activeF;
    }

    @JsonProperty("TileName")
    public Object getTileName() {
        return tileName;
    }

    @JsonProperty("TileName")
    public void setTileName(Object tileName) {
        this.tileName = tileName;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}
-----------------------------------com.example.SPOAnnouncement.java-----------------------------------

package com.example;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "TileLevel",
        "SystemLevel",
        "Announcements"
})
public class SPOAnnouncement {

    @JsonProperty("TileLevel")
    private List<Object> tileLevel = null;
    @JsonProperty("SystemLevel")
    private List<SystemLevel> systemLevel = null;
    @JsonProperty("Announcements")
    private List<Announcement> announcements = null;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("TileLevel")
    public List<Object> getTileLevel() {
        return tileLevel;
    }

    @JsonProperty("TileLevel")
    public void setTileLevel(List<Object> tileLevel) {
        this.tileLevel = tileLevel;
    }

    @JsonProperty("SystemLevel")
    public List<SystemLevel> getSystemLevel() {
        return systemLevel;
    }

    @JsonProperty("SystemLevel")
    public void setSystemLevel(List<SystemLevel> systemLevel) {
        this.systemLevel = systemLevel;
    }

    @JsonProperty("Announcements")
    public List<Announcement> getAnnouncements() {
        return announcements;
    }

    @JsonProperty("Announcements")
    public void setAnnouncements(List<Announcement> announcements) {
        this.announcements = announcements;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}
-----------------------------------com.example.SystemLevel.java-----------------------------------

package com.example;

import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "Title",
        "Description",
        "AnnouncementType",
        "ActiveF",
        "TileName"
})
public class SystemLevel {

    @JsonProperty("Title")
    private String title;
    @JsonProperty("Description")
    private String description;
    @JsonProperty("AnnouncementType")
    private String announcementType;
    @JsonProperty("ActiveF")
    private Object activeF;
    @JsonProperty("TileName")
    private Object tileName;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("Title")
    public String getTitle() {
        return title;
    }

    @JsonProperty("Title")
    public void setTitle(String title) {
        this.title = title;
    }

    @JsonProperty("Description")
    public String getDescription() {
        return description;
    }

    @JsonProperty("Description")
    public void setDescription(String description) {
        this.description = description;
    }

    @JsonProperty("AnnouncementType")
    public String getAnnouncementType() {
        return announcementType;
    }

    @JsonProperty("AnnouncementType")
    public void setAnnouncementType(String announcementType) {
        this.announcementType = announcementType;
    }

    @JsonProperty("ActiveF")
    public Object getActiveF() {
        return activeF;
    }

    @JsonProperty("ActiveF")
    public void setActiveF(Object activeF) {
        this.activeF = activeF;
    }

    @JsonProperty("TileName")
    public Object getTileName() {
        return tileName;
    }

    @JsonProperty("TileName")
    public void setTileName(Object tileName) {
        this.tileName = tileName;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

如果您正在创建 Web 服务,请记住对它们进行序列化;)。

【讨论】:

    【解决方案2】:

    您可以使用@JsonProperty("FieldName") 表示法来映射所有未映射的字段。但 FieldName 必须与 JSON 字符串中的确切字段名称匹配。

    【讨论】:

      猜你喜欢
      • 2014-03-05
      • 1970-01-01
      • 2016-10-28
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      相关资源
      最近更新 更多