java - 使用 Jackson 反序列化 JSON - 为什么 JsonMappingException "No suitable constructor"?

标签 java json jackson

我在使用 Jackson 反序列化 JSON 字符串时遇到问题(但我将对象序列化为 JSON 没有问题)。

下面我介绍我使用的类。当我收到一个 JSON 字符串(一个在别处序列化并通过 web 服务检索的 ProtocolContainer)并想要反序列化它时,问题就出现了:

JSON 字符串:

{"DataPacketJSONString":null,"DataPacketType":"MyPackage.DataPackets.LoginRequestReply","MessageId":6604,"SenderUsername":null,"SubPacket":{"__type":"LoginRequestReply:#MyPackage.DataPackets","Reason":"Wrong pass or username","Success":false,"Username":"User1"}}

我尝试像这样反序列化:

ProtocolContainer ret = ProtocolContainer.Create(jsonString);

下面可以看到在 ProtocolContainer 中执行的代码。异常(exception):

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class MyPackage.ProtocolContainer]: can not instantiate from JSON object (need to add/enable type information?) at [Source: java.io.StringReader@4059dcb0; line: 1, column: 2]

ProtocolContainer.java - 一个封装我的“SubPackets”的容器类:

import java.io.IOException;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import MyPackage.DataPackets.*;

public class ProtocolContainer 
{
    public String SenderUsername;
    public String DataPacketType;
    public long MessageId;
    public String DataPacketJSONString;
    public DataPacket SubPacket;

    public ProtocolContainer(DataPacket dp)
    {
        DataPacketType = dp.getClass().toString().substring(6);
        SubPacket = dp;
    }

    public String toJSON()
    {
        try {
            if (SubPacket != null)
                this.DataPacketJSONString = ProtocolContainer.mapper.writeValueAsString(SubPacket);

            return ProtocolContainer.mapper.writeValueAsString(this);
        } catch (JsonGenerationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public static ObjectMapper mapper = new ObjectMapper();

    public static ProtocolContainer Create(String jsonString)
    {
        ProtocolContainer pc = null;
        try {
            pc = mapper.readValue(jsonString, ProtocolContainer.class); // error here!
        } catch (JsonParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();  // Exception when deserializing
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        try 
        {
            if (pc != null && pc.DataPacketType == "LoginRequest")
                pc.SubPacket = mapper.readValue(jsonString, LoginRequest.class);
    }
        catch (JsonParseException e) 
        {
            e.printStackTrace();
        }
        catch (JsonMappingException e) 
        {
            e.printStackTrace();
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
        return pc;
    }
}

DataPacket.java - 我所有数据包的父类(super class)

public class DataPacket 
{

}

LoginRequestReply.java - 一个数据包

package MyPackage.DataPackets;

import MyPackage.DataPacket;

public class LoginRequestReply extends DataPacket
{
    public boolean LoginOK;
    public int UserId;
}

最佳答案

错误消息说明了一切,您的 ProtocolContainer 没有默认构造函数,因此 Jackson 无法创建它的实例。 (因为当前创建 ProtocolContainer 的唯一方法是传入 DataPacket。)

关于java - 使用 Jackson 反序列化 JSON - 为什么 JsonMappingException "No suitable constructor"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8367445/

相关文章:

java - 如果被 Spring 包装到代理中,如何知道原始类名?

java - @NotNull 在类里面被忽略

javascript - JSONP使用JQuery从HTTPS协议(protocol)中获取JSON

java - 如何使用 spring boot 将 json 映射到对象

java - Jackson Databind 中是否有任何替代品来替代已弃用的属性 SerializationFeature.WRITE_NULL_MAP_VALUES ?

java - withSerializationInclusion 函数在最新的 Jackson-databind-2.9.8 中不可用

java - Space Invaders - 奇怪的运动与外星人运动算法

json - 在 Express.js 中的某个时间间隔后刷新变量

javascript - 如何预解析 JSON 字符串?

java - 我应该怎么做才能停止线程执行?