我有一个RESTful服务,如果随请求提交“选择器”,则只需要返回一些XmlElements。该URL将采用以下形式:
/merchants/{merchantId}/profile?selectors=<field1|field2|....|fieldN>
选择器是可选的,到目前为止,我已经为没有指定选择器的{merchantId}
返回的完整元素集实现了服务。现在我想弄清楚如何添加这个添加的功能。我确信这包含在文档中,但我无法找到。任何RTFM指针将不胜感激。感谢。
答案 0 :(得分:2)
EclipseLink JAXB (MOXy)目前不提供一种机制来选择性地指示每个编组操作包含哪些字段/属性。这听起来像一个有趣的用例。如果您可以使用以下链接输入此作为增强请求,我将不胜感激:
下面是一个示例,说明如何使用有状态XmlAdapter
来实现此用例,方法是利用JAXB (JSR-222)在值为null时不会封送元素的事实(请参阅:{{ 3}})。
<强> FieldAdapter 强>
由于我们要利用有状态的XmlAdapter,我们每个字段需要一个。由于我们所有的XmlAdapter都将执行相同的逻辑,我们可以创建一个其他人可以扩展的超类。
package forum13094195;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class FieldAdapter<T> extends XmlAdapter<T, T> {
private boolean include;
public FieldAdapter() {
this.include = true;
}
public FieldAdapter(boolean include) {
this.include = include;
}
@Override
public T marshal(T value) throws Exception {
if(include) {
return value;
}
return null;
}
@Override
public T unmarshal(T value) throws Exception {
return value;
}
}
<强> Field1Adapter 强>
package forum13094195;
public class Field1Adapter extends FieldAdapter<String> {
public Field1Adapter() {}
public Field1Adapter(boolean include) {
super(include);
}
}
<强> Field2Adapter 强>
package forum13094195;
public class Field2Adapter extends FieldAdapter<Integer>{
public Field2Adapter() {}
public Field2Adapter(boolean include) {
super(include);
}
}
<强> Field3Adapter 强>
package forum13094195;
public class Field3Adapter extends FieldAdapter<String> {
public Field3Adapter() {}
public Field3Adapter(boolean include) {
super(include);
}
}
<强>商户强>
@XmlJavaTypeAdapter
注释用于在字段/属性上指定XmlAdapter
。
package forum13094195;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Merchant {
@XmlJavaTypeAdapter(Field1Adapter.class)
String field1;
@XmlJavaTypeAdapter(Field2Adapter.class)
int field2;
@XmlJavaTypeAdapter(Field3Adapter.class)
String field3;
}
<强>演示强>
下面的演示代码演示了如何在XmlAdapter
上设置有状态Marshaller
。
package forum13094195;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Merchant.class);
Merchant merchant = new Merchant();
merchant.field1 = "A";
merchant.field2 = 2;
merchant.field3 = "C";
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(merchant, System.out);
marshaller.setAdapter(new Field1Adapter(false));
marshaller.setAdapter(new Field2Adapter(false));
marshaller.setAdapter(new Field3Adapter(true));
marshaller.marshal(merchant, System.out);
}
}
<强>输出强>
以下是运行演示代码的输出。默认情况下,整个对象被编组出来。编组的第二个文档不包含我们排除的字段。
<?xml version="1.0" encoding="UTF-8"?>
<merchant>
<field1>A</field1>
<field2>2</field2>
<field3>C</field3>
</merchant>
<?xml version="1.0" encoding="UTF-8"?>
<merchant>
<field3>C</field3>
</merchant>
答案 1 :(得分:1)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。
在EclipseLink 2.5.0中,我们发布了一个名为Object Graphs的新功能,使您能够编组/解组映射字段/属性的子集。
// Create the Object Graph
ObjectGraph subset = JAXBHelper.getJAXBContext(jc).createObjectGraph(Merchant.class);
subset.addAttributeNodes("field1", "field1", "fieldN");
// Output XML - Based on Object Graph
marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, subset);
marshaller.marshal(customer, System.out);
了解更多信息