使用JAXRS返回子标识
问题描述:
我在使用@Produces时遇到JAXRS/JAXB问题,包括JSON结果中的子标识。以下是我的代码的一部分。因为我们使用Hibernate,所以我将这个id抽象成一个AbstractEntity类。使用JAXRS返回子标识
的POJO:
@XmlRootElement
public abstract class AbstractEntity implements Serializable {
private Serializable id;
@XmlElement(type-Object.class)
@XmlSchemaType(name="anySimpleType")
public final Serializable getId() {
return this.id
}
public final Serializable setId(Serializable id) {
this.id = id;
}
}
@XmlRootElement
public class Parent extends AbstractEntity {
private String parentName;
private Child child;
@XmlElement
public String getParentName() {
return parentName;
}
@XmlElement
public Child getChild() {
return child;
}
}
@XmlRootElement
public class Child extends AbstractEntity {
private String childName;
@XmlElement
public String getChildName() {
return childName;
}
}
JAXRS服务:
@Path("/parent")
public class ParentService {
@GET
@Path("/get/{id}")
@Produces(MediaType.APPLICATION.JSON)
public Parent getById(@PathParam("id") Long id) {
Parent parent = hibernateDataController.getParentById(id);
if (parent== null)
throw new NotFoundException("GET: Parent" + id + " not found.");
return parent;
}
}
@Path("/child")
public class ChildService {
@GET
@Path("/get/{id}")
@Produces(MediaType.APPLICATION.JSON)
public Child getById(@PathParam("id") Long id) {
Child child = hibernateDataController.getChildById(id);
if (child == null)
throw new NotFoundException("GET: Child " + id + " not found.");
return child;
}
}
(注:没有显示更多的代码,但主要部分是以上)
我的项目是在Eclipse中,使用Maven,所以我开启了码头:mvn码头:运行
这是问题出现的地方。我可以通过访问子POJO:
http://myserver:8080/example/child/get/1 returns->
{
"id":{"@type":"xs:long","$":"1"},
"childName":"Bart Simpson"
}
但是,当我访问父POJO,孩子的id没有返回POJO:
http://myserver:8080/example/parent/get/1回报 - >
{
"id":{"@type":"xs:long","$":"1"},
"parentName":"Homer Simpson",
"child": {
"childName":"BartSimpson"
}
}
请注意,没有返回孩子的ID,只是childName。我正在使用的GUI团队正在使用GWT,他们要求我在JSON结果中包含任何孩子的ID。
任何帮助获取JAXRS/JAXB返回子JSON内的ID将不胜感激。谢谢你的时间。
马特
答
今天早上我找到了我对失踪孩子ID的解决方案。它实际上不是JAXRS/JAXB问题,而是由Hibernate映射文件引起的(是的,我仍然喜欢使用映射文件来覆盖Hibernate的注释)。
用于例如文件Hibernate映射文件以上将是:
<hibernate-mapping>
<class name="com.mycompany.Parent" table="PARENT">
<id name="id" type="java.lang.Long">
<column name="PARENT_ID" scale="0" />
<generator class="native" />
</id>
<property name="parentName" type="java.lang.String">
<column name="PARENT_NAME" />
</property>
<set name="children" inverse="true" lazy="true" table="CHILD" fetch="select">
<key>
<column name="CHILD_ID" />
</key>
<one-to-many class="com.mycompany.Child" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.mycompany.Child" table="CHILD">
<id name="id" type="java.lang.Long">
<column name="CHILD_ID" scale="0" />
<generator class="native" />
</id>
<property name="childName" type="java.lang.String">
<column name="CHILD_NAME" />
</property>
<many-to-one name="parent" type="com.mycompany.Child" fetch="select">
<column name="PARENT_ID" />
</many-to-one>
</class>
</hibernate-mapping>
此修复程序是强制Hibernate不是“懒惰负载”的孩子。我改变:
<set name="children" inverse="true" **lazy="true"** table="CHILD" **fetch="select"**>
到:
<set name="children" inverse="true" lazy="false" table="CHILD" **fetch="join"**>
与修改后的Hibernate映射文件的ID来通过JAXRS结果:
{
"id":{"@type":"xs:long","$":"1"},
"parentName":"Homer Simpson",
"child": {
"id":{"@type":"xs:long","$":"1"},
"childName":"BartSimpson"
}
}
希望这会帮助,如果别人跑进这个问题。
如果可能的话,你可以让'id'属性比'long''Serializable'更具体,这将消除'type'(真正的xsi:type)属性被写出来。 – 2011-06-13 18:17:35
不幸的是,我们的数据模型有点“搞砸了”。我们的一些表格使用Long作为ID,其他使用UUID。我选择了Serializable,因为它涵盖了Long和UUID。我仍然想要一个DAO控制器来处理所有的表格。 – 2011-06-13 20:22:26
你的'ParentService'正在返回一个'Person'。在转换为SO问题时,您的层次结构中是否存在另一个级别,或者只有一个错字? – bamana 2011-06-13 21:13:22