22

循環参照に問題があります。

オブジェクトをフロントエンドに返すRest Webservicesがあります。問題は、いくつかの参照を持つオブジェクトを返そうとしたときに発生するため、結果として無限の応答が生成されます。

java.lang.IllegalStateException: 
    Cannot call sendError() after the response has been committed

オブジェクトは Hibernate Code Generation によって自動的に生成され、バックエンドに循環参照が必要です。Jackson を使用して情報をフロントエンドに送信する前に、循環参照を削除するだけです。

コントローラーのメソッド ヘッダーは次のとおりです。

@RequestMapping(value="/list", method=RequestMethod.POST)
public @ResponseBody eventResponse list(@RequestBody String sessionID) {

私はJsonに変換するために明示的に何もしていません。私はこれを初めて使用し、jacksonがこれを自動的に解決したと思います。

4

3 に答える 3

44

これには 2 つの方法があります。エンティティを外部に公開する必要がある場合@JsonIgnoreは、循環参照の原因となっているプロパティを追加することをお勧めします。これにより、Jackson はそのプロパティをシリアル化しないように指示されます。

もう 1 つの方法は、Jackson が提供する双方向機能を使用することです。@JsonManagedReferenceまたはのいずれかを使用できます@JsonBackReference@JsonManagedReferenceプロパティの「転送」部分であり、通常どおりシリアル化されます。@JsonBackReference参照の「後ろ」の部分です。シリアライズされませんが、「フォワード」タイプがデシリアライズされると再構築されます。

ここで例を確認できます。

これはあなたのコメントに対応しています。この場合、あなたがやりたいことは、外の世界から見える DTO を使用することだと思います。エンティティを外部に公開したくないので、このアプローチが気に入っています。これは、Jackson の注釈がエンティティーではなく DTO にあることを意味します。エンティティを DTO に変換するある種のマッパーまたはコンバーターが必要になります。エンティティに変更を加えても、マッパー/コンバーターを変更しない限り、DTO に反映されません。エンティティに変更を加えるときに、その変更を公開するかどうかを決定できるため、これで問題ないと思います。

アップデート

ここには、Jackson で双方向の関係を処理するさまざまな方法について詳しく説明している優れたブログ投稿があります。、、@JsonIgnore@JsonManagedReferenceおよびカスタム シリアライザも使用するソリューションについて説明します。これは、使用できるさまざまなテクニックのかなり包括的な記事です。@JsonBackReference@JsonIdentityInfo@JsonView

于 2013-06-30T19:03:44.797 に答える