I had a similar problem, but it was related to the Hibernate bidirectional relationship. I wanted to show one side of the relationship and programmatically ignore the other, depending on which point of view I was dealing with. If you cannot do this, you will get nasty StackOverflowException s. For example, if I had these objects
public class A{ Long id; String name; List<B> children; } public class B{ Long id; A parent; }
I would like to programmatically ignore the parent field in B if I look at A, and ignore the children field in A if I look at B.
I started using the mixin to do this, but it quickly becomes terrible; there are so many useless classes around you that exist solely for formatting data. I ended up writing my own serializer for cleaner processing: https://github.com/monitorjbl/json-view .
This allows you to programmatically indicate which 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 allows you to easily specify very simplified representations using wildcards:
String json = mapper.writeValueAsString(JsonView.with(list) .onClass(A.class, match() .exclude("*") .include("id", "name")));
In my original case, the need for simple ideas like this was to show a minimum minimum for the parent / child, but it also became useful for our role-based security. Less privileged representations of objects are needed to get less information about the object.
It all comes from a serializer, but I used Spring MVC in my application. So that he handles these cases correctly, I wrote an integration that you can incorporate into existing Spring controller classes:
@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 at Maven Central. I hope this helps someone else, this is a particularly ugly problem with Jackson, which did not have a good solution for my case.