使用 Jackson 将通用 java 对象序列化为 JSON
Posted
技术标签:
【中文标题】使用 Jackson 将通用 java 对象序列化为 JSON【英文标题】:Serializing generic java object to JSON using Jackson 【发布时间】:2011-12-23 17:37:50 【问题描述】:当我尝试将以下类实例转换为 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 ;
进入无限循环:
在 sun.reflect.GeneratedMethodAccessor48.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 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) 在 org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) 在 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(ObjectMapper.java:2566) 在 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?
【问题讨论】:
完全不相关,但是 ctor 签名让我有点冷——我宁愿看到明确命名成功/失败状态的小工厂,而不是具有怪异语义的 ctor。也不确定为什么将字符串设置为空白,然后立即用 JSON 覆盖它。 为了简单起见,我删除了一些代码 您是否尝试过使用@JsonIgnore
注释?我不知道它是否会默认跳过 @Transient 属性。这是一个 Hibernate 实体吗?
用户是 pojo 对象,还没有休眠注释。我确实计划稍后添加它们。你建议在哪里添加@jsonignore?
致可能导致无限循环的吸气剂。
【参考方案1】:
正如其他人所建议的,这很可能是由于循环引用;默认情况下,Jackson 不处理此类依赖项。
您可以尝试跳过该属性的序列化,或者,如果它是父/子类型链接,则对其进行注释(有关详细信息,请参阅 Jackson Wiki 上的“bi-directional references”条目)。
不管怎样,泛型类型不会导致这种情况(也就是说,这可能只是一个巧合);循环类型非常好。
【讨论】:
您是我的英雄。节省了 0.5 PD。【参考方案2】:默认情况下,Jackson 将通过get
方法进行序列化。一旦遇到getAsJson
方法,poom,无限循环。用@JsonIgnore
注释标记它。
@JsonIgnore
public String getAsJSON()
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this) ;
您还可以将 Jackson 配置为仅基于属性进行序列化,这可能会消除对 @JsonIgnore
的需求,但这可能会也可能不会满足您的需求。
我相信最新的 Jackson 允许选择使用 Hibernate @Transient
注释,尽管我不确定如何配置它(最近的变化)。
【讨论】:
(对downvoting 的解释/说明通常受到赞赏。) @JsonIgnore 拯救了我的一天以上是关于使用 Jackson 将通用 java 对象序列化为 JSON的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 Jackson ObjectMapper 将 Json 序列化为 Java 对象
如何使用 Jackson 将原始 JSON 反序列化为 Java 对象