我一直在研究这个问题好几个小时,可能很简单,但我不再理解了:
我有一个实体(Param),它通过jax-rs呈现给json。实体引用另一个实体(步骤)。 在编写/读取json时,我不想看到整个步骤实体,只是它的id,所以我使用这段代码:
@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Param implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
long id;
@Column(name = "KEYNAME")
String key;
String value;
@XmlIDREF
Step step;
}
完美适用于编组。
因此,任何GET请求都会向我显示以下内容:
{id: 1,
key: "a",
value: "b",
step: 53
}
但是当我向服务器发布一些param时,它无法将数字id映射回step-entity。
我需要为unmarshaller提供自定义IDResolver。但是如何配置unmarshaller ???? Jax-RS servlet正在为我进行编组。我的代码看起来像这样:
@Path("param")
public class ParamRepresentation {
/**
* Retrieves representation of an instance of ParamRepresentation
* @return an instance of Param
*/
@GET
@Produces("application/json")
@Path("{ID}")
public Param getJson(@PathParam("ID") long id) {
return (Param) ctr.find(id, Param.class);
}
@PUT
@Path("{ID}")
@Consumes("application/json")
@Produces("application/json")
public SuccessMessage updateStep(@PathParam("ID") long id, Param p) {
ctr.update(p);
ParamSuccessMessage sm = new ParamSuccessMessage();
sm.setSuccess(true);
sm.setParam(p);
return sm;
}
}
那么如何配置unmarshaller ?????
答案 0 :(得分:1)
我认为你误解了XML模式中IDREF的用途。它允许您引用另一个标记为ID的元素(即,在JAXB中使用@XmlID
注释)在同一文档中。你不能用它来引用世界其他地方的ID;因为你使用了一个URI(可能带有一个片段标识符部分)。要在JAXB中执行那些,请使用:
@XmlElement // You might be able to omit this part; it's here for clarity
@XmlSchemaType(name = "anyURI")
public URI exampleField;
然后,您需要确定URI是否引用您知道的内容(即,解析URI并查看它是否指向您自己)并处理片段标识符。或者做一个更常见的只使用字符串的技巧,而不用担心尝试神奇地挂钩绑定层中的所有内容。 (这在实践中效果很好。)
答案 1 :(得分:1)
我使用Jersey和xml表示做了类似的事情。我使用xml适配器在完整的子元素和部分(只是id)元素之间进行对称映射。
我会在Param实体中注释Step实体,如下所示:
//javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter
@XmlJavaTypeAdapter(PartialStepEntityAdapter.class)
Step step
然后,您需要定义部分步骤实体和适配器。 PartialStep
与原始步骤类相同,但只包含id字段。
PartialStepEntityAdapter
会在编组时将Step
映射到PartialStep
,并在解组时将PartialStep
映射到Step
:
//javax.xml.bind.annotation.adapters.XmlAdapter
public class PartialStepEntityAdapter extends XmlAdapter<PartialStep, Step> {
@Override
public Step unmarshal(PartialStep partialStep) throws Exception {
Step step = new Step();
step.setId(partialStep.getId());
return step;
}
@Override
public PartialStep marshal(Step step) throws Exception {
PartialStep partialStep= new PartialStep();
partialStep.setId(step.getId());
return partialStep;
}
}
希望有所帮助。