Java 将JAXB元素封送到SOAP处理转义字符中
我正在尝试将JAXB元素封送到SOAPBody包装器中,我能够转义JAXB中的编码字符,但是当我将其封送到SOAP文档中时,它并没有转义这些xml字符。需要帮助吗?提前感谢 我的项目很小,我们没有使用任何外部包,试图在开放jdk中实现这一点Java 将JAXB元素封送到SOAP处理转义字符中,java,soap,encoding,jaxb,saaj,Java,Soap,Encoding,Jaxb,Saaj,我正在尝试将JAXB元素封送到SOAPBody包装器中,我能够转义JAXB中的编码字符,但是当我将其封送到SOAP文档中时,它并没有转义这些xml字符。需要帮助吗?提前感谢 我的项目很小,我们没有使用任何外部包,试图在开放jdk中实现这一点 package test; import java.io.File; import java.io.IOException; import java.io.OutputStreamWrite
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><![CDATA[Hel..<..lo]]></payload><age>29</age><name>Hel..<..lo</name></customer>
</SOAP-ENV:Body></SOAP-ENV:Envelope>
封装测试;
导入java.io.File;
导入java.io.IOException;
导入java.io.OutputStreamWriter;
导入java.io.UnsupportedEncodingException;
导入java.io.Writer;
导入javax.xml.bind.JAXBContext;
导入javax.xml.bind.JAXBException;
导入javax.xml.bind.Marshaller;
导入javax.xml.soap.MessageFactory;
导入javax.xml.soap.SOAPBody;
导入javax.xml.soap.SOAPEnvelope;
导入javax.xml.soap.SOAPException;
导入javax.xml.soap.SOAPMessage;
导入javax.xml.soap.SOAPPart;
导入com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;
公共类JAXBE示例{
公共静态void main(字符串[]args)引发SOAPException、IOException{
客户=新客户();
customer.setId(100);
customer.setName("Hel..Marshaller.JAXB_ENCODING
和com.sun.xml.internal.bind.characterEscapeHandler
属性仅在编组到流时有效,但在编组到DOM时无效。如果您希望在最终结果中包含CDATA部分,则最好让JAXB正常编组数据,然后对数据进行后期处理OM,将文本节点更改为需要的CDATA节。您可以使用apache StringEscapeUtils。由于我不知道您的客户类是什么样子,我只构建了一个快速示例,请参见下面的类。结果如下所示:
soapMessage.writeTo(System.out);
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;customer&gt;
&lt;id&gt;123&amp;lt;&amp;gt;&amp;amp;g&lt;/id&gt;
&lt;name&gt;Hello&lt;/name&gt;
&lt;lastname&gt;World*+;:-&amp;lt;&amp;gt;&amp;amp;%$&lt;/lastname&gt;
&lt;/customer&gt;
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
<id>123<>&g</id>
<name>Hello</name>
<lastname>World*+;:-<>&%$</lastname>
</customer>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;customer&gt;
&lt;id&gt;Hello &amp;lt;&amp;gt;&amp;amp;g World*+;:-&amp;lt;&amp;gt;&amp;amp;%$&lt;/id&gt;
&lt;/customer&gt;
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
好吧,如果没有ApacheScape UTIL,那么(丑陋的)解决方法如何呢。 基本上,您将其马歇尔两次,然后切掉您需要的部分,并将其直接设置到您的soap主体,请参见下面的示例 soapMessage.writeTo(System.out);
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;customer&gt;
&lt;id&gt;123&amp;lt;&amp;gt;&amp;amp;g&lt;/id&gt;
&lt;name&gt;Hello&lt;/name&gt;
&lt;lastname&gt;World*+;:-&amp;lt;&amp;gt;&amp;amp;%$&lt;/lastname&gt;
&lt;/customer&gt;
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
<id>123<>&g</id>
<name>Hello</name>
<lastname>World*+;:-<>&%$</lastname>
</customer>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;customer&gt;
&lt;id&gt;Hello &amp;lt;&amp;gt;&amp;amp;g World*+;:-&amp;lt;&amp;gt;&amp;amp;%$&lt;/id&gt;
&lt;/customer&gt;
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Workaround.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");
}
}
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;
}
}
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();
}
}
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;
}
}
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;
}
}
感谢您的回复,很遗憾我不能使用Apache字符串utils。