17

Gsonライブラリを使用して JavaオブジェクトをJson応答に変換します...問題は、JPAリクエストの後、他のエンティティとの再帰的な関係のために、DBから取得したオブジェクトを変換できないことです(前の質問を参照)。

public class Gps implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "IMEI", nullable = false, length = 20)
    private String imei;
    //some code here...
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "gpsImei", fetch = FetchType.LAZY)
    private List<Coordonnees> coordonneesList;


public class Coordonnees implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "IDCOORDONNEES", nullable = false)
    private Integer idcoordonnees;
    //some code here...
    @JoinColumn(name = "GPS_IMEI", referencedColumnName = "IMEI", nullable = false)
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Gps gpsImei;

私のソースコード:

  EntityManagerFactory emf=Persistence.createEntityManagerFactory("JavaApplication21PU");
  GpsJpaController gjc=new GpsJpaController(emf);

  Gps gps=gjc.findGps("123456789012345");

  for(int i=0;i<gps.getCoordonneesList().size();i++){
   gps.getCoordonneesList().get(i).setGpsImei(null);
  }  

  Gson gson=new Gson();
  String json=gson.toJson(gps);//convert to json response

  System.out.println(json);  

あなたがここで見ることができるように私は作りました:

   for(int i=0;i<gps.getCoordonneesList().size();i++){
     gps.getCoordonneesList().get(i).setGpsImei(null);
   }  

coordonneesList内の各GPSオブジェクトにnullを設定することにより、再帰的な関係を強制終了するだけです。

あなたの意見では、これは良い解決策ですか、それとももっと実用的な別の方法がありますか?ありがとう

4

5 に答える 5

28

循環参照を含むオブジェクトをシリアル化できるGraphAdapterBuilderと呼ばれるGson拡張機能があります。対応するテストケースの非常に単純化された例を次に示します。

Roshambo rock = new Roshambo("ROCK");
Roshambo scissors = new Roshambo("SCISSORS");
Roshambo paper = new Roshambo("PAPER");
rock.beats = scissors;
scissors.beats = paper;
paper.beats = rock;

GsonBuilder gsonBuilder = new GsonBuilder();
new GraphAdapterBuilder()
    .addType(Roshambo.class)
    .registerOn(gsonBuilder);
Gson gson = gsonBuilder.create();
System.out.println(gson.toJson(rock));

これは印刷します:

{
  '0x1': {'name': 'ROCK', 'beats': '0x2'},
  '0x2': {'name': 'SCISSORS', 'beats': '0x3'},
  '0x3': {'name': 'PAPER', 'beats': '0x1'}
}

GraphAdapterBuilderクラスはgson.jarに含まれていないことに注意してください。使用する場合は、手動でプロジェクトにコピーする必要があります。

于 2012-04-06T16:14:42.850 に答える
2

Gsonについてはわかりませんが、Jacksonと一緒に仕事をしています。ObjectMapperクラスの使用例を調べてください。再帰については、@JsonManagedReferenceと@JsonBackReferenceを使用して停止します。使用法なども調べてください。

于 2012-04-06T02:25:06.933 に答える
1

@Expose(serialize = false)を使用して、コレクションがシリアル化されないようにすることができます。

于 2015-01-21T10:46:09.023 に答える
1

google.gsonの@OneToManyセットを無視するためにtransientを使用する

于 2017-11-06T15:07:24.270 に答える
1

ジャクソンアノテーションを処理するようにGsonBuilderを構成します。

GsonBuilder builder = new GsonBuilder()
    .addSerializationExclusionStrategy(serializationExclusionStrategy);

final ExclusionStrategy serializationExclusionStrategy = new ExclusionStrategy() {
  @Override
  public boolean shouldSkipField(FieldAttributes f) {
    return f.getAnnotation(JsonIgnore.class) != null
           || f.getAnnotation(JsonBackReference.class) != null;
  }

  @Override
  public boolean shouldSkipClass(Class<?> aClass) {
    return false;
  }
};
于 2020-01-14T19:00:42.390 に答える