Tôi đã gặp vấn đề tương tự, nhưng nó liên quan đến các mối quan hệ hai chiều của Hibernate. Tôi muốn thể hiện một mặt của mối quan hệ và lập trình bỏ qua mặt kia, tùy thuộc vào quan điểm mà tôi đang xử lý. Nếu bạn không thể làm điều đó, bạn sẽ kết thúc với những điều khó chịu StackOverflowException
. Ví dụ, nếu tôi có những đồ vật này
public class A{
Long id;
String name;
List<B> children;
}
public class B{
Long id;
A parent;
}
Tôi muốn lập trình bỏ qua parent
trường ở B nếu tôi đang nhìn A và bỏ qua children
trường trong A nếu tôi đang nhìn B.
Tôi đã bắt đầu sử dụng mixin để làm điều này, nhưng điều đó rất nhanh chóng trở nên kinh khủng; bạn có rất nhiều lớp vô dụng nằm xung quanh chỉ tồn tại để định dạng dữ liệu. Cuối cùng, tôi đã viết bộ tuần tự của riêng mình để xử lý vấn đề này theo cách gọn gàng hơn: https://github.com/monitorjbl/json-view .
Nó cho phép bạn chỉ định theo chương trình những trường nào cần bỏ qua:
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")));
Nó cũng cho phép bạn dễ dàng chỉ định các chế độ xem rất đơn giản thông qua trình đối sánh ký tự đại diện:
String json = mapper.writeValueAsString(JsonView.with(list)
.onClass(A.class, match()
.exclude("*")
.include("id", "name")));
Trong trường hợp ban đầu của tôi, nhu cầu về các chế độ xem đơn giản như thế này là thể hiện mức tối thiểu nhất về cha / con, nhưng nó cũng trở nên hữu ích cho bảo mật dựa trên vai trò của chúng tôi. Chế độ xem ít đặc quyền của các đối tượng cần thiết để trả về ít thông tin hơn về đối tượng.
Tất cả những điều này đến từ bộ tuần tự, nhưng tôi đã sử dụng Spring MVC trong ứng dụng của mình. Để giúp nó xử lý đúng các trường hợp này, tôi đã viết một tích hợp mà bạn có thể đưa vào các lớp Spring controller hiện có:
@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();
}
}
Cả hai đều có sẵn trên Maven Central. Tôi hy vọng nó sẽ giúp được ai đó ngoài kia, đây là một vấn đề đặc biệt xấu với Jackson mà không có giải pháp tốt cho trường hợp của tôi.