【问题标题】:Json Jackson do not deserialize inner object (null on properties)Json Jackson 不反序列化内部对象(属性为空)
【发布时间】:2016-08-03 10:02:40
【问题描述】:

我知道有很多这样的帖子,但我仍然找不到合适的答案。

我需要从网络解析给定的 Json

{
  "args": {

  },
  "headers": {
    "Accept": "application/json",
    "Accept-Encoding": "gzip",
    "Content-Length": "0",
    "Host": "httpbin.org",
    "User-Agent": "Dalvik/1.6.0 (Linux; U; Android 4.3; C5303 Build/12.1.A.1.205)"
  },
  "origin": "91.193.147.8",
  "url": "https://httpbin.org/get"
}

我有两节课

第一个包含从网站获取的所有信息

public class WebJSONObject {
    @JsonDeserialize(using  = HeadersDeserializer.class)
    private Headers headers;

    private String origin;

    private String url;
    //getters and seters
}

它包括如下所示的 Headers 类:

@JsonRootName("headers")
public class Headers {

    @JsonProperty("Accept")
    private String accept;

    @JsonProperty("Accept-Encoding")
    private String acceptEncoding;

    @JsonProperty("Content-Length")
    private String contentLenght;

    @JsonProperty("Host")
    private String host;

    @JsonProperty("User-Agent")
    private String userAgent;
    //Getters and setters
}

origin 和 url 等属性被正确解析 但 Header 类存在问题

这是我的反序列化器

public class HeadersDeserializer  extends JsonDeserializer<Headers> {

    @Override
    public Headers deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);

        JsonNode node = mapper.readTree(jsonParser);

        //for testing issue (parsing properly)
        //Json String: {"origin":"91.193.147.8","url":"https://httpbin.org/get"}
        TreeNode tree = jsonParser.getCodec().readTree(jsonParser);
        String node_as_text2 = tree.toString();
        WebJSONObject wbo = mapper.readValue(node_as_text2,WebJSONObject.class);

        //Json String {"Accept":"application/json","Accept-Encoding":"gzip","Content-Length":"0","Host":"httpbin.org","User-Agent":"Dalvik/1.6.0 (Linux; U; Android 4.3; C5303 Build/12.1.A.1.205)"}
        String node_as_text = mapper.writeValueAsString(node);
        Headers headers = mapper.readValue(node_as_text,Headers.class);

        return headers;
    }
}

当我对 WebJsonObject 进行测试解析时,它也做得很好(原点和 url 都充满了值) 问题是当我解析标题时,所有属性都填充了空值。

【问题讨论】:

  • 用户改造并根据给定的响应创建 POJO
  • 你还需要@JsonDeserialize 吗?我认为你想要实现的根本不需要那个。如果你只是评论那一行会发生什么?
  • 当我删除这一行时它仍然没有解析。 Null 或 Header 类属性

标签: java android json parsing jackson


【解决方案1】:

当您使用@JsonRootName("headers") 时,您假设您会将整个 json 解析为 Headers 对象。

原谅我的记性不好,如果你写这样的话就可以了:

Headers headers = objectMapper.readValue(string,Headers.class);

但既然你提到你正在正确解析来源和网址,你就暗示你做了类似的事情

WebJSONObject object = objectMapper.readValue(string, WebJSONObject.class);

如果正确,解决方案是同时删除 @JsonRootName@JsonDeserialize

事实上,使用这些注释中的任何一个或从头开始编写反序列化器都是非常不寻常的。只有在 json 和 POJO 之间没有直接对应关系的边缘情况下才需要它们,即使在很多情况下,您也可以使用 UNWRAP_ROOT 等其他功能。

【讨论】:

  • 我还看到了一些非常特殊的情况,杰克逊真的希望你拥有默认的构造函数。试试public Headers() { System.out.println("Hello headers") },如果它被调用,请告诉我们。
  • 我找到了与代码无关的解决方案。无论如何,谢谢你的回答
【解决方案2】:

我已经解决了问题。这与代码本身无关。

错误的是我导入了

import org.codehaus.jackson.annotate.JsonProperty;

而不是

import com.fasterxml.jackson.annotation.JsonProperty

...

尽管事实如此(正如@Fabio 所说),但代码还可以 无需编写任何反序列化器。

可以简单地做到:

public class WebJSONObject {
    private Headers headers;

    private String origin;

    private String url;
    //setters and getters

public class Headers {

    @JsonProperty("Accept")
    private String accept;

    @JsonProperty("Accept-Encoding")
    private String acceptEncoding;

    @JsonProperty("Content-Length")
    private String contentLenght;

    @JsonProperty("Host")
    private String host;

    @JsonProperty("User-Agent")
    private String userAgent;
    //setters and getters

【讨论】:

  • 哦,是的,旧的 codehaus 还在。小心你使用的其他库,如果你间接包含了 codehaus,那可能会很头疼。检查 gradlew 依赖项
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
  • 2011-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
相关资源
最近更新 更多