【发布时间】:2012-03-09 22:49:05
【问题描述】:
所以我正在使用 Java、Hibernate、JPA 注释、JAX-RS 注释、JAXB 注释、Jersey 和 Jackson JSON 解析器来开发 RESTful 数据 API。
在尝试了 Jersey 提供的 MAPPING 和 NATURAL JSON 符号的各种配置后,我最终决定改用 Jackson JSON 解析器。除了这一点,杰克逊将是完美的......
我遇到的问题是 Jackson 不能使用 JAXB 注释“@XmlID”和“@XmlIDREF”,我用它们来表示我的实体关系,尽管“@JsonBackReference”和“@JsonManagedReference “帮助解决这个问题。在处理直接的自引用属性时,这种组合似乎失效了。
这似乎是一个相当普遍的问题。你们中的任何人是如何绕过 Jackson 的这一限制的?
以我的 POJO 为...
@XmlRootElement
public class Employee implements Serializable {
private Date lastUpdatedOn;
private Employee lastUpdatedBy;
private Integer empId;
@JoinColumn(nullable=false)
@OneToOne
@XmlIDREF
public Employee getLastUpdatedBy() {
return createdBy;
}
public void setLastUpdatedBy(Employee lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
@Temporal(TemporalType.TIMESTAMP)
public Date getLastUpdatedOn() {
return createdOn;
}
public void setLastUpdatedOn(Date lastUpdatedOn) {
this.lastUpdatedOn = lastUpdatedOn;
}
@XmlID
@XmlJavaTypeAdapter(IntegerAdapter.class)
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
}
...以及以下 EmployeeResource...
@Path("/Employees")
public class EmployeeResource {
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
@GET
@Path("/{empId}")
public Response getEmployees(
@Context UriInfo ui
, @PathParam("id") Integer empId
) {
this.employees = HibernateUtil.pagedQuery(
Employee.class
, new ArrayList() {
Restrictions.eq("empId",empId)
}
);
return Response.ok(this).build();
}
}
我的 JAX-RS 资源会产生以下错误
org.codehaus.jackson.map.JsonMappingException: Direct self-reference leading to cycle (through reference chain: resources.EmployeeResource["employees"]->java.util.ArrayList[0]->entities.Employee["lastUpdatedBy"])
...但我希望它产生...
{
"employees" : [ {
"lastUpdatedOn" : 1331149770737,
"lastUpdatedBy" : 10150,
"empId" : 10150,
} ],
}
提前谢谢大家!
注意事项:
- 我使用 IntegerAdapter.class 将其转换为字符串,以便与 @XmlID 注释一起使用。
- 上述 Employee 和 EmployeeResource 类只是我的实际实现的缩写版本,但它们代表了我的实现中与这个直接自引用问题相关的部分。
编辑 #1 2012.03.10 对不起,在这个问题的第一个版本中,我对使用 Jersey 的自然符号的版本与我使用 Jackson 运行的版本感到困惑。我已经修改了我的问题,以更准确地反映我对杰克逊的直接自我引用问题。
【问题讨论】:
-
我认为您的问题与
@XmlID原样无关,而是与 JSON 基础知识有关。 JSON 不支持类型,因此"10150"(字符串)和10150(整数,但不支持)是“相同的”。 -
我不得不不同意。 JSON 对 Object、Array、String 和 number 等类型有了解,www.json.org 。
-
我错了对不起。我相信你需要的是从
Date到int的转换器。参见示例here。 -
对不起@dma_k,我在写这个问题时感到困惑。我试图回去更具体。最初我只是使用 Jersey 的自然注释,它不能很好地处理日期。现在我正在使用 Jackson,所有字符串、日期(时间戳)和数字都已正确序列化。但是,我现在遇到了这个直接的自引用问题,当 Jersey 使用 JAXB 注释“@XmlID”和“@XmlIDREF”时,这不是问题。
标签: java jaxb jersey jax-rs jackson