首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用JSON反序列化JSON--为什么JsonMappingException“没有合适的构造器”?

用JSON反序列化JSON--为什么JsonMappingException“没有合适的构造器”?
EN

Stack Overflow用户
提问于 2011-12-03 19:51:56
回答 5查看 95.7K关注 0票数 24

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

下面我将介绍我使用的类。当我接收一个JSON-string (一个在别处序列化并通过webservice检索的ProtocolContainer )并想要反序列化它时,问题就来了:

JSON-string:

{"DataPacketJSONString":null,"SubPacket":{"__type":"LoginRequestReply:#MyPackage.DataPackets",“用户名”:6604,"SenderUsername":null,false“原因”:“错误的传递或用户名”,“成功”:false,“用户名”:“User1”}}

我尝试像这样反序列化:

代码语言:javascript
复制
ProtocolContainer ret = ProtocolContainer.Create(jsonString);

在ProtocolContainer中执行的代码如下所示。例外情况是:

JSON org.codehaus.jackson.map.JsonMappingException:找不到适用于类型简单类型的构造函数,类MyPackage.ProtocolContainer:无法从

对象实例化(需要添加/启用类型信息?)来源:java.io.StringReader@4059dcb0,第1行,第2列

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

代码语言:javascript
复制
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 -所有数据包的超类

代码语言:javascript
复制
public class DataPacket 
{

}

LoginRequestReply.java -a DataPacket

代码语言:javascript
复制
package MyPackage.DataPackets;

import MyPackage.DataPacket;

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

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-12-03 20:02:55

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

票数 31
EN

Stack Overflow用户

发布于 2011-12-08 00:00:57

在这种情况下,您可以向构造函数添加@JsonCreator注释。有两种方法可以做到:

  • 如果您只添加了该注释,则整个匹配的JSON首先绑定到唯一参数的类型(``DataPacket‘)。如果您还在参数之前添加了@JsonProperty注释,那么与该名称匹配的
  • 属性将被传递给构造函数(注释是必需的,因为

字节码不包含方法名称或构造函数参数) --我怀疑您想要@JsonProperty("SubPacket")

如果构造函数的必要信息来自JSON,则此方法有效。如果不是,则需要添加替代的无参数构造函数。

顺便说一下,在这种情况下,错误消息听起来确实是错误的。只有当JSON数据与JSON字符串的预期值匹配时,才应该给出它。

票数 15
EN

Stack Overflow用户

发布于 2015-02-26 14:46:55

经验法则:为您用作映射类的每个类添加一个默认构造函数。你错过了这一点,问题就出现了!

只需添加一个默认构造函数,它就应该可以工作了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8367445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档