【发布时间】:2012-01-12 03:19:37
【问题描述】:
我在使用 Jackson 反序列化 JSON 字符串时遇到问题(但我将对象序列化为 JSON 没有问题)。
下面我介绍我使用的类。当我收到一个 JSON 字符串(一个在别处序列化并通过 web 服务检索的 ProtocolContainer)并想要反序列化它时,问题就出现了:
JSON 字符串:
{"DataPacketJSONString":null,"DataPacketType":"MyPackage.DataPackets.LoginRequestReply","MessageId":6604,"SenderUsername":null,"SubPacket":{"__type":"LoginRequestReply:#MyPackage.DataPackets ","Reason":"错误的密码或用户名","Success":false,"Username":"User1"}}
我尝试像这样反序列化:
ProtocolContainer ret = ProtocolContainer.Create(jsonString);
下面可以看到在 ProtocolContainer 中执行的代码。例外:
org.codehaus.jackson.map.JsonMappingException: 没有合适的构造函数 找到类型 [简单类型,类 MyPackage.ProtocolContainer]:不能 从 JSON 对象实例化(需要添加/启用类型信息?) 在 [来源: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 - 一个数据包
package MyPackage.DataPackets;
import MyPackage.DataPacket;
public class LoginRequestReply extends DataPacket
{
public boolean LoginOK;
public int UserId;
}
【问题讨论】:
-
跟进:经过一番折腾,我没有收到以下错误:JsonMappingException: Can not instantiate value of type [simple type, class MyPackage.ProtocolContainer] from JSON String;没有单字符串构造函数/工厂方法。如果我添加一个接受字符串的构造函数,那么没有错误但对象是“空的”......我认为没有必要在构造函数中添加实现支持。 我应该如何解决这个问题?