我有这个JSON:{“成功”:false}
我想将此反序列化为此POJO:
class Message {
private Map<String, String> dataset = new HashMap<String, String>();
@JsonProperty("success")
public boolean isSuccess() {
return Boolean.valueOf(dataset.get("success"));
}
@JsonProperty("success")
public void setSuccess(boolean success) {
dataset.put("success", String.valueOf(success));
}
}
是否可以将此JSON反序列化为没有字段成功的类? 到目前为止,我总是得到“UnrecognizedPropertyException:Unrecognized field”成功“”
感谢您的帮助!
答案 0 :(得分:6)
您可以实现一个方法并使用@JsonAnySetter
注释它,如下所示:
@JsonAnySetter
public void handleUnknownProperties(String key, Object value) {
// this will be invoked when property isn't known
}
另一种可能性就是这样失败:
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
这可以让你在没有找到属性的情况下反序列化你的JSON。
public static class Message {
private final Map<String, String> dataset = new HashMap<String, String>();
@Override
public String toString() {
return "Message [dataset=" + dataset + "]";
}
}
@Test
public void testJackson() throws JsonParseException, JsonMappingException, IOException {
String json = "{\"success\":false}";
ObjectMapper om = new ObjectMapper().configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
System.out.println(om.readValue(json, Message.class));
}
答案 1 :(得分:0)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。
如果您无法与Jackson合作,以下是您如何使用MOXy支持此用例。
<强>消息强>
Message
课程不需要注释。默认情况下,使用属性访问。您可以使用@XmlAccessorType(XmlAccessType.FIELD)
指定字段访问权限,请参阅:http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html。
package forum11315389;
import java.util.*;
class Message {
private Map<String, String> dataset = new HashMap<String, String>();
public boolean isSuccess() {
return Boolean.valueOf(dataset.get("success"));
}
public void setSuccess(boolean success) {
dataset.put("success", String.valueOf(success));
}
}
<强> jaxb.properties 强>
要将MOXy指定为JAXB提供程序,您需要在与域模型相同的包中包含名为jaxb.properties
的文件,并带有以下条目:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
<强>演示强>
package forum11315389;
import java.io.StringReader;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String,Object> properties = new HashMap<String,Object>(1);
properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Message.class}, properties);
StreamSource json = new StreamSource(new StringReader("{\"success\":false}"));
Unmarshaller unmarshaller = jc.createUnmarshaller();
Message message = unmarshaller.unmarshal(json, Message.class).getValue();
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(message, System.out);
}
}
<强>输入/输出强>
{"success":false}
答案 2 :(得分:0)
我不明白这个问题。杰克逊将(de)从原始问题中定义的消息POJO的当前版本序列化,没有错误,没有任何特殊配置(除了@JsonProperty注释)。当前的消息POJO没有名为success的字段,但它确定了一个名为success的属性,这就是为什么Jackson很乐意将示例JSON映射到它而没有任何成功其他配置。您要删除@JsonProperty注释吗?
如果是这种情况,那么你可以这样做,并且Jackson仍然会(或)使用相同的示例JSON从消息POJO序列化,而不需要任何其他配置,因为isSuccess和setSuccess方法签名已经充分定义了Message有一个名为success的属性,它匹配JSON中的元素名称。
以下示例说明了这些要点。
示例1,消息POJO完全按照原始问题中的定义:
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonFoo
{
public static void main(String[] args) throws Exception
{
// input: {"success":false}
String inputJson = "{\"success\":false}";
ObjectMapper mapper = new ObjectMapper();
Message message = mapper.readValue(inputJson, Message.class);
System.out.println(mapper.writeValueAsString(message));
// output: {"success":false}
}
}
class Message
{
private Map<String, String> dataset = new HashMap<String, String>();
@JsonProperty("success")
public boolean isSuccess()
{
return Boolean.valueOf(dataset.get("success"));
}
@JsonProperty("success")
public void setSuccess(boolean success)
{
dataset.put("success", String.valueOf(success));
}
}
示例2,修改了消息POJO以删除@JsonProperty注释。
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonFoo
{
public static void main(String[] args) throws Exception
{
// input: {"success":false}
String inputJson = "{\"success\":false}";
ObjectMapper mapper = new ObjectMapper();
Message message = mapper.readValue(inputJson, Message.class);
System.out.println(mapper.writeValueAsString(message));
// output: {"success":false}
}
}
class Message
{
private Map<String, String> dataset = new HashMap<String, String>();
public boolean isSuccess()
{
return Boolean.valueOf(dataset.get("success"));
}
public void setSuccess(boolean success)
{
dataset.put("success", String.valueOf(success));
}
}
使用MessageWrapper的示例:
public class JacksonFoo
{
public static void main(String[] args) throws Exception
{
// input: {"success":false}
String inputJson = "{\"success\":true}";
ObjectMapper mapper = new ObjectMapper();
MessageWrapper wrappedMessage = mapper.readValue(inputJson, MessageWrapper.class);
System.out.println(mapper.writeValueAsString(wrappedMessage));
// output: {"success":true}
}
}
class MessageWrapper
{
@JsonUnwrapped
@JsonProperty // exposes non-public field for Jackson use
Message message;
}