使用Jackson将通用java对象序列化为JSON

时间:2011-11-07 15:39:29

标签: java jackson

当我尝试将以下类实例转换为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?

2 个答案:

答案 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”条目。)

对于它的价值,泛型类型不会导致这种情况(即它可能只是巧合);循环类型非常好。