web-dev-qa-db-ja.com

名前空間と接頭辞を使用したJAXB非整列化

JAXBを使用してSOAP応答からのxml要素を解析しています。xml要素のPOJOクラスを定義しました。名前空間なしでpojoクラスをテストし、正常に機能するように接頭辞を付けました。名前空間とプレフィックスを使用して解析し、次の例外に直面します。要件は、SOAPMessageオブジェクトからの入力を解析することです

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Envelope"). Expected elements are <{}Envelope>

Package-info.Javaでパッケージの@XMLSchemaを作成して修正しようとし、このファイルをパッケージフォルダーに配置しました。

参照 この投稿は私を助けませんでした。

EDITED:XMLSchema

@javax.xml.bind.annotation.XmlSchema (
    xmlns = {  @javax.xml.bind.annotation.XmlNs(prefix = "env", 
                 namespaceURI="http://schemas.xmlsoap.org/soap/envelope/"),
      @javax.xml.bind.annotation.XmlNs(prefix="ns3", namespaceURI="http://www.xxxx.com/ncp/oomr/dto/")
    }
  )
package com.one.two;

前もって感謝します

16
gks

これは、標準のSOAPMessageクラスを使用して、生成されたJAXBコードを変更せずに実行できます。私はこれについて書きました ここここ

少し面倒ですが、正しく動作します。

マーシャリング

Farm farm = new Farm();
farm.getHorse().add(new Horse());
farm.getHorse().get(0).setName("glue factory");
farm.getHorse().get(0).setHeight(BigInteger.valueOf(123));

Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Marshaller marshaller = JAXBContext.newInstance(Farm.class).createMarshaller();
marshaller.marshal(farm, document);
SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
soapMessage.getSOAPBody().addDocument(document);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
soapMessage.writeTo(outputStream);
String output = new String(outputStream.toByteArray());

アンマーシャリング

String example =
        "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header /><soapenv:Body><ns2:farm xmlns:ns2=\"http://adamish.com/example/farm\"><horse height=\"123\" name=\"glue factory\"/></ns2:farm></soapenv:Body></soapenv:Envelope>";
SOAPMessage message = MessageFactory.newInstance().createMessage(null,
        new ByteArrayInputStream(example.getBytes()));
Unmarshaller unmarshaller = JAXBContext.newInstance(Farm.class).createUnmarshaller();
Farm farm = (Farm)unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());
17
Adam

これは、使用caeを処理する方法です。

Envelope要素をマップする必要がある場合

package-info

通常、次のように@XmlSchemaを使用します。これまでのようにnamespaceプロパティとelementFormDefaultプロパティを使用すると、XML要素にマップされたすべてのデータは、特にマップされていない限り、http://www.xxxx.com/ncp/oomr/dto/名前空間に属します。 xmlnsで指定される情報はXMLスキーマ生成用ですが、一部のJAXB実装はこれを使用して、マーシャリング時にネームスペースの優先プレフィックスを決定します(参照: http://blog.bdoughan.com/2011/ 11/jaxb-and-namespace-prefixes.html )。

@XmlSchema (
    namespace="http://www.xxxx.com/ncp/oomr/dto/",
    elementFormDefault=XmlNsForm.QUALIFIED,
    xmlns = {  
        @XmlNs(prefix = "env", namespaceURI="http://schemas.xmlsoap.org/soap/envelope/"),
        @XmlNs(prefix="whatever", namespaceURI="http://www.xxxx.com/ncp/oomr/dto/")
    }
  )
package com.one.two;

import javax.xml.bind.annotation.*;

封筒

com.one.two内でhttp://www.xxxx.com/ncp/oomr/dto/以外の名前空間の要素にマップする必要がある場合は、@XmlRootElementおよび@XmlElementアノテーションで指定する必要があります。

package com.one.two;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="Envelope", namespace="http://schemas.xmlsoap.org/soap/envelope/")
@XmlAccessorType(XmlAccessType.FIELD)
public class Envelope {

    @XmlElement(name="Body", namespace="http://schemas.xmlsoap.org/soap/envelope/")
    private Body body;

}

詳細情報

体をマッピングしたいだけなら

StAXパーサーを使用してメッセージを解析し、ペイロード部分に進み、そこからマーシャリングを解除できます。

import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;

public class UnmarshalDemo {

    public static void main(String[] args) throws Exception {
        XMLInputFactory xif = XMLInputFactory.newFactory();
        StreamSource xml = new StreamSource("src/blog/stax/middle/input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(xml);
        xsr.nextTag();
        while(!xsr.getLocalName().equals("return")) {
            xsr.nextTag();
        }

        JAXBContext jc = JAXBContext.newInstance(Customer.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        JAXBElement<Customer> jb = unmarshaller.unmarshal(xsr, Customer.class);
        xsr.close();
    }

}

詳細情報

15
bdoughan

既存の回答に追加したいだけです-XMLドキュメントが名前空間に対応していない場合は非整列化中に、次のエラーが発生する可能性があります:javax.xml.bind.UnmarshalException:予期しない要素(uri: " http:// some。 url ";, local:" someOperation ")

この場合は、アンマーシャラーで別のメソッドを使用するだけです。

Unmarshaller unmarshaller = JAXBContext.newInstance(YourObject.class).createUnmarshaller();
JAXBElement<YourObject> element = unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument(), YourObject.class);
YourObject yo = element.getValue();
2
ptdunlap