Jackson throws JsonMappingException on deserialize; demands single-String constructor?

前端 未结 4 1084
夕颜
夕颜 2020-12-03 17:56

Another question, but it relates to this one: Deserializing JSON with Jackson - Why JsonMappingException "No suitable constructor"?

This time I am getting

相关标签:
4条回答
  • 2020-12-03 18:26

    It seems that you are sending to the server a string instead of an object.

    Instead of sending the string to be parsed on the server side, you can do it easier just by sending JSON.parse(stringObject), and Jackson will deserialize it normally as expected.

    0 讨论(0)
  • 2020-12-03 18:32

    I had the same problem. For me, the solution was to switch from passing a String to the convertValue method, to an InputStream to the readValue method:

    // Instead of this:
    String jsonString = "..."
    ProtocolContainer pc = mapper.convertValue(jsonString, ProtocolContainer.class);
    
    // ... do this:
    String jsonString = "..."
    InputStream is = new StringInputStream(jsonString);
    ProtocolContainer pc = mapper.readValue(is, ProtocolContainer.class);
    
    0 讨论(0)
  • 2020-12-03 18:39

    Oh, so once again I found out the answer AFTER I posted this question (even though I tried a lot of things before posting).

    What I did to solve this was to use the @JsonCreator annotation. I simply annotated my static Create method, like this:

    @JsonCreator
    public static ProtocolContainer Create(String jsonString)
    {
    
        ProtocolContainer pc = null;
        try {
            pc = mapper.readValue(jsonString, ProtocolContainer.class);
        } catch (JsonParseException|JsonMappingException|IOException e) {
            // handle
        }
    
        return pc;
    }
    

    And then problem solved.

    0 讨论(0)
  • 2020-12-03 18:43

    The exception suggests that the JSON value you have is a String, something like:

    { "protocol" : "http" }
    

    or perhaps "double-quoted JSON":

    "\"{\"property\":\"value\"}\"
    

    when trying to bind like:

    ProtocolContainer p = mapper.readValue(json, ProtocolContainer.class);
    

    in which case Jackson has no properties to map, just a String. And in that case it does indeed require either a custom deserializer, or a creator method. Creator methods are either single-string-argument constructors, or single-string argument static methods: the difference being that only constructors can be auto-detected (this is just a practical short-cut as there can only be one such constructor, but multiple static methods).

    Your solution does indeed work, just thought I'd give some background as to what is happening.

    Reading through it second time it seems more likely you have double-quoted stuff (JSON in JSON): another thing to consider is to get plain JSON, if possible. But maybe that's hard to do.

    0 讨论(0)
提交回复
热议问题