Jackson Parser can't read backslash quotation

2019-07-14 09:39发布

问题:

I've got JSON like this from the server:

{
  "id":"1",
  "value":13,
  "text":"{\"Pid\":\"2\",\"value\":42}"
}

I am using jackson library to deserialize this JSON string into java object with this code: (example below)

ObjectMapper mapper = new ObjectMapper();
MapObj obj = mapper.readValue(JSONfromServerInString, MapObj.class);

where Map Object looks like that:

public class MapObj {
        @JsonProperty("id")
        private Integer id;
        @JsonProperty("value")
        private Integer value;
        @JsonProperty("text")
        private String text;

        public Integer getId() {return id;}
        public void setId(Integer id) {this.id = id;}
        public Integer getValue() {return value;}
        public void setValue(Integer value) {this.value = value;}
        public String getText() {return text;}
        public void setText(String text) {this.text = text;}
    }

But when I try to deserialize this String with Backslashes before quotation marks. Jackson deserializer seems to end when he finds the first end of the string. He ignore that backslash. So the example will output this:

org.codehaus.jackson.JsonParseException: Unexpected character ('P' (code 80)): was expecting comma to separate OBJECT entries at [Source: java.io.StringReader@2f7c7260; line: 1, column: 33]

(The ('P' (code 80)) stands for the P character in the original JSON string \"Pid\")

回答1:

Are you sure it does not work? This test works fine:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();

        String json = "{\n" +
                "  \"id\":\"1\",\n" +
                "  \"value\":13,\n" +
                "  \"text\":\"{\\\"Pid\\\":\\\"2\\\",\\\"value\\\":42}\"\n" +
                "}";

        MapObj mapObj = objectMapper.readValue(json, MapObj.class);
        System.out.println("text = " + mapObj.getText());
    }

    private static class MapObj {
        @JsonProperty("id")
        private Integer id;
        @JsonProperty("value")
        private Integer value;
        @JsonProperty("text")
        private String text;

        public Integer getId() {return id;}
        public void setId(Integer id) {this.id = id;}
        public Integer getValue() {return value;}
        public void setValue(Integer value) {this.value = value;}
        public String getText() {return text;}
        public void setText(String text) {this.text = text;}
    }
}

It prints:

text = {"Pid":"2","value":42}

Using Jackson 2.6.4



回答2:

Looks like the server is converting the "text" map into a string before returning it in the response. Would it be possible to make the changes at the server side to send the Map as a whole, so that serialization of Map is correctly done ?

As far as I've tried, Jackson would not be able to deserialize the string into a Map by default.



回答3:

So I have found the solution.

JSONfromServerInString.replace("\\", "\\\\\\");

It seems to be working now. I have found that you need to insert three times backslash to make it work.

So the working string should be like this:

{
    "id" : "1",
    "value":13,
    "text":"{\\\"Pid\\\":\\\"2\\\",\\\"value\\\":42}"
}

I have found solution here:

How do you replace double quotes with a blank space in Java?