Java 使用Jackson反序列化JSON而不使用正确的字段

Java 使用Jackson反序列化JSON而不使用正确的字段,java,json,jackson,Java,Json,Jackson,我得到了这个JSON:{“success”:false} 我想将其反序列化到此POJO中: class Message { private Map<String, String> dataset = new HashMap<String, String>(); @JsonProperty("success") public boolean isSuccess() { return Boolean.valueOf(dataset.g

我得到了这个JSON:{“success”: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));
    }
}
类消息{
私有映射数据集=新HashMap();
@JsonProperty(“成功”)
公共布尔值isSuccess(){
返回Boolean.valueOf(dataset.get(“success”);
}
@JsonProperty(“成功”)
public void setSuccess(布尔值成功){
dataset.put(“success”,String.valueOf(success));
}
}
是否可以在没有字段成功的情况下将此JSON反序列化为类? 到目前为止,我一直得到“UnrecognizedPropertyException:Unrecognized”字段“success”


谢谢你的帮助

您可以实现一个方法,并使用
@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);
另一种可能是关闭此故障,如下所示:

@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而不会失败

试验
公共静态类消息{
私有最终映射数据集=新HashMap();
@凌驾
公共字符串toString(){
返回“Message[dataset=“+dataset+”]”;
}
}
@试验
public void testJackson()抛出JsonParseException、JsonMappingException、IOException{
字符串json=“{\'success\”:false}”;
ObjectMapper om=new ObjectMapper().configure(UNKNOWN属性上的反序列化config.Feature.FAIL,false);
System.out.println(om.readValue(json,Message.class));
}

注意:我是专家组的负责人和成员

如果您无法让它与Jackson一起使用,下面是您如何使用MOXy支持此用例

消息

消息
类不需要任何注释。默认情况下,使用属性访问。您可以使用
@xmlacessortype(xmlacesstype.field)
指定字段访问,请参阅:

演示

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);
    }

}

我不明白这个问题。Jackson将从/序列化到您在原始问题中定义的消息POJO的当前版本,没有错误,没有任何特殊配置(除了@JsonProperty注释)。当前消息POJO没有名为success的字段,但它定义了名为success的属性,这就是为什么Jackson很乐意将示例JSON映射到它,而不需要任何其他配置。是否要删除@JsonProperty注释

如果是这种情况,那么您可以这样做,Jackson仍将使用相同的示例JSON从/到消息POJO(反)序列化,而无需任何其他必要的配置,因为isSuccess和setSuccess方法签名已经充分定义了该消息具有名为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));
  }
}

我就是这么想的。。。但我不能让它工作。谢谢你的回答。很明显,我的代码有点错误。嗯,事实上我忘了一些重要的东西。。。我没有尝试直接将JSON字符串反序列化到对象消息中,而是在另一个类MessageWrapper中,该类作为对对象消息的引用。。。我使用MessageWrapper字段消息上的注释@JsonUnwrapped来请求对象消息的反序列化。我是否必须将我的getter/setter放在根类MessageWrapper中?@yann“我是否必须将我的getter/setter放在根类MessageWrapper中?”--不需要。只需在MessageWrapper中用@jsonUnrapped和@JsonProperty对消息字段进行注释(或者为Jackson提供其他知道如何使用该字段的方法,例如,将其公开)(实际上不要这样做))。我将更新上面的答案,以包含这样一个示例。
{"success":false}
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));
  }
}
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));
  }
}
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;
}