jax-rs响应实体不是xmlroot,而是一个元素

时间:2013-02-22 00:03:27

标签: jaxb jax-rs

我有一个JAX-RS响应方法

@Produces('application/xml', 'application/json')

我还有一个生成这个的JAX-B实体:

<person>
    <name>joe</name>
    <address>
        <street>123 home</street>
    </address>
<person>

此次通话/person/Joe

我想回复/person/joe/address

并返回

  <address>
       <street>123 home</street>
  </address>

使用JAX-RS / Jersey我收到错误:

  当mime类型为application / XML

时,

没有类型为Address.class的编组器

这种情况正在发生,因为地址对象未注释为@XMLRootElement

2 个答案:

答案 0 :(得分:0)

您可以使用Address注释@XmlRootElement类,或将其包装在JAXBElement的实例中。

new JAXBElement<Address>(
    new QName("address"), 
    Address.class, 
    address);

答案 1 :(得分:0)

我已经编写了一个简单的提供程序来处理这种情况,它看起来像我预期的那样工作。它会将xmlType包装在jaxbelement中,以便可以编组。

/**
 * by default we are unable to write an {@link XmlType} object as xml it must be
 * an {@link XmlRootElement} based object this class will wrap {@link XmlType}
 * with {@link JAXBElement} and marshall them
 * 
 * @author shaun
 * 
 */
@Provider
@Consumes({ "application/xml", "text/xml" })
public class XMLTypeWriter extends AbstractRootElementProvider {

    private static final Logger logger = LoggerFactory.getLogger(XMLTypeWriter.class);

    public XMLTypeWriter(@Context Providers ps) {
        super(ps, MediaType.APPLICATION_XML_TYPE);
    }

    @Override
    protected boolean isSupported(MediaType m) {
        return (m.equals(MediaType.APPLICATION_XML_TYPE) || m.equals(MediaType.TEXT_XML_TYPE));
    }

    @Override
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        // There is already a xmltype reader defined.
        return false;
    }

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return type.isAnnotationPresent(XmlType.class) && isSupported(mediaType);
    }

    @Override
    protected void writeTo(Object t, MediaType mediaType, Charset c, Marshaller m, OutputStream entityStream) throws JAXBException {

        // need to get the type name from the annotation
        XmlType xt = t.getClass().getAnnotation(XmlType.class);
        JAXBElement p = null;
        if (xt != null) {
            String name = xt.name();
            p = new JAXBElement(QName.valueOf(name), t.getClass(), t);
        }
        super.writeTo(p, mediaType, c, m, entityStream);
    }
}