Camel XStream unmarshall 属性为空

Camel XStream unmarshall attributes are null

我正在使用 Apache Camel 使用一些 XML 文件。
问题是当它处理文件的属性时,值总是空的...
我写了一些单元测试来确定我的 XML 文件是有效的,但 Camel 仍然出错...

这是我的路线:

Namespaces ns = new Namespaces("ns", "http://www.vaudoise.ch/b2b/gm/interchange");
    from(source).marshal().string("ISO-8859-1").log("body = ${body}")
    .setHeader("fileName").simple("${header.CamelFileRelativePath}")
    .setHeader("lotId").xpath("//ns:documents//@T_demandeLotID", String.class, ns)
    .setHeader("typeDoc").xpath("//ns:documents//@T_demandeTypeDoc", String.class, ns)
    .setHeader("source").xpath("//ns:documents//@T_demandeSource", String.class, ns)
    .setHeader("time").xpath("//ns:documents//@T_demandeTimestamp", String.class, ns)
    .split().xpath("//ns:documents/ns:document",ns).log(" splited body  = ${body}")
    .unmarshal(new XStreamDataFormat(FichierService.getOrCreateXStream())).log("body after unmarshal ${body}")
    .transform(method(event)).to(BATCHCORE_INJECTOR);

FichierService.getOrCreateXStream() return 一个这样的 XStream 实例:

  public static XStream getOrCreateXStream() {
    if (XSTREAM == null) {
      QNameMap qname = new QNameMap();
      qname.setDefaultNamespace(XMLNS);
      XmlFriendlyNameCoder replacer = new XmlFriendlyNameCoder("-", "_");
      StaxDriver staxDriver = new StaxDriver(qname, replacer);
      XSTREAM = new XStream(staxDriver);
      XSTREAM.processAnnotations(new Class[] { DocumentEnteteDto.class, 
                                                DocumentDto.class, 
                                                ReferenceDto.class,
                                                ObjetMetierDto.class, 
                                                ObjetMetierSinistreDto.class,
                                                ObjetMetierAnnonceDto.class,
                                                ObjetMetierContratDto.class,
                                                ObjetMetierFactureDto.class,
                                                ObjetMetierMutationDto.class});
      XSTREAM.registerConverter(new DateConverter("yyyy-MM-dd'T'HH:mm:ss", new String[] { "yyyy-MM-dd",
          "yyyy-MM-dd'T'HH:mm:ss" }));
      XSTREAM.registerConverter(new JodaDateConverter());
      XSTREAM.registerConverter(BooleanConverter.BINARY);
    }
    return XSTREAM;
  }

当我在 XStream classes 中逐步进行时,我看到来自 class AbstractReflectionConverter 的方法 doUnmarshall 的指令 Object value = converter.fromString(reader.getAttribute(attrAlias)); 总是 returnnull

这是我要使用的 XML 文件的示例:

<?xml version='1.0' encoding='ISO-8859-1'?>
<documents xmlns="http://www.xxx.yyy/b2b/gm/interchange" 
        T_demandeLotID="2" 
        T_demandeTypeDoc="Sinistre" 
        T_demandeSource="ST_PROG" 
        T_demandeTimestamp="2015-02-13T07:23:23">

        <document>
            <references 
                D_refSequence="132" 
                D_refContratVA="001213456.3100" 
                D_refPreneurVA="00123456" 
                D_refSinistreVA="1000012345" 
                D_refContratGM="123-GA-456" 
                D_refPreneurGM="123456" 
                D_refSinistreGM="12345678"/>

            <objetMetier>
                <sinistre 
                    S_sinistreEtat="S" 
                    S_sinistreAcceptation="1" 
                    S_sinistreDateSurv="2015-02-01" 
                    S_sinistreDevise="CHF" 
                    S_sinistreDescriptif="Vol d'un velo" 
                    S_sinistreDateLiquidation="2015-01-01">

                    <gestionnaire 
                        S_gestionnaireNom="nom" 
                        S_gestionnairePrenom="prenom" 
                        S_gestionnaireTel="tel" 
                        S_gestionnaireEmail="mail"/>
                </sinistre>
            </objetMetier>
        </document>
    </documents>

我发现了我的问题!

这是因为属性名称中的 _...XStream 将它们用作转义字符...我不知道为什么我的单元测试很好,但 Camel 却没有。
为了解决这个问题,我不得不创建两种实例XStream。一个用于编组,一个用于使用不同类型的 XmlFriendlyNameCoder 解组:

 public static XStream getOrCreateXStreamToUnmarshall(){
    if(XSTREAM_TO_UNMARSHALL != null){
      return XSTREAM_TO_UNMARSHALL;
    }
    XmlFriendlyNameCoder replacer = new XmlFriendlyNameCoder("-", "");
    return createXStream(XSTREAM_TO_UNMARSHALL, replacer);
  }

  public static XStream getOrCreateXStreamToMarshall() {
    if(XSTREAM_TO_MARSHALL != null){
      return XSTREAM_TO_MARSHALL;
    }
    XmlFriendlyNameCoder replacer = new XmlFriendlyNameCoder("-", "_");
    return createXStream(XSTREAM_TO_MARSHALL, replacer);
  }

  private static XStream createXStream(XStream xSTreamToInitialize, XmlFriendlyNameCoder encoder){
    QNameMap qname = new QNameMap();
    qname.setDefaultNamespace(XMLNS_VAUDOISE);
    StaxDriver staxDriver = new StaxDriver(qname, encoder);
    xSTreamToInitialize = new XStream(staxDriver);
    xSTreamToInitialize.processAnnotations(new Class[] { DocumentEnteteDto.class, 
      DocumentDto.class, 
      ReferenceDto.class,
      ObjetMetierDto.class, 
      ObjetMetierSinistreDto.class,
      ObjetMetierAnnonceDto.class,
      ObjetMetierContratDto.class,
      ObjetMetierFactureDto.class,
      ObjetMetierMutationDto.class});
    xSTreamToInitialize.registerConverter(new DateConverter("yyyy-MM-dd'T'HH:mm:ss", new String[] { "yyyy-MM-dd",
    "yyyy-MM-dd'T'HH:mm:ss" }));
    xSTreamToInitialize.registerConverter(new JodaDateConverter());
    xSTreamToInitialize.registerConverter(BooleanConverter.BINARY);
    return xSTreamToInitialize;
  }