web-dev-qa-db-ja.com

Jaxbが作成したXMLに<![CDATA [および]]>を追加する方法

CDATAを使用してXMLを準備する方法、

私はJaxbを介してこの応答を事前に作成しています。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
 <SOAP-ENV:Header/>
 <soapenv:Body>
   <tem:RequestData>
     <tem:requestDocument>
        <![CDATA[
        <Request>
           <Authentication CMId="68" Function="1" Guid="5594FB83-F4D4-431F-B3C5-EA6D7A8BA795" Password="poihg321TR"/>
           <Establishment Id="4297867"/>
        </Request>
        ]]>
      </tem:requestDocument>
   </tem:RequestData>
 </soapenv:Body>
 </soapenv:Envelope>  

しかし、JaxbからCDATAを取得していません。CDATAを<tem:requestDocument>要素内に配置する方法。

これが私のJavaコード:

  public static String test1() {
    try {
        initJB();
        String response = null;
        StringBuffer xmlStr = null;
        String strTimeStamp = null;
        com.cultagent4.travel_republic.gm.Envelope envelope = null;
        com.cultagent4.travel_republic.gm.Header header = null;
        com.cultagent4.travel_republic.gm.Body body = null;
        com.cultagent4.travel_republic.gm.RequestData requestData = null;
        com.cultagent4.travel_republic.gm.RequestDocument requestDocument = null;
        com.cultagent4.travel_republic.gm.RequestDocument.Request request = null;
        com.cultagent4.travel_republic.gm.RequestDocument.Request.Authentication authentication = null;
        com.cultagent4.travel_republic.gm.RequestDocument.Request.Establishment establishment = null;

        ObjectFactory objFact = new ObjectFactory();
        envelope = objFact.createEnvelope();
        header = objFact.createHeader();
        envelope.setHeader(header);
        body = objFact.createBody();
        requestData = objFact.createRequestData();


        requestDocument = objFact.createRequestDocument();
        request = new RequestDocument.Request();

        authentication = new RequestDocument.Request.Authentication();
        authentication.setCMId("68");
        authentication.setGuid("5594FB83-F4D4-431F-B3C5-EA6D7A8BA795");
        authentication.setPassword("poihg321TR");
        authentication.setFunction("1");
        request.setAuthentication(authentication);
        establishment = new RequestDocument.Request.Establishment();
        establishment.setId("4297867");
        request.setEstablishment(establishment);
        requestDocument.setRequest(request);
        requestData.setRequestDocument(requestDocument);
        body.setRequestData(requestData);
        envelope.setBody(body);



        jaxbMarshallerForBase = jaxbContextForBase.createMarshaller();
        OutputStream os = new ByteArrayOutputStream();


        System.out.println();
        // output pretty printed

//                jaxbMarshallerForBase.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//                jaxbMarshallerForBase.marshal(envelope, System.out);
//                jaxbMarshallerForBase.marshal(envelope, os);


        jaxbMarshallerForBase.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        jaxbMarshallerForBase.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//            jaxbMarshallerForBase.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
// get an Apache XMLSerializer configured to generate CDATA
        XMLSerializer serializer = getXMLSerializer();


// marshal using the Apache XMLSerializer
        SAXResult result = new SAXResult(serializer.asContentHandler());

         System.out.println("*************");
        jaxbMarshallerForBase.marshal(envelope, result);
        System.out.println("--------------");



        return null;
    } catch (JAXBException ex) {
        Logger.getLogger(GM_TravelRepublic.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        return null;
    }
}

private static XMLSerializer getXMLSerializer() {
    // configure an OutputFormat to handle CDATA
    OutputFormat of = new OutputFormat();

    // specify which of your elements you want to be handled as CDATA.
    // The use of the ; '^' between the namespaceURI and the localname
    // seems to be an implementation detail of the xerces code.
    // When processing xml that doesn't use namespaces, simply omit the
    // namespace prefix as shown in the third CDataElement below.
    of.setCDataElements(new String[]{"^Request","^Authentication","^Establishment"});


    // set any other options you'd like
   of.setPreserveSpace(true);
    of.setIndenting(true);


    StringWriter writer = new StringWriter();
    // create the serializer
    XMLSerializer serializer = new XMLSerializer(of);


    serializer.setOutputByteStream(System.out);


    return serializer;
}  

ここでは同じxmlを取得していますが、CDATAはありません。私のサーバーはCDATAなしでリクエストを受け付けていません。助けてください。

11
LMK
  1. XMLAdapterクラスを拡張するカスタムアダプタクラスを作成する必要があります。

インポートjavax.xml.bind.annotation.adapters.XmlAdapter;

パブリッククラスCDATAAdapterはXmlAdapterを拡張します{

@Override
public String marshal(String inStr) throws Exception {
    return "<![CDATA[" + inStr + "]]>";
}

@Override
public String unmarshal(String v) throws Exception {
    return inStr;
}

}

  1. Java BeanまたはPOJO内で、CDATAで必要な文字列にXMLJavaTypeAdapterを定義します

    @XmlJavaTypeAdapter(value = CDATAAdapter.class)プライベート文字列メッセージ。

  2. デフォルトでは、JAXBRIのマーシャラー実装は文字をエスケープしようとします。この動作を変更するには、CharacterEscapeHandlerを実装するクラスを作成します。

このインターフェイスには、オーバーライドする必要のあるエスケープメソッドがあります。

インポートcom.Sun.xml.internal.bind.marshaller.CharacterEscapeHandler;

m.setProperty("com.Sun.xml.internal.bind.characterEscapeHandler",
                new CharacterEscapeHandler() {
                    @Override
                    public void escape(char[] ch, int start, int length,
                            boolean isAttVal, Writer writer)
                            throws IOException {
                        writer.write(ch, start, length);
                    }
                });

次に、EclipseMOXyの実装を介して実行することもできます。

5
Ashu

これからロジックを作れますか

輸入

import org.dom4j.CDATA;
import org.dom4j.DocumentHelper;

サンプルコード

public static String appendCdata(String input) {
    CDATA cdata = DocumentHelper.createCDATA(input);      
    return cdata.asXML();
}
4
user2130460

CDATAは文字データであり、サーバーがRequestで始まるXMLの一部をテキストとして入力することを望んでいるようです。 XmlAdapterのインスタンスをRequestに変換するには、Stringを作成するだけで十分な場合があります。結果の文字はCDATAではエスケープされませんが、これはユースケースに適合する可能性があります。

次に、XmlAdapterに加えてCDATAとして本当に必要な場合は、以下のリンクで説明されている戦略の1つを適用できます。

1
bdoughan

サーバーは、_<tem:requestDocument>_要素ではなくtextを含むことを_<Request>_に期待しています。 CDATAは、手書きのXMLを作成するのに本当に役立つので、埋め込まれたXMLをエスケープすることを心配する必要はありません。問題は、[〜#〜] jaxb [〜#〜]エスケープを適切に処理し、サーバーが適切なXML市民である場合は、適切にエスケープされたXMLをCDATAブロック。

したがって、request要素をrequestDocument内に追加する代わりに、に:

_requestDocument = objFact.createRequestDocument();
request = new RequestDocument.Request();

...
requestDocument.setRequest(request);
_

最初にJAXBを使用してrequestを適切にエスケープされた文字列にマーシャリングし、thatsarequestDocument値:

_requestDocument = objFact.createRequestDocument();
request = new RequestDocument.Request();

...
String escapedRequest = marshal(request);
requestDocument.setRequest(escapedRequest);
_

marshal(request)の実装は演習として残されています。 ;)

0
Edward Samson

private static XMLSerializer getXMLSerializer()メソッドでCDATA要素を間違って設定していると思います。これは、CDATA要素がコンテンツであるRequestAuthenticationEstablishmentではなく<tem:requestDocument>であるためです。試してみてください:

of.setCDataElements(new String[]{"tem^requestDocument","http://tempuri.org/^requestDocument","requestDocument"});

の代わりに:

of.setCDataElements(new String[]{"^Request","^Authentication","^Establishment"});

お役に立てれば、

0
albciff

Apacheドキュメントの setCDataElementsメソッドの説明 から:

Sets the list of elements for which text node children should be output as CDATA.

つまり、これが機能するためには、tem:requestDocument要素の子がすべて1つの単一テキストチャンクの一部である必要があります(xml要素自体ではありません)。あなたがそれをしたら、おそらく簡単です

of.setCDataElements(new String[]{"tem^requestDocument"});

トリックを行う必要があります。

それを試して、私に知らせてください:)

0