长话短说,我的一个实体拥有一个GeometryCollection对象,当调用“getBoundary”方法时会抛出异常(为什么会这样是另一本书的问题,现在我们假设它就是这样工作的)。
我是否可以告诉Jackson不要包括那个特定的getter方法?我知道当我拥有或控制代码时,可以使用@JacksonIgnore。但这不是这种情况,Jackson通过父对象的连续序列化最终到达这一点。我在jackson文档中看到了过滤选项,这是一个可行的解决方案吗?
谢谢!
长话短说,我的一个实体拥有一个GeometryCollection对象,当调用“getBoundary”方法时会抛出异常(为什么会这样是另一本书的问题,现在我们假设它就是这样工作的)。
我是否可以告诉Jackson不要包括那个特定的getter方法?我知道当我拥有或控制代码时,可以使用@JacksonIgnore。但这不是这种情况,Jackson通过父对象的连续序列化最终到达这一点。我在jackson文档中看到了过滤选项,这是一个可行的解决方案吗?
谢谢!
您可以使用Jackson Mixin注释。
class YourClass {
public int ignoreThis() { return 0; }
}
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)
进行调用。
objectMapper.addMixInAnnotations(Class<?> target, Class<?> mixinSource);
方法来添加混合注解。 - CorayThan@JsonIgnore private HttpClient httpClient;
- aksh1618mapper.disable(MapperFeature.USE_ANNOTATIONS);
如果它之前已经配置过,否则这些 Mixin 注解将不会起作用。 - gkns另一种可能性是,如果您想忽略所有未知的属性,您可以按照以下方式配置映射器:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.failOnUnknownPropertiesExcep(new String[] {"myField"}));
。 - ms_27without()
进行配置,例如:mapper.reader().without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
。 - Drew Stephens使用Java类
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
使用注释
@JsonIgnoreProperties(ignoreUnknown=true)
基于注解的方法更好。但有时需要手动操作。为此,您可以使用ObjectWriter 的without方法。
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
ObjectWriter writer = mapper.writer().withoutAttribute("property1").withoutAttribute("property2");
String jsonText = writer.writeValueAsString(sourceObject);
ObjectWriter.withoutAttribute
方法的作用与答案中所建议的不同。"attribute" 不是指输入数据的属性名称,也从未在此类语境下引用过,例如在这个评论中指出。该方法似乎是专为内部使用而设计的,如这里所示。 - omahdi如果您想要在任何类中始终排除某些属性,可以使用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;
}
});
正如先前提到的那样,混合注释在这里非常有效。如果您有一种永远不应该包含的类型(即,如果所有GeometryCollection属性的实例都应该被忽略),除了每个属性@JsonIgnore之外,另一个可能性是使用@JsonIgnoreType。然后,您可以直接添加它(如果您控制该类型),或者使用混合注释,例如:
@JsonIgnoreType abstract class MixIn { }
// and then register mix-in, either via SerializationConfig, or by using SimpleModule
我曾经遇到过类似的问题,但它与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
字段。
一开始我使用了mixin来做这个,但很快就变得很糟糕;你会有很多无用的类存在,仅仅是为了格式化数据。最终我编写了自己的序列化器以更清晰的方式处理它: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")));
@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上找到。希望能对其他人有所帮助,因为这是一个特别棘手的问题,对于我来说,Jackson没有一个好的解决方案。
Match.match()
的 import
是什么? - Pasupathi Rajamanickam