我在使用Jackson对JSON字符串进行反序列化时遇到了问题(但将对象序列化为JSON没有问题)。
下面我将介绍我使用的类。当我接收一个JSON-string (一个在别处序列化并通过webservice检索的ProtocolContainer )并想要反序列化它时,问题就来了:
JSON-string:
{"DataPacketJSONString":null,"SubPacket":{"__type":"LoginRequestReply:#MyPackage.DataPackets",“用户名”:6604,"SenderUsername":null,false“原因”:“错误的传递或用户名”,“成功”:false,“用户名”:“User1”}}
我尝试像这样反序列化:
ProtocolContainer ret = ProtocolContainer.Create(jsonString);
在ProtocolContainer中执行的代码如下所示。例外情况是:
JSON org.codehaus.jackson.map.JsonMappingException:找不到适用于类型简单类型的构造函数,类MyPackage.ProtocolContainer:无法从
对象实例化(需要添加/启用类型信息?)来源:java.io.StringReader@4059dcb0,第1行,第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 -所有数据包的超类
public class DataPacket
{
}
LoginRequestReply.java -a DataPacket
package MyPackage.DataPackets;
import MyPackage.DataPacket;
public class LoginRequestReply extends DataPacket
{
public boolean LoginOK;
public int UserId;
}
发布于 2011-12-03 20:02:55
错误消息说明了一切,您的ProtocolContainer没有默认构造函数,因此杰克逊无法创建它的实例。(因为当前创建ProtocolContainer的唯一方法是传入DataPacket。)
发布于 2011-12-08 00:00:57
在这种情况下,您可以向构造函数添加@JsonCreator
注释。有两种方法可以做到:
@JsonProperty
注释,那么与该名称匹配的字节码不包含方法名称或构造函数参数) --我怀疑您想要@JsonProperty("SubPacket")
如果构造函数的必要信息来自JSON,则此方法有效。如果不是,则需要添加替代的无参数构造函数。
顺便说一下,在这种情况下,错误消息听起来确实是错误的。只有当JSON数据与JSON字符串的预期值匹配时,才应该给出它。
发布于 2015-02-26 14:46:55
经验法则:为您用作映射类的每个类添加一个默认构造函数。你错过了这一点,问题就出现了!
只需添加一个默认构造函数,它就应该可以工作了。
https://stackoverflow.com/questions/8367445
复制相似问题