带有JSON的杰克逊:无法识别的字段,未标记为可忽略

这篇博客讨论了在使用Jackson处理JSON时遇到的'无法识别的字段'问题。用户分享了多种解决方案,包括修改JSON属性名以匹配Java类的字段名,使用@JsonIgnoreProperties(ignoreUnknown = true)注解,以及确保Java类的getter和setter方法与JSON属性名匹配。还提到了使用jsonschema2pojo工具自动生成匹配的Java模型类。
摘要由CSDN通过智能技术生成

我需要将某个JSON字符串转换为Java对象。 我正在使用Jackson进行JSON处理。 我无法控制输入的JSON(我从Web服务读取)。 这是我输入的JSON:

{"wrapper":[{"id":"13","name":"Fred"}]}

这是一个简化的用例:

private void tryReading() {
    String jsonStr = "{\"wrapper\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
    ObjectMapper mapper = new ObjectMapper();  
    Wrapper wrapper = null;
    try {
        wrapper = mapper.readValue(jsonStr , Wrapper.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("wrapper = " + wrapper);
}

我的实体类是:

public Class Student { 
    private String name;
    private String id;
    //getters & setters for name & id here
}

我的包装程序类基本上是一个容器对象,用于获取我的学生列表:

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

我不断收到此错误,“包装器”返回null 。 我不确定缺少什么。 有人可以帮忙吗?

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
    Unrecognized field "wrapper" (Class Wrapper), not marked as ignorable
 at [Source: java.io.StringReader@1198891; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.java:53)

#1楼

正如没有人提到的那样,以为我会...

问题是您在JSON中的属性称为“包装”,而在Wrapper.class中的属性称为“学生”。

所以...

  1. 在类或JSON中更正属性的名称。
  2. 根据StaxMan的注释注释属性变量。
  3. 注释设置器(如果有)

#2楼

我已经尝试过以下方法,并且可以与Jackson一起用于此类JSON格式读取。 使用已经建议的解决方案:使用@JsonProperty("wrapper")注释getter

您的包装课

public Class Wrapper{ 
  private List<Student> students;
  //getters & setters here 
} 

我对包装课的建议

public Class Wrapper{ 

  private StudentHelper students; 

  //getters & setters here 
  // Annotate getter
  @JsonProperty("wrapper")
  StudentHelper getStudents() {
    return students;
  }  
} 


public class StudentHelper {

  @JsonProperty("Student")
  public List<Student> students; 

  //CTOR, getters and setters
  //NOTE: If students is private annotate getter with the annotation @JsonProperty("Student")
}

但是,这将为您提供以下格式的输出:

{"wrapper":{"student":[{"id":13,"name":Fred}]}}

有关更多信息,请参阅https://github.com/FasterXML/jackson-annotations

希望这可以帮助


#3楼

您可以使用

ObjectMapper objectMapper = getObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

它将忽略所有未声明的属性。


#4楼

当读取json流时,此解决方案是通用的,并且仅需要获取某些字段,而在域类中未正确映射的字段可以忽略:

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)

一个详细的解决方案是使用诸如jsonschema2pojo之类的工具从json响应的模式中自动生成所需的域类,例如Student。 您可以通过任何在线json到架构转换器执行后者。


#5楼

这对我来说非常完美

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(
    DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

@JsonIgnoreProperties(ignoreUnknown = true)注释没有。


#6楼

这比全部效果更好,请参考此属性。

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    projectVO = objectMapper.readValue(yourjsonstring, Test.class);

#7楼

如果您使用的是Jackson 2.0

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

#8楼

POJO应该定义为

回应等级

public class Response {
    private List<Wrapper> wrappers;
    // getter and setter
}

包装类

public class Wrapper {
    private String id;
    private String name;
    // getters and setters
}

和映射器读取值

Response response = mapper.readValue(jsonStr , Response.class);

#9楼

对我有用的是将财产公开。 它为我解决了问题。


#10楼

要么改变

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

public Class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}

- - 要么 - -

将您的JSON字符串更改为

{"students":[{"id":"13","name":"Fred"}]}

#11楼

就我而言,唯一的一行

@JsonIgnoreProperties(ignoreUnknown = true)

也没用

只需添加

@JsonInclude(Include.NON_EMPTY)

杰克逊2.4.0


#12楼

这对我来说很完美

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

#13楼

我通过简单地更改POJO类的setter和getter方法的签名来解决此问题。 我要做的就是更改getObject方法以匹配映射器正在寻找的内容。 在我的情况下,我最初有一个getImageUrl ,但是JSON数据具有image_url ,这使映射器无法使用。 我将setter和getter都更改为getImage_url和setImage_url

希望这可以帮助。


#14楼

使用Jackson 2.6.0,这对我有用:

private static final ObjectMapper objectMapper = 
    new ObjectMapper()
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

并设置:

@JsonIgnoreProperties(ignoreUnknown = true)

#15楼

它通过以下代码为我工作:

ObjectMapper mapper =new ObjectMapper();    
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

#16楼

您只需将List的字段从“ students”更改为“ wrapper”即可,只需json文件,然后映射器将对其进行查找。


#17楼

根据文档,您可以忽略所选字段或所有未知字段:

 // to prevent specified fields from being serialized or deserialized
 // (i.e. not include in JSON output; or being set even if they were included)
 @JsonIgnoreProperties({ "internalId", "secretKey" })

 // To ignore any unknown properties in JSON input without exception:
 @JsonIgnoreProperties(ignoreUnknown=true)

#18楼

您的输入

{"wrapper":[{"id":"13","name":"Fred"}]}

表示它是一个对象,其字段名为“包装器”,是学生的集合。 所以我的建议是

Wrapper = mapper.readValue(jsonStr , Wrapper.class);

Wrapper被定义为

class Wrapper {
    List<Student> wrapper;
}

#19楼

就我而言,这很简单:REST服务JSON对象已更新(添加了属性),但REST客户端JSON对象未更新。 一旦我更新了JSON客户端对象,“无法识别的字段...”异常就消失了。


#20楼

新的Firebase Android进行了一些巨大的改变; 在文件副本下方:

[ https://firebase.google.com/support/guides/firebase-android]

更新您的Java模型对象

与2.x SDK一样,Firebase数据库将自动将传递给DatabaseReference.setValue() Java对象转换为JSON,并可以使用DataSnapshot.getValue()将JSON读取为Java对象。

在新的SDK中,当使用DataSnapshot.getValue()将JSON读入Java对象时,默认情况下现在会忽略JSON中的未知属性,因此您不再需要@JsonIgnoreExtraProperties(ignoreUnknown=true)

为了在将Java对象写入JSON时排除字段/获取器,注释现在称为@Exclude而不是@JsonIgnore

BEFORE

@JsonIgnoreExtraProperties(ignoreUnknown=true)
public class ChatMessage {
   public String name;
   public String message;
   @JsonIgnore
   public String ignoreThisField;
}

dataSnapshot.getValue(ChatMessage.class)

AFTER

public class ChatMessage {
   public String name;
   public String message;
   @Exclude
   public String ignoreThisField;
}

dataSnapshot.getValue(ChatMessage.class)

如果您的JSON中有一个Java类中没有的额外属性,您将在日志文件中看到以下警告:

W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage

您可以通过在类上放置@IgnoreExtraProperties批注来摆脱此警告。 如果您希望Firebase数据库的行为与2.x SDK中的行为相同,并且在属性未知的情况下引发异常,则可以在类上放置@ThrowOnExtraProperties批注。


#21楼

如下注释现场学生,因为json属性和java属性的名称不匹配

public Class Wrapper {
    @JsonProperty("wrapper")
    private List<Student> students;
    //getters & setters here
}

#22楼

它可以通过两种方式实现:

  1. 标记POJO以忽略未知属性

     @JsonIgnoreProperties(ignoreUnknown = true) 
  2. 配置ObjectMapper来对POJO / json进行序列化/反序列化,如下所示:

     ObjectMapper mapper =new ObjectMapper(); // for Jackson version 1.X mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); // for Jackson version 2.X mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 

#23楼

杰克逊在抱怨,因为它在您的类包装器中找不到称为“包装器”的字段。 这样做是因为您的JSON对象具有一个称为“包装器”的属性。

我认为解决方法是将Wrapper类的字段重命名为“ wrapper”而不是“ students”。


#24楼

第一个答案几乎是正确的,但是需要的是更改getter方法,而不是字段-字段是私有的(并且不会自动检测到); 此外,如果两者均可见,则吸气剂优先于字段(也有使私有字段可见的方法,但是如果要使用吸气剂则没有什么意义)

因此,getter应该命名为getWrapper() ,或带有以下注释:

@JsonProperty("wrapper")

如果您更喜欢使用getter方法名称。


#25楼

这可能是一个很晚的响应,但是只需将POJO更改为此,就可以解决问题中提供的json字符串(因为输入的字符串不在您所说的控件中):

public class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}

#26楼

谷歌把我带到这里,我很惊讶地看到答案……所有的人都建议绕过这个错误( 在开发中总是会咬人4倍 ),而不是解决这个错误,直到这位绅士对SO 有了信心!

objectMapper.readValue(responseBody, TargetClass.class)

用于JSON字符串转换为类对象,什么遗漏的是, TargetClass应该有公共get之三/ set TER值。 OP的问题片段中也缺少同样的内容! :)

通过龙目岛您的班级如下所示!

@Data
@Builder
public class TargetClass {
    private String a;
}

#27楼

将您的班级字段设为公开而非私有

public Class Student { 
    public String name;
    public String id;
    //getters & setters for name & id here
}

#28楼

另一种可能性是application.properties spring.jackson.deserialization.fail-on-unknown-properties=false中的此属性,该spring.jackson.deserialization.fail-on-unknown-properties=false不需要在应用程序中进行任何其他代码更改。 并且当您认为合同稳定时,可以删除此属性或将其标记为true。


#29楼

这可能不是OP遇到的同一个问题,但是如果有人以我犯的相同错误来到这里,那么这将帮助他们解决他们的问题。 当我使用来自其他依赖项的ObjectMapper作为JsonProperty批注时,遇到了与OP相同的错误。

这有效:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;

不起作用:

import org.codehaus.jackson.map.ObjectMapper; //org.codehaus.jackson:jackson-mapper-asl:1.8.8
import com.fasterxml.jackson.annotation.JsonProperty; //com.fasterxml.jackson.core:jackson-databind:2.2.3

#30楼

您可以使用Jackson的类级注释:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties
class { ... }

它将忽略您尚未在POJO中定义的每个属性。 当您仅在JSON中查找几个属性并且不想编写整个映射时,此功能非常有用。 有关更多信息,请访问Jackson的网站 。 如果要忽略任何未声明的属性,则应输入:

@JsonIgnoreProperties(ignoreUnknown = true)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值