jsh*_*ree 602 java data-binding json jackson
我需要将某个JSON字符串转换为Java对象.我正在使用Jackson进行JSON处理.我无法控制输入JSON(我从Web服务中读取).这是我的输入JSON:
{"wrapper":[{"id":"13","name":"Fred"}]}
Run Code Online (Sandbox Code Playgroud)
这是一个简化的用例:
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);
}
Run Code Online (Sandbox Code Playgroud)
我的实体类是:
public Class Student {
private String name;
private String id;
//getters & setters for name & id here
}
Run Code Online (Sandbox Code Playgroud)
My Wrapper类基本上是一个容器对象,用于获取我的学生列表:
public Class Wrapper {
private List<Student> students;
//getters & setters here
}
Run Code Online (Sandbox Code Playgroud)
我一直收到这个错误,"包装"返回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)
Run Code Online (Sandbox Code Playgroud)
Ari*_*gan 928
您可以使用Jackson的类级别注释:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties
class { ... }
Run Code Online (Sandbox Code Playgroud)
它将忽略您在POJO中未定义的每个属性.当你只是在JSON中寻找几个属性并且不想编写整个映射时非常有用.更多信息,请访问杰克逊的网站.如果要忽略任何未声明的属性,则应编写:
@JsonIgnoreProperties(ignoreUnknown = true)
Run Code Online (Sandbox Code Playgroud)
Sur*_*ani 432
您可以使用
ObjectMapper objectMapper = getObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Run Code Online (Sandbox Code Playgroud)
它将忽略未声明的所有属性.
Sta*_*Man 123
第一个答案几乎是正确的,但是需要的是改变getter方法,NOT字段 - 字段是私有的(而不是自动检测的); 此外,如果两者都是可见的,则getters优先于字段.(有一些方法可以使私有字段可见,但是如果你想获得getter,则没有太多意义)
所以getter应该被命名getWrapper()
,或注释为:
@JsonProperty("wrapper")
Run Code Online (Sandbox Code Playgroud)
如果您更喜欢getter方法名称.
Sco*_*ott 80
使用Jackson 2.6.0,这对我有用:
private static final ObjectMapper objectMapper =
new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Run Code Online (Sandbox Code Playgroud)
并设置:
@JsonIgnoreProperties(ignoreUnknown = true)
Run Code Online (Sandbox Code Playgroud)
Ana*_*ika 50
它可以通过2种方式实现:
标记POJO以忽略未知属性
@JsonIgnoreProperties(ignoreUnknown = true)
Run Code Online (Sandbox Code Playgroud)配置序列化/反序列化POJO/json的ObjectMapper,如下所示:
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)
Run Code Online (Sandbox Code Playgroud)ddc*_*ddc 45
添加 setter 和 getter 解决了问题,我觉得实际问题是如何解决它,而不是如何抑制/忽略错误。我收到错误“无法识别的字段.. 未标记为可忽略.. ”
虽然我在类的顶部使用了下面的注释,但它无法解析 json 对象并给我输入
@JsonIgnoreProperties(ignoreUnknown = true)
然后我意识到我没有添加 setter 和 getter,在将 setter 和 getter 添加到“Wrapper”和“Student”之后,它就像一个魅力。
小智 41
这对我来说非常合适
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(
DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Run Code Online (Sandbox Code Playgroud)
@JsonIgnoreProperties(ignoreUnknown = true)
注释没有.
小智 35
这比All更好,请参考这个属性.
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);
Run Code Online (Sandbox Code Playgroud)
Aal*_*iry 27
如果您使用的是Jackson 2.0
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
Run Code Online (Sandbox Code Playgroud)
tom*_*ozb 18
根据该文档,您可以忽略所选字段或所有未知字段:
// 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)
Run Code Online (Sandbox Code Playgroud)
Jim*_*ans 14
杰克逊抱怨是因为它无法在你的班级Wrapper中找到一个被称为"包装器"的字段.这样做是因为你的JSON对象有一个叫做"wrapper"的属性.
我认为修复是将您的Wrapper类的字段重命名为"wrapper"而不是"students".
小智 14
我尝试了下面的方法,它适用于与杰克逊这样的JSON格式阅读.使用已经建议的解决方案:使用注释getter@JsonProperty("wrapper")
你的包装类
public Class Wrapper{
private List<Student> students;
//getters & setters here
}
Run Code Online (Sandbox Code Playgroud)
我对包装类的建议
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")
}
Run Code Online (Sandbox Code Playgroud)
但是,这将为您提供格式的输出:
{"wrapper":{"student":[{"id":13,"name":Fred}]}}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅https://github.com/FasterXML/jackson-annotations
希望这可以帮助
小智 14
它使用以下代码为我工作:
ObjectMapper mapper =new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Run Code Online (Sandbox Code Playgroud)
Ale*_*mov 12
Java 11 及更高版本的简单解决方案:
var mapper = new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(FAIL_ON_UNKNOWN_PROPERTIES)
.disable(WRITE_DATES_AS_TIMESTAMPS)
.enable(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);
Run Code Online (Sandbox Code Playgroud)
忽略的重要一点是禁用“FAIL_ON_UNKNOWN_PROPERTIES”
Geo*_*rou 10
此解决方案在读取json流时是通用的,并且只需要获取某些字段,而在域类中未正确映射的字段可以忽略:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
Run Code Online (Sandbox Code Playgroud)
一个详细的解决方案是使用诸如jsonschema2pojo之类的工具从json Response的Schema中自动生成所需的域类,例如Student.您可以通过任何在线json到架构转换器来执行后者.
小智 10
由于json属性和java属性的名称不匹配,因此将字段学生注释如下
public Class Wrapper {
@JsonProperty("wrapper")
private List<Student> students;
//getters & setters here
}
Run Code Online (Sandbox Code Playgroud)
没有人提到过,以为我会......
问题是你的JSON中的属性被称为"包装器",你在Wrapper.class中的属性被称为"学生".
所以要么......
不知何故,在 10 年的 45 个帖子之后,没有人为我的案例发布正确的答案。
@Data //Lombok
public class MyClass {
private int foo;
private int bar;
@JsonIgnore
public int getFoobar() {
return foo + bar;
}
}
Run Code Online (Sandbox Code Playgroud)
就我而言,我们有一个名为 的方法getFoobar()
,但没有foobar
属性(因为它是根据其他属性计算的)。 @JsonIgnoreProperties
在课堂上不起作用。
解决方案是将该方法注释为@JsonIgnore
我通过简单地更改 POJO 类的 setter 和 getter 方法的签名解决了这个问题。我所要做的就是更改getObject方法以匹配映射器正在寻找的内容。就我而言,我最初有一个getImageUrl,但 JSON 数据有image_url,这导致映射器关闭。我将 setter 和 getter 更改为getImage_url 和 setImage_url。
这可能与OP遇到的问题不同,但如果有人犯了与我相同的错误,那么这将帮助他们解决问题。当我使用来自不同依赖项的 ObjectMapper 作为 JsonProperty 注释时,我得到了与 OP 相同的错误。
这有效:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;
Run Code Online (Sandbox Code Playgroud)
不起作用:
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
Run Code Online (Sandbox Code Playgroud)
改变
public Class Wrapper {
private List<Student> students;
//getters & setters here
}
Run Code Online (Sandbox Code Playgroud)
至
public Class Wrapper {
private List<Student> wrapper;
//getters & setters here
}
Run Code Online (Sandbox Code Playgroud)
- - 要么 - -
将您的JSON字符串更改为
{"students":[{"id":"13","name":"Fred"}]}
Run Code Online (Sandbox Code Playgroud)
小智 5
就我而言,唯一的线路
@JsonIgnoreProperties(ignoreUnknown = true)
也没有用。
只需添加
@JsonInclude(Include.NON_EMPTY)
Run Code Online (Sandbox Code Playgroud)
杰克逊 2.4.0
这对我来说非常有效
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Run Code Online (Sandbox Code Playgroud)
小智 5
你的意见
{"wrapper":[{"id":"13","name":"Fred"}]}
Run Code Online (Sandbox Code Playgroud)
表示它是一个Object,带有一个名为"wrapper"的字段,它是一个学生集合.所以我的推荐是,
Wrapper = mapper.readValue(jsonStr , Wrapper.class);
Run Code Online (Sandbox Code Playgroud)
在哪里Wrapper
定义为
class Wrapper {
List<Student> wrapper;
}
Run Code Online (Sandbox Code Playgroud)
新的 Firebase Android 引入了一些巨大的变化;在文档副本下方:
[ https://firebase.google.com/support/guides/firebase-android] :
更新您的 Java 模型对象
与 2.x SDK 一样,Firebase 数据库会自动将您传递的 Java 对象转换DatabaseReference.setValue()
为 JSON,并且可以使用DataSnapshot.getValue()
.
在新的 SDK 中,当使用 将 JSON 读入 Java 对象时DataSnapshot.getValue()
,JSON 中的未知属性现在默认会被忽略,因此您不再需要@JsonIgnoreExtraProperties(ignoreUnknown=true)
.
为了在将 Java 对象写入 JSON 时排除字段/getter,现在调用注释@Exclude
而不是@JsonIgnore
.
BEFORE
@JsonIgnoreExtraProperties(ignoreUnknown=true)
public class ChatMessage {
public String name;
public String message;
@JsonIgnore
public String ignoreThisField;
}
dataSnapshot.getValue(ChatMessage.class)
Run Code Online (Sandbox Code Playgroud)
AFTER
public class ChatMessage {
public String name;
public String message;
@Exclude
public String ignoreThisField;
}
dataSnapshot.getValue(ChatMessage.class)
Run Code Online (Sandbox Code Playgroud)
如果您的 JSON 中有一个不在您的 Java 类中的额外属性,您将在日志文件中看到此警告:
W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage
Run Code Online (Sandbox Code Playgroud)
您可以通过@IgnoreExtraProperties
在类上添加注释来消除此警告。如果您希望 Firebase 数据库像在 2.x SDK 中那样运行并在存在未知属性时抛出异常,您可以@ThrowOnExtraProperties
在类上添加注释。
将您的班级字段设为公开而非私有。
public Class Student {
public String name;
public String id;
//getters & setters for name & id here
}
Run Code Online (Sandbox Code Playgroud)
另一种可能性是 application.properties 中的这个属性
spring.jackson.deserialization.fail-on-unknown-properties=false
,它不需要在您的应用程序中更改任何其他代码。当您认为合约稳定时,您可以删除此属性或将其标记为真。
如果由于某种原因您无法将 @JsonIgnoreProperties 注释添加到您的类中,并且您位于 Web 服务器/容器(例如 Jetty)中。您可以在自定义提供程序中创建和自定义 ObjectMapper
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
@Provider
public class CustomObjectMapperProvider implements ContextResolver<ObjectMapper> {
private ObjectMapper objectMapper;
@Override
public ObjectMapper getContext(final Class<?> cls) {
return getObjectMapper();
}
private synchronized ObjectMapper getObjectMapper() {
if(objectMapper == null) {
objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
return objectMapper;
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题已经有很多答案了。我正在添加现有答案。
如果您想应用于@JsonIgnoreProperties
应用程序中的所有类,那么最好的方法是覆盖 Spring Boot 默认的 jackson 对象。
在您的应用程序配置文件中定义一个 bean 来创建这样的 jackson 对象映射器。
@Bean
public ObjectMapper getObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
Run Code Online (Sandbox Code Playgroud)
现在,您不需要标记每个类,它会忽略所有未知属性。
谢谢。
归档时间: |
|
查看次数: |
691934 次 |
最近记录: |