长话短说,我的一个实体有一个GeometryCollection,当你调用“getBoundary”时会抛出异常(为什么这是另一本书,现在让我们说这就是它的工作方式)。
有没有办法告诉杰克逊不要包含那个特定的吸气剂?我知道当我拥有/控制代码时我可以使用@JacksonIgnore。但事实并非如此,杰克逊通过连续序列化父对象来达到这一点。我在jackson文档中看到了一个过滤选项。这是一个看似合理的解决方案吗?
谢谢!
答案 0 :(得分:145)
您可以使用Jackson Mixins。例如:
class YourClass {
public int ignoreThis() { return 0; }
}
使用此Mixin
abstract class MixIn {
@JsonIgnore abstract int ignoreThis(); // we don't need it!
}
有了这个:
objectMapper.getSerializationConfig().addMixInAnnotations(YourClass.class, MixIn.class);
编辑:
感谢Jackson 2.5+的评论,API已更改,应使用objectMapper.addMixIn(Class<?> target, Class<?> mixinSource)
答案 1 :(得分:61)
另一种可能性是,如果要忽略所有未知属性,可以按如下方式配置映射器:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
答案 2 :(得分:24)
使用Java类
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
使用注释
@JsonIgnoreProperties(ignoreUnknown=true)
答案 3 :(得分:8)
如上所述,混合注释在这里工作得很好。每个属性@JsonIgnore之外的另一种可能性是使用@JsonIgnoreType,如果你有一个永远不应该包含的类型(即如果应该忽略所有GeometryCollection属性的实例)。然后,您可以直接添加它(如果您控制类型),或者使用混合,例如:
@JsonIgnoreType abstract class MixIn { }
// and then register mix-in, either via SerializationConfig, or by using SimpleModule
如果你有很多类都有一个'IgnoredType getContext()'访问器,那么这会更方便(许多框架就是这种情况)
答案 4 :(得分:8)
基于注释的方法更好。但有时需要手动操作。为此,您可以使用 ObjectWriter 的无方法。
<Class>
<Student>
<name>First</name>
<age></age>
</Student>
<Student>
<name>Second</name>
<age></age>
</Student>
</Class>.
答案 5 :(得分:5)
我有一个类似的问题,但它与Hibernate的双向关系有关。我希望展示关系的一面,并以编程方式忽略另一面,具体取决于我处理的是什么视图。如果你不能这样做,你最终会得到令人讨厌的StackOverflowException
。例如,如果我有这些对象
public class A{
Long id;
String name;
List<B> children;
}
public class B{
Long id;
A parent;
}
如果我正在查看A,我想以编程方式忽略B中的parent
字段,如果我正在查看B,则忽略A中的children
字段。
我开始使用mixins来做这件事,但很快就会变得很糟糕;你有很多无用的课程,只是为了格式化数据。我最终编写了自己的序列化程序,以更清晰的方式处理它:https://github.com/monitorjbl/json-view。
它允许您以编程方式指定要忽略的字段:
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")));
它还允许您通过通配符匹配器轻松指定非常简化的视图:
String json = mapper.writeValueAsString(JsonView.with(list)
.onClass(A.class, match()
.exclude("*")
.include("id", "name")));
在我原来的情况下,需要像这样的简单视图来显示父/子的最低限度,但它对我们基于角色的安全性也很有用。返回关于对象的较少信息所需的对象的特权较少的视图。
所有这些都来自序列化程序,但我在我的应用程序中使用了Spring MVC。为了使它能够正确处理这些情况,我编写了一个集成,您可以将其放入现有的Spring控制器类中:
@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();
}
}
两者都可以在Maven Central上找到。我希望它可以帮助其他人,这对杰克逊来说是一个特别难看的问题,对我的案子没有很好的解决方案。
答案 6 :(得分:0)
这里的另一个好处是使用@JsonFilter
。
这里有一些细节http://wiki.fasterxml.com/JacksonFeatureJsonFilter
答案 7 :(得分:0)
如果您希望始终为任何类排除某些属性,则可以使用setMixInResolver
方法:
@JsonIgnoreProperties({"id", "index", "version"})
abstract class MixIn {
}
mapper.setMixInResolver(new ClassIntrospector.MixInResolver(){
@Override
public Class<?> findMixInClassFor(Class<?> cls) {
return MixIn.class;
}
@Override
public ClassIntrospector.MixInResolver copy() {
return this;
}
});