当我尝试将以下类实例转换为JSON(使用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 ;
}
}
它进入无限循环:
at sun.reflect.GeneratedMethodAccessor48.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.codehaus.jackson.map.ser.BeanPropertyWriter.get(BeanPropertyWriter.java:483) at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:418) at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610) at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256) at org.codehaus.jackson.map.ObjectMapper._configAndWriteValue(ObjectMapper.java:2566) at org.codehaus.jackson.map.ObjectMapper.writeValueAsString(ObjectMapper.java:2088)
RPCRespond的启动由
完成User u = new User() ;
u.setFirstName("aaaa") ;
RPCRespond<User> result = new RPCRespond<User>(u) ;
result.setSuccess(true) ;
return result.getAsJSON() ;
如何将RPCRespond转换为JSON?
答案 0 :(得分:56)
默认情况下,杰克逊将通过get
方法进行序列化。一旦它到达getAsJson
方法, poom ,无限循环。使用@JsonIgnore
注释标记它。
@JsonIgnore
public String getAsJSON() {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this) ;
}
您还可以将Jackson配置为仅基于属性进行序列化,这可能会消除对@JsonIgnore
的需求,但可能会或可能不会满足您的需求。
我相信最新的Jackson允许选择使用Hibernate @Transient
注释,虽然我不确定如何配置它(最近的更改)。
答案 1 :(得分:2)
正如其他人所说,这很可能是由于循环引用;默认情况下,杰克逊不会处理这种依赖。
您可以尝试跳过该属性的序列化,或者,如果它是父/子类型链接,则可以对其进行注释(有关详细信息,请参阅Jackson Wiki中的“bi-directional references”条目。)
对于它的价值,泛型类型不会导致这种情况(即它可能只是巧合);循环类型非常好。