我需要将某个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中的属性称为“学生”。
所以...
- 在类或JSON中更正属性的名称。
- 根据StaxMan的注释注释属性变量。
- 注释设置器(如果有)
#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楼
它可以通过两种方式实现:
标记POJO以忽略未知属性
@JsonIgnoreProperties(ignoreUnknown = true)
配置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)