同様の問題がありましたが、それはHibernateの双方向の関係に関連していました。私は、関係の一方の面を示し、プログラムでもう一方を無視したかったのですが、私が扱っていた見方によっては。それができない場合は、厄介なStackOverflowException
sになります。たとえば、これらのオブジェクトがある場合
public class A{
Long id;
String name;
List<B> children;
}
public class B{
Long id;
A parent;
}
プログラムparent
でAを見ている場合はB のフィールドを無視し、Bを見ているchildren
場合はA のフィールドを無視します。
私はこれを行うためにミックスインを使い始めましたが、それはすぐに恐ろしくなります。データをフォーマットするためだけに存在する無駄なクラスがたくさんあります。私はこれをよりきれいな方法で処理するために自分のシリアライザを作成することになりました: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で利用できます。私はそれが他の誰かを助けることを願っています、これは私のケースに対して良い解決策を持っていなかったジャクソンの特に醜い問題です。