将JAXB元素编组为SOAP处理转义字符

时间:2018-11-01 20:24:27

标签: java soap encoding jaxb saaj

我试图将JAXB元素编组为SOAPBody包装器,我能够对JAXB中的编码字符进行转义,但是当我将其编组为SOAP文档时,它并没有转义这些xml字符。需要任何帮助。 >

我的项目很小,我们没有使用任何外部软件包,而是尝试在开放的jdk中进行此操作。

         package test;

        import java.io.File;
        import java.io.IOException;
        import java.io.OutputStreamWriter;
        import java.io.UnsupportedEncodingException;
        import java.io.Writer;

        import javax.xml.bind.JAXBContext;
        import javax.xml.bind.JAXBException;
        import javax.xml.bind.Marshaller;
        import javax.xml.soap.MessageFactory;
        import javax.xml.soap.SOAPBody;
        import javax.xml.soap.SOAPEnvelope;
        import javax.xml.soap.SOAPException;
        import javax.xml.soap.SOAPMessage;
        import javax.xml.soap.SOAPPart;

        import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;

        public class JAXBExample {
            public static void main(String[] args) throws SOAPException, IOException {

                Customer customer = new Customer();
                customer.setId(100);
                customer.setName("Hel..<..lo");
                customer.setAge(29);

                try {

                    MessageFactory messageFactory = MessageFactory.newInstance();
                    SOAPMessage soapMessage = messageFactory.createMessage();
                    SOAPPart soapPart = soapMessage.getSOAPPart();
                    SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
                    SOAPBody soapBody = soapEnvelope.getBody();
                    JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
                    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
                    // jaxbMarshaller.setProperty(CharacterEscapeHandler.class.getName(), new CustomCharacterEscapeHandler());
                    jaxbMarshaller.setProperty("com.sun.xml.internal.bind.characterEscapeHandler",
                            new CharacterEscapeHandler() {
                                public void escape(char[] ch, int start, int length, boolean isAttVal, Writer writer)
                                        throws IOException {
                                    writer.write(ch, start, length);
                                }
                            });


                    // output pretty printed
                    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                    jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

                    jaxbMarshaller.marshal(customer, System.out);
                    jaxbMarshaller.marshal(customer, soapBody);
                    soapMessage.saveChanges();
                    soapMessage.writeTo(System.out);

                }
                catch (JAXBException e) {
                    e.printStackTrace();
                }

            }
        }


 // result just with jaxb ***
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <customer id="100">
        <payload><![CDATA[Hel..<..lo]]></payload>
        <age>29</age>
        <name>Hel..<..lo</name>
    </customer>
// result jaxb wrapped into SOAPbody***
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/>
    <SOAP-ENV:Body>
    <customer id="100">
    <payload>&lt;![CDATA[Hel..&lt;..lo]]&gt;</payload><age>29</age><name>Hel..&lt;..lo</name></customer>
    </SOAP-ENV:Body></SOAP-ENV:Envelope>

3 个答案:

答案 0 :(得分:0)

jsonObj.forEach(async(data)=>{ try { var result = await collections.collection('studentData').find({rollNumber:parseInt(data.rollNumber)}).toArray() console.log('--------data---------') if (result[0]) { course.push(result[0].course) branch.push(result[0].branch) console.log('-------- entry object ----------') await collections.collection('something').insertOne(something,(err,res)=>{if (err){console.log(err)}else {console.log('inserted')}}) } else { console.log('not inserted') } } catch (e) { console.log(e) } } ) var title = 'Result is out' var body = 'Result of' + reqs.body.company console.log('-------------branch and course--------------') console.log(branch) console.log(course) Marshaller.JAXB_ENCODING属性仅在编组到流时有效,而在编组到DOM时无效。如果希望在最终结果中使用CDATA节,最好让JAXB正常封送数据,然后再对DOM进行后处理,将文本节点更改为所需的CDATA节。

答案 1 :(得分:0)

您可以使用Apache StringEscapeUtils。由于我不知道您的客户类别是什么样子,因此我仅构建一个简单的示例,请参见下面的类别。结果看起来像这样:

soapMessage.writeTo(System.out);

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;
            &amp;lt;customer&amp;gt;
            &amp;lt;id&amp;gt;123&amp;amp;lt;&amp;amp;gt;&amp;amp;amp;g&amp;lt;/id&amp;gt;
            &amp;lt;name&amp;gt;Hello&amp;lt;/name&amp;gt;
            &amp;lt;lastname&amp;gt;World*+;:-&amp;amp;lt;&amp;amp;gt;&amp;amp;amp;%$&amp;lt;/lastname&amp;gt;
            &amp;lt;/customer&amp;gt;
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

System.out.println(StringEscapeUtils.unescapeXml(soapBody.getValue()));

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <customer>
    <id>123&lt;&gt;&amp;g</id>
    <name>Hello</name>
    <lastname>World*+;:-&lt;&gt;&amp;%$</lastname>
</customer>

专家

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.6</version>
</dependency>

Main.java

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import java.io.*;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import org.apache.commons.text.StringEscapeUtils;

public class Main {
    private static final Logger log = LogManager.getLogger(Main.class);

    public static void main(String[] args) {
        try {
            Customer customer = new Customer().setID("123<>&g").setName("Hello").setLastname("World*+;:-<>&%$");
            MessageFactory messageFactory = MessageFactory.newInstance();
            SOAPMessage soapMessage = messageFactory.createMessage();
            SOAPPart soapPart = soapMessage.getSOAPPart();
            SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
            SOAPBody soapBody = soapEnvelope.getBody();

            JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            // output pretty printed
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

            StringWriter sw = new StringWriter();
            jaxbMarshaller.marshal(customer, sw);

            soapBody.setValue(StringEscapeUtils.escapeXml11(sw.toString()));

            soapMessage.saveChanges();
            soapMessage.writeTo(System.out);
            System.out.println("\r\n\r\n-----\r\n\r\n");
            System.out.println(StringEscapeUtils.unescapeXml(soapBody.getValue()));
        } catch(Exception e) {
            log.error("no! ", e);
        }

        log.info("stop");
    }
}

Customer.java

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
    @XmlElement(name="id")
    private String id;
    @XmlElement(name="name")
    private String name;
    @XmlElement(name="lastname")
    private String lastname;

    public String getID() {
        return this.id;
    }

    public Customer setID(String value) {
        this.id = value;
        return this;
    }

    public String getName() {
        return this.name;
    }

    public Customer setName(String value) {
        this.name = value;
        return this;
    }

    public String getLastname() {
        return this.lastname;
    }

    public Customer setLastname(String value) {
        this.lastname = value;
        return this;
    }
}

答案 2 :(得分:0)

好吧,如果没有apache转义工具,那么(丑陋的)解决方法如何。 基本上,您将其编组两次,然后切下所需的部分并将其直接设置在肥皂主体上,请参见下面的示例。

soapMessage.writeTo(System.out);

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>&amp;lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&amp;gt;
        &amp;lt;customer&amp;gt;
        &amp;lt;id&amp;gt;Hello &amp;amp;lt;&amp;amp;gt;&amp;amp;amp;g World*+;:-&amp;amp;lt;&amp;amp;gt;&amp;amp;amp;%$&amp;lt;/id&amp;gt;
        &amp;lt;/customer&amp;gt;
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Main.java

public class Main {
    private static final Logger log = LogManager.getLogger(Main.class);

    public static void main(String[] args) {
        try {
            Customer customer = new Customer().setID("Hello <>&g World*+;:-<>&%$");
            String xml = marshall(new Workaround().setID(marshall(customer)));
            xml = xml.substring(0, xml.indexOf("</id>"));
            xml = xml.substring(xml.indexOf("<id>") + 4);
            System.out.println("\r\n\r\nxml:\r\n" + xml);


            MessageFactory messageFactory = MessageFactory.newInstance();
            SOAPMessage soapMessage = messageFactory.createMessage();
            SOAPPart soapPart = soapMessage.getSOAPPart();
            SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
            SOAPBody soapBody = soapEnvelope.getBody();
            soapBody.setValue(xml);

            System.out.println("\r\n\r\nsoap:");
            soapMessage.writeTo(System.out);
        } catch (Exception e) {
            log.error("no! ", e);
        }

        log.info("stop");
    }

    public static String marshall(Object o) throws Exception {
        System.out.println("-------------------");
        StringWriter sw = new StringWriter();
        JAXBContext jaxbContext = JAXBContext.newInstance(o.getClass());
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        jaxbMarshaller.marshal(o, System.out);
        jaxbMarshaller.marshal(o, sw);

        return sw.toString();
    }
}

Customer.java

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
    @XmlElement(name="id")
    private String id;

    public String getID() {
        return this.id;
    }

    public Customer setID(String value) {
        this.id = value;
        return this;
    }
}

替代方法.java

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="workaround")
@XmlAccessorType(XmlAccessType.FIELD)
public class Workaround {
    @XmlElement(name="id")
    private String id;

    public String getID() {
        return this.id;
    }

    public Workaround setID(String value) {
        this.id = value;
        return this;
    }
}