Quand j'ai essayé de convertir l'instance de classe suivante en JSON (en utilisant Jackson)
public class RPCRespond<Result> {
private int code;
private Result result;
private boolean success;
private String failureReason;
public RPCRespond() {
this.code = 0;
this.success = true;
this.result = null;
}
public RPCRespond(Result result) {
this.code = 0;
this.success = true;
this.result = result;
}
public RPCRespond(int code, String failureReason) {
this.code = code;
this.success = false;
this.failureReason = failureReason;
}
public RPCRespond(int code, String failureReason, Object... args) {
this.code = code;
this.success = false;
this.failureReason = String.format(failureReason, args);
}
public Result getResult() {
return result;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getFailureReason() {
return failureReason;
}
public void setFailureReason(String failureReason) {
this.failureReason = failureReason;
}
public int getCode() {
return code;
}
public boolean getSuccess() {
return success;
}
@Transient
public String getAsJSON() {
String json = "";
ObjectMapper mapper = new ObjectMapper();
json = mapper.writeValueAsString(this) ;
return json ;
}
}
il entre dans une boucle infinie de:
sur Sun.reflect.GeneratedMethodAccessor48.invoke (Source inconnue) sur Sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.Java:43) sur Java.lang.reflect.Method .invoke (Method.Java:601) à org.codehaus.jackson.map.ser.BeanPropertyWriter.get (BeanPropertyWriter.Java:483) à org.codehaus. jackson.map.ser.BeanPropertyWriter.serializeAsField (BeanPropertyWriter.Java:418) à org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields (BeanSerializerBase.Java:150) sur org.codehaus.jackson.map.ser.BeanSerializer.serialize (BeanSerializer.Java:112) sur org.codehaus.jackson.map.ser .StdSerializerProvider._serializeValue (StdSerializerProvider.Java:610) À Org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue (StdSerializerProvider.Java:256) À org.codehaus.jackson.map.ObjectMapper._configAndWriteValue (ObjectMapp er.Java:2566) à org.codehaus.jackson.map.ObjectMapper.writeValueAsString (ObjectMapper.Java:2088)
L'initiation du RPCRespond se fait par
User u = new User() ;
u.setFirstName("aaaa") ;
RPCRespond<User> result = new RPCRespond<User>(u) ;
result.setSuccess(true) ;
return result.getAsJSON() ;
Comment puis-je convertir RPCRespond en JSON?
Par défaut, Jackson sérialisera via les méthodes get
. Une fois qu'il atteint la méthode getAsJson
, poom, boucle infinie. Marquez-le avec le @JsonIgnore
annotation.
@JsonIgnore
public String getAsJSON() {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this) ;
}
Vous pouvez également configurer Jackson pour sérialiser en fonction des propriétés uniquement, ce qui peut éliminer le besoin de @JsonIgnore
, mais cela peut ou non répondre à vos besoins.
I croyez le dernier Jackson permet le choix d'utiliser le Hibernate @Transient
annotation, mais je ne sais pas comment le configurer (changement récent).
Comme d'autres l'ont suggéré, cela est probablement dû à des références cycliques; par défaut, Jackson ne gère pas ces dépendances.
Vous pouvez soit ignorer la sérialisation de cette propriété, soit, s'il s'agit d'une liaison de type parent/enfant, l'annoter en tant que telle (voir l'entrée " références bidirectionnelles " sur Jackson Wiki pour plus de détails).
Pour ce que ça vaut, les types génériques ne provoquent pas cela (c'est-à-dire que ce n'est probablement qu'une coïncidence ici); les types cycliques sont parfaitement fins.