2

我正在使用 JAXB 和 RestEasy。

我从一个需要具有的 xml 文件返回一个 Comprobante.class(JAXB 生成的类):

<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd">...</cfdi:Comprobante>

我在包声明中有这个:

@XmlSchema(
    location = "http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd",
    namespace = "http://www.sat.gob.mx/cfd/3",
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
    attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED,

    xmlns={
        @XmlNs(
                prefix="cfdi",
                namespaceURI="http://www.sat.gob.mx/cfd/3"
                ),
        @XmlNs(
                prefix="xsi",
                namespaceURI="http://www.w3.org/2001/XMLSchema-instance"
                )
        }) 

但是从 XML 文件解组到 JAXB 类的结果没有:

xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd"

它只打印

<cfdi:Comprobante 
xmlns:cfdi="http://www.sat.gob.mx/cfd/3" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">..</cfdi:Comprobante>

我的代码是:

File p = new File(servletContext.getRealPath("/")+factura.getXml().getCfdi());

JAXBContext context = JAXBContext.newInstance("foo.bar.Model.CFDIv32");
Unmarshaller u = context.createUnmarshaller();

return (foo.bar.Comprobante) u.unmarshal(p);

我如何告诉 JAXB Unmarshaller 放置 xsi:schemaLocation="" 属性。

谢谢你。

编辑:我是如何解决的

看我自己的答案

4

1 回答 1

2

Rest easy 具有 JAXB 装饰器,因此您可以在编组之前添加到编组器属性。

1.- 创建一个装饰处理器

@DecorateTypes({"application/xml"})
public class NameSpaceProcesor implements DecoratorProcessor<Marshaller, CustomMarshaller> {

/* Override method</br>
 * @see org.jboss.resteasy.spi.interception.DecoratorProcessor#decorate(java.lang.Object, java.lang.annotation.Annotation, java.lang.Class, java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType)
 */
@Override
public Marshaller decorate(Marshaller target, CustomMarshaller arg1,
        @SuppressWarnings("rawtypes") Class arg2, Annotation[] arg3, MediaType arg4) {
    try {
        target.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        target.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,"http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd");
    } catch (PropertyException e) {
    }
    return target;
}
}

2.- 创建您的装饰注释。

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Decorator(processor = NameSpaceProcesor.class, target = Marshaller.class)
public @interface CustomMarshaller {}

3.- 然后用装饰器注释你的方法。

    @GET
@CustomMarshaller
@Path("cfdi")
@Produces({"application/xml", "application/json"})
// /consulta/cfdi?uuid=0a7da89b-a328-4e54-9666-e1a3d7a10b0a
public Comprobante cfdi(...){}

希望这对其他人有帮助。

于 2013-11-05T23:35:39.580 回答