object转json - object to json java




杰克逊与JSON:无法识别的字段,未标记为可忽略 (20)

我需要将某个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: [email protected]; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.java:53)

POJO应该被定义为

响应类

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

包装类

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

和mapper读取值

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

新的Firebase Android引入了一些巨大的变化; 在文档副本下方:

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

更新你的Java模型对象

与2.x SDK一样,Firebase数据库将自动将通过的Java对象转换为DatabaseReference.setValue()为JSON,并使用DataSnapshot.getValue()将JSON读入Java对象。

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

要在将JSON写入Java对象时排除字段/ getters,现在将该标注称为@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注释。


你应该将List的字段从“students”改为“wrapper”,只是将json文件和映射器查找它。


你的json字符串不与映射类内联。 更改输入字符串

String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";

或者改变你的映射类

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

使用杰克逊2.6.0,这为我工作:

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

并设置:

@JsonIgnoreProperties(ignoreUnknown = true)

在我的情况下很简单:REST服务JSON对象已更新(已添加属性),但REST客户端JSON对象不是。 只要我更新了JSON客户端对象,'无法识别的字段...'异常就消失了。


如果您使用的是杰克逊2.0

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

它为我工作与以下代码:

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

将Wrapper类更改为

public Class Wrapper {

          @JsonProperty("wrapper")  // add this line
          private List<Student> students;
}

它所做的是将students字段识别为json对象的wrapper键。

另外我个人更喜欢使用Lombok Annotations for Getters和Setters作为

@Getter
@Setter
public Class Wrapper {

          @JsonProperty("wrapper")  // add this line
          private List<Student> students;
}

因为我还没@JsonProperty Lombok和@JsonProperty一起测试上面的代码,所以我建议你将下面的代码添加到Wrapper类中,以覆盖Lombok的默认getter和setter。

public List<Student> getWrapper(){
     return students;
}

public void setWrapper(List<Student> students){
     this.students = students;
}

还要检查一下使用Jackson进行反序列化列表。


就我而言,唯一的路线

@JsonIgnoreProperties(ignoreUnknown = true)

也没有工作。

只需添加

@JsonInclude(Include.NON_EMPTY)

杰克逊2.4.0


您可以使用Jackson的课程级注释:

@JsonIgnoreProperties

它会忽略你在POJO中没有定义的每个属性。 当您只是在JSON中查找几个属性并且不想编写整个映射时非常有用。 杰克逊的网站更多信息。 如果你想忽略任何非声明属性,你应该写:

@JsonIgnoreProperties(ignoreUnknown = true)

我已经尝试了下面的方法,它适用于与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

希望这可以帮助


无论是更改

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"}]}

杰克逊抱怨,因为它无法在你的类包装器中找到一个叫做“包装器”的字段。 这是因为你的JSON对象有一个名为“wrapper”的属性。

我认为解决的办法是将Wrapper类的字段重命名为“包装器”而不是“学生”。


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

问题是你的JSON中的属性被称为“包装器”,你的Wrapper.class中的属性被称为“学生”。

所以要么...

  1. 在类或JSON中更正属性的名称。
  2. 按照StaxMan的评论注释你的属性变量。
  3. 注释setter(如果有的话)

由于json属性和java属性的名称不匹配,因此按照以下注释字段学生

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

谷歌把我带到这里,我很惊讶地看到答案......所有人都建议绕过这个错误( 在发展后总会反过来4倍 ),而不是解决它,直到这位先生因信仰而恢复为止!

objectMapper.readValue(responseBody, TargetClass.class)

用于将json字符串转换为类对象,缺少的是TargetClass应该有公共get ter / set TargetClass 。 在OP的问题片段中也缺少这一点! :)

通过lombok你的课如下应该工作!

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

这个解决方案在读取json流时是通用的,只需要获取一些字段,而在Domain Classes中未正确映射的字段可以被忽略:

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

详细的解决方案是使用诸如jsonschema2pojo之类的工具从json响应的模式中自动生成所需的Domain Classes,例如Student。 你可以通过任何在线json to schema转换器来完成后者。


这完全适合我

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

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


这对我来说非常合适

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);




jackson