ฉันมีปัญหาที่คล้ายกัน แต่เกี่ยวข้องกับความสัมพันธ์สองทิศทางของ Hibernate ฉันต้องการแสดงด้านหนึ่งของความสัมพันธ์และเพิกเฉยต่ออีกด้านหนึ่งโดยทางโปรแกรมขึ้นอยู่กับมุมมองที่ฉันกำลังเผชิญอยู่ ถ้าทำไม่ได้ก็จบด้วยStackOverflowException
s ที่น่ารังเกียจ ตัวอย่างเช่นถ้าฉันมีวัตถุเหล่านี้
public class A{
Long id;
String name;
List<B> children;
}
public class B{
Long id;
A parent;
}
ฉันต้องการที่จะละเว้นparent
ฟิลด์ใน B โดยทางโปรแกรมถ้าฉันมองไปที่ A และไม่สนใจchildren
ฟิลด์ใน A ถ้าฉันกำลังมองไปที่ B
ฉันเริ่มจากการใช้มิกซ์อินเพื่อทำสิ่งนี้ แต่มันก็กลายเป็นเรื่องน่ากลัวอย่างรวดเร็ว คุณมีชั้นเรียนที่ไร้ประโยชน์มากมายที่มีอยู่เพื่อจัดรูปแบบข้อมูลเท่านั้น ฉันลงเอยด้วยการเขียน serializer ของตัวเองเพื่อจัดการสิ่งนี้ด้วยวิธีที่สะอาดกว่า: https://github.com/monitorjbl/json-view 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")));
ในกรณีเดิมของฉันความต้องการมุมมองที่เรียบง่ายเช่นนี้คือการแสดงขั้นต่ำที่เปลือยเปล่าเกี่ยวกับพ่อแม่ / ลูก แต่ก็มีประโยชน์สำหรับการรักษาความปลอดภัยตามบทบาทของเราด้วย มุมมองที่มีสิทธิพิเศษน้อยกว่าของอ็อบเจ็กต์ที่จำเป็นในการส่งคืนข้อมูลเกี่ยวกับอ็อบเจ็กต์น้อยลง
ทั้งหมดนี้มาจาก serializer แต่ฉันใช้ Spring MVC ในแอปของฉัน เพื่อให้จัดการกับกรณีเหล่านี้ได้อย่างถูกต้องฉันได้เขียนการผสานรวมที่คุณสามารถส่งไปยังคลาส Spring controller ที่มีอยู่ได้:
@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 ฉันหวังว่ามันจะช่วยคนอื่นได้นี่เป็นปัญหาที่น่าเกลียดอย่างยิ่งกับแจ็คสันที่ไม่มีทางออกที่ดีสำหรับกรณีของฉัน