我怎么能告诉jackson忽略一个我无法控制源代码的属性呢?

时间:2021-03-25 07:18:19

Long story short, one of my entities has a GeometryCollection that throws an exception when you call "getBoundary" (the why of this is another book, for now let's say this is the way it works).

长话短说,我的一个实体有一个GeometryCollection,当您调用“getBoundary”时,它会抛出一个异常(这是另一本书的原因,现在我们假设它是这样工作的)。

Is there a way I can tell Jackson not to include that specific getter? I know I can use @JacksonIgnore when I do own/control the code. But this is not case, jackson ends reaching this point through continuous serialization of the parent objects. I saw a filtering option in jackson documentation. Is that a plausible solution?

我能不能告诉Jackson不要包含那个特定的getter?我知道我可以在拥有/控制代码时使用@JacksonIgnore。但这并不是说,jackson通过对父对象的连续序列化来达到这一点。我在jackson文档中看到了一个过滤选项。这是一个合理的解决方案吗?

Thanks!

谢谢!

8 个解决方案

#1


130  

You can use Jackson Mixins. For example:

你可以用杰克逊调酒师。例如:

class YourClass {
  public int ignoreThis() { return 0; }    
}

With this Mixin

这种混合

abstract class MixIn {
  @JsonIgnore abstract int ignoreThis(); // we don't need it!  
}

With this:

用这个:

objectMapper.getSerializationConfig().addMixInAnnotations(YourClass.class, MixIn.class);

Edit:

编辑:

Thanks to the comments, with Jackson 2.5+, the API has changed and should be called with objectMapper.addMixIn(Class<?> target, Class<?> mixinSource)

由于有了Jackson 2.5+的评论,API已经改变,应该使用objectMapper.addMixIn(类 目标类< ?> mixinSource)

#2


54  

One other possibility is, if you want to ignore all unknown properties, you can configure the mapper as follows:

另一种可能是,如果您想忽略所有未知的属性,可以配置映射器如下:

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

#3


19  

Using Java Class

使用Java类

new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

Using Annotation

使用注释

@JsonIgnoreProperties(ignoreUnknown=true)

#4


8  

Mix-in annotations work pretty well here as already mentioned. Another possibility beyond per-property @JsonIgnore is to use @JsonIgnoreType if you have a type that should never be included (i.e. if all instances of GeometryCollection properties should be ignored). You can then either add it directly (if you control the type), or using mix-in, like:

正如前面提到的,Mix-in注释在这里工作得很好。除了每个属性@JsonIgnore之外的另一种可能是使用@JsonIgnoreType,如果您有一个类型不应该包含进来(例如,如果应该忽略所有的GeometryCollection属性实例)。然后您可以直接添加它(如果您控制类型),或者使用mix-in,比如:

@JsonIgnoreType abstract class MixIn { }
// and then register mix-in, either via SerializationConfig, or by using SimpleModule

This can be more convenient if you have lots of classes that all have a single 'IgnoredType getContext()' accessor or so (which is the case for many frameworks)

如果有很多类都只有一个“IgnoredType getContext()”访问器,这就更方便了(这是很多框架的情况)

#5


8  

public @interface JsonIgnoreProperties

Annotation that can be used to either suppress serialization of properties (during serialization), or ignore processing of JSON properties read (during deserialization).

可用于抑制属性的序列化(在序列化期间)或忽略读取的JSON属性的处理(在反序列化期间)的注释。

to prevent specified fields from being serialized or deserialized you can use:

为了防止指定字段被序列化或反序列化,您可以使用:

@JsonIgnoreProperties(ignoreUnknown=true)

#6


4  

I had a similar issue, but it was related to Hibernate's bi-directional relationships. I wanted to show one side of the relationship and programmatically ignore the other, depending on what view I was dealing with. If you can't do that, you end up with nasty *Exceptions. For instance, if I had these objects

我有一个类似的问题,但它与Hibernate的双向关系有关。我想显示关系的一面,并以编程方式忽略另一面,这取决于我处理的视图。如果你做不到这一点,你最终会得到令人讨厌的*exception。例如,如果我有这些对象

public class A{
  Long id;
  String name;
  List<B> children;
}

public class B{
  Long id;
  A parent;
}

I would want to programmatically ignore the parent field in B if I were looking at A, and ignore the children field in A if I were looking at B.

我想以编程的方式忽略B中的父字段,如果我在看A,忽略A中的子字段如果我在看B。

I started off using mixins to do this, but that very quickly becomes horrible; you have so many useless classes laying around that exist solely to format data. I ended up writing my own serializer to handle this in a cleaner way: https://github.com/monitorjbl/json-view.

我开始用混合物来做这个,但很快就变得很可怕;您有很多无用的类,它们只存在于格式化数据。最后,我编写了自己的序列化程序,以一种更简洁的方式处理这个问题:https://github.com/monitorjbl/json-view。

It allows you programmatically specify what fields to ignore:

它允许您以编程方式指定要忽略的字段:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);

List<A> list = getListOfA();
String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(B.class, match()
        .exclude("parent")));

It also lets you easily specify very simplified views through wildcard matchers:

它还允许您通过通配符匹配器轻松指定非常简化的视图:

String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(A.class, match()
        .exclude("*")
         .include("id", "name")));

In my original case, the need for simple views like this was to show the bare minimum about the parent/child, but it also became useful for our role-based security. Less privileged views of objects needed to return less information about the object.

在我最初的例子中,需要像这样的简单视图来显示父/子的最小值,但它也对基于角色的安全性有用。返回关于对象的更少信息所需的对象的更少的特权视图。

All of this comes from the serializer, but I was using Spring MVC in my app. To get it to properly handle these cases, I wrote an integration that you can drop in to existing Spring controller classes:

所有这些都来自于序列化器,但我在app中使用了Spring MVC。

@Controller
public class JsonController {
  private JsonResult json = JsonResult.instance();
  @Autowired
  private TestObjectService service;

  @RequestMapping(method = RequestMethod.GET, value = "/bean")
  @ResponseBody
  public List<TestObject> getTestObject() {
    List<TestObject> list = service.list();

    return json.use(JsonView.with(list)
        .onClass(TestObject.class, Match.match()
            .exclude("int1")
            .include("ignoredDirect")))
        .returnValue();
  }
}

Both are available on Maven Central. I hope it helps someone else out there, this is a particularly ugly problem with Jackson that didn't have a good solution for my case.

两者都可以在Maven中心上使用。我希望它能帮助其他的人,这是杰克逊的一个特别丑陋的问题,对我的案子没有一个好的解决方案。

#7


4  

Annotation based approach is better. But sometimes manual operation is needed. For this purpose you can use without method of ObjectWriter.

基于注释的方法更好。但有时需要手工操作。为此,您可以不使用ObjectWriter的方法。

ObjectMapper mapper   = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
ObjectWriter writer   = mapper.writer().withoutAttribute("property1").withoutAttribute("property2");
String       jsonText = writer.writeValueAsString(sourceObject);

#8


0  

One more good point here is to use @JsonFilter. Some details here http://wiki.fasterxml.com/JacksonFeatureJsonFilter

这里的另一个优点是使用@JsonFilter。一些细节在这里http://wiki.fasterxml.com/JacksonFeatureJsonFilter

#1


130  

You can use Jackson Mixins. For example:

你可以用杰克逊调酒师。例如:

class YourClass {
  public int ignoreThis() { return 0; }    
}

With this Mixin

这种混合

abstract class MixIn {
  @JsonIgnore abstract int ignoreThis(); // we don't need it!  
}

With this:

用这个:

objectMapper.getSerializationConfig().addMixInAnnotations(YourClass.class, MixIn.class);

Edit:

编辑:

Thanks to the comments, with Jackson 2.5+, the API has changed and should be called with objectMapper.addMixIn(Class<?> target, Class<?> mixinSource)

由于有了Jackson 2.5+的评论,API已经改变,应该使用objectMapper.addMixIn(类 目标类< ?> mixinSource)

#2


54  

One other possibility is, if you want to ignore all unknown properties, you can configure the mapper as follows:

另一种可能是,如果您想忽略所有未知的属性,可以配置映射器如下:

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

#3


19  

Using Java Class

使用Java类

new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

Using Annotation

使用注释

@JsonIgnoreProperties(ignoreUnknown=true)

#4


8  

Mix-in annotations work pretty well here as already mentioned. Another possibility beyond per-property @JsonIgnore is to use @JsonIgnoreType if you have a type that should never be included (i.e. if all instances of GeometryCollection properties should be ignored). You can then either add it directly (if you control the type), or using mix-in, like:

正如前面提到的,Mix-in注释在这里工作得很好。除了每个属性@JsonIgnore之外的另一种可能是使用@JsonIgnoreType,如果您有一个类型不应该包含进来(例如,如果应该忽略所有的GeometryCollection属性实例)。然后您可以直接添加它(如果您控制类型),或者使用mix-in,比如:

@JsonIgnoreType abstract class MixIn { }
// and then register mix-in, either via SerializationConfig, or by using SimpleModule

This can be more convenient if you have lots of classes that all have a single 'IgnoredType getContext()' accessor or so (which is the case for many frameworks)

如果有很多类都只有一个“IgnoredType getContext()”访问器,这就更方便了(这是很多框架的情况)

#5


8  

public @interface JsonIgnoreProperties

Annotation that can be used to either suppress serialization of properties (during serialization), or ignore processing of JSON properties read (during deserialization).

可用于抑制属性的序列化(在序列化期间)或忽略读取的JSON属性的处理(在反序列化期间)的注释。

to prevent specified fields from being serialized or deserialized you can use:

为了防止指定字段被序列化或反序列化,您可以使用:

@JsonIgnoreProperties(ignoreUnknown=true)

#6


4  

I had a similar issue, but it was related to Hibernate's bi-directional relationships. I wanted to show one side of the relationship and programmatically ignore the other, depending on what view I was dealing with. If you can't do that, you end up with nasty *Exceptions. For instance, if I had these objects

我有一个类似的问题,但它与Hibernate的双向关系有关。我想显示关系的一面,并以编程方式忽略另一面,这取决于我处理的视图。如果你做不到这一点,你最终会得到令人讨厌的*exception。例如,如果我有这些对象

public class A{
  Long id;
  String name;
  List<B> children;
}

public class B{
  Long id;
  A parent;
}

I would want to programmatically ignore the parent field in B if I were looking at A, and ignore the children field in A if I were looking at B.

我想以编程的方式忽略B中的父字段,如果我在看A,忽略A中的子字段如果我在看B。

I started off using mixins to do this, but that very quickly becomes horrible; you have so many useless classes laying around that exist solely to format data. I ended up writing my own serializer to handle this in a cleaner way: https://github.com/monitorjbl/json-view.

我开始用混合物来做这个,但很快就变得很可怕;您有很多无用的类,它们只存在于格式化数据。最后,我编写了自己的序列化程序,以一种更简洁的方式处理这个问题:https://github.com/monitorjbl/json-view。

It allows you programmatically specify what fields to ignore:

它允许您以编程方式指定要忽略的字段:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);

List<A> list = getListOfA();
String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(B.class, match()
        .exclude("parent")));

It also lets you easily specify very simplified views through wildcard matchers:

它还允许您通过通配符匹配器轻松指定非常简化的视图:

String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(A.class, match()
        .exclude("*")
         .include("id", "name")));

In my original case, the need for simple views like this was to show the bare minimum about the parent/child, but it also became useful for our role-based security. Less privileged views of objects needed to return less information about the object.

在我最初的例子中,需要像这样的简单视图来显示父/子的最小值,但它也对基于角色的安全性有用。返回关于对象的更少信息所需的对象的更少的特权视图。

All of this comes from the serializer, but I was using Spring MVC in my app. To get it to properly handle these cases, I wrote an integration that you can drop in to existing Spring controller classes:

所有这些都来自于序列化器,但我在app中使用了Spring MVC。

@Controller
public class JsonController {
  private JsonResult json = JsonResult.instance();
  @Autowired
  private TestObjectService service;

  @RequestMapping(method = RequestMethod.GET, value = "/bean")
  @ResponseBody
  public List<TestObject> getTestObject() {
    List<TestObject> list = service.list();

    return json.use(JsonView.with(list)
        .onClass(TestObject.class, Match.match()
            .exclude("int1")
            .include("ignoredDirect")))
        .returnValue();
  }
}

Both are available on Maven Central. I hope it helps someone else out there, this is a particularly ugly problem with Jackson that didn't have a good solution for my case.

两者都可以在Maven中心上使用。我希望它能帮助其他的人,这是杰克逊的一个特别丑陋的问题,对我的案子没有一个好的解决方案。

#7


4  

Annotation based approach is better. But sometimes manual operation is needed. For this purpose you can use without method of ObjectWriter.

基于注释的方法更好。但有时需要手工操作。为此,您可以不使用ObjectWriter的方法。

ObjectMapper mapper   = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
ObjectWriter writer   = mapper.writer().withoutAttribute("property1").withoutAttribute("property2");
String       jsonText = writer.writeValueAsString(sourceObject);

#8


0  

One more good point here is to use @JsonFilter. Some details here http://wiki.fasterxml.com/JacksonFeatureJsonFilter

这里的另一个优点是使用@JsonFilter。一些细节在这里http://wiki.fasterxml.com/JacksonFeatureJsonFilter