Phate P
Phate P

Reputation: 1691

Json Jackson do not deserialize inner object (null on properties)

I know there was alot of posts like this but still I am not able to find an proper anwser.

I need to parse given Json from web

{
  "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"
}

I have 2 classes

first one holds all information got from website

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

    private String origin;

    private String url;
    //getters and seters
}

it includes Headers class which look like this:

@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
}

properties like origin and url are parsed properly but there is an issue with Header class

Here is my derserializer

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;
    }
}

Also here when i do test-parse of WebJsonObject its done well (origin and url are filled with valuse) Problem is when i Parse Headers, all properties are filled with null.

Upvotes: 0

Views: 2808

Answers (2)

Phate P
Phate P

Reputation: 1691

I have solved problem. Which was unrelated to code itself.

Wrong thing was that I imported

import org.codehaus.jackson.annotate.JsonProperty;

instead of

import com.fasterxml.jackson.annotation.JsonProperty

...

Code is ok despite fact that (as @Fabio said) there is no need to write any Deserializer.

One can simply do:

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

Upvotes: 0

Fabio
Fabio

Reputation: 2834

When you use @JsonRootName("headers") you're assuming that you'll parse the whole json into a Headers object.

Forgiving my bad memory, it'd work if you wrote something like this:

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

But since you mention that you're parsing origin and url correctly you're implying that you did something like

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

If that's correct the solution is about dropping both @JsonRootName and @JsonDeserialize.

In fact it's very unusual to use either of those annotations, or to write a deserializer from scratch. They're only needed for edge cases where there's not a direct correspondance between json and POJO's, and even in a lot of those cases you can get away with other features like UNWRAP_ROOT.

Upvotes: 1

Related Questions