删除JAX-WS消息中的XML声明 [英] Removing XML declaration in JAX-WS message
问题描述
我正在尝试使用Java代码调用Web服务. 因此,我使用JAX-WS和JAXB从wsdl文件生成对象.
I'm trying to invoke a webservice using Java code. So I used JAX-WS and JAXB to generate my object from wsdl file.
当我调用Web服务时,它会以以下错误响应:
When I invoke the webservice it respond with this error:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: The [javax.xml.transform.TransformerException] occurred during XSLT transformation: javax.xml.transform.TransformerException: org.xml.sax.SAXParseException: The XML declaration must end with "?>".
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: The [javax.xml.transform.TransformerException] occurred during XSLT transformation: javax.xml.transform.TransformerException: org.xml.sax.SAXParseException: The XML declaration must end with "?>".
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:189)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:122)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)
因此,我用Wireshark分析了正在发送的xml消息.并尝试使用soapUI重新发送.
So with wireshark I analysed the xml message that is being sent. And tried to resend it with soapUI.
发现我的xml包含xml声明
And found out that my xml contains the xml declaration
<?xml version='1.0' encoding='UTF-8'?>
当我从SoapUI删除它并重新发送它时.消息正常.
When I remove it from SoapUI and resend it. The message goes ok.
我的Java代码如下:
My java code goes like this:
public static Data receiveSIBS(webserviceclient.Data input) {
webserviceclient.Starter service = new webserviceclient.Starter();
webserviceclient.PortType port = service.getSOAPEventSource();
BindingProvider bp = (BindingProvider) port;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
return port.receiveSIBS(input);
}
在没有此xml声明的情况下,如何用Java生成消息? 因为xml消息都是使用 JAX-WS 和 JAXB 生成的.
How can I generate my message in Java without this xml declaration? because the xml message is all generated with JAX-WS and JAXB.
感谢进阶!
推荐答案
找到了自己的解决方案!
Found my own solution!
首先,如其他文章所述,我实现了一个SOAPHandler来编辑这两个属性:
First, as referred in other post, I implemented a SOAPHandler to edit this two properties:
soapMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-16");
soapMsg.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "false");
但是,尽管这两个属性更改了handleMessage()方法中的消息实例,但它不会像这样发送,并且会发送带有默认xml声明的消息.
But although this two properties change message instance inside handleMessage() method, it won't be sent like it, and message with default xml declaration is sent.
代替设置此属性,解决方案是设置这两个NamespaceDeclaration:
Instead of setting this properties the solution was to set this two NamespaceDeclaration:
SOAPEnvelope env = sp.getEnvelope();
env.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
env.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
我不明白为什么会收到"XML声明必须以?>"结尾的错误.因为我的解决方案没有删除xml声明.可能与xml结构有关(但是我没有足够的知识来确认它).
I don't understand why we get "The XML declaration must end with "?>"" error. Because my solution didn't removed xml declaration. Might be related to xml structure (but I don't have enough knowledge to confirm it).
我需要引用 http://blog.jdevelop.eu/?p=67让我介绍此解决方案的帖子,而一些调试代码则来自此帖子.
I need to refer http://blog.jdevelop.eu/?p=67 post that let me to this solution, and some debug code is from this post.
下面,我放置了完整的CustomHandler类,以便它可以容纳任何人.
Following I put my complete CustomHandler class so it can held anyone.
import java.io.ByteArrayOutputStream;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
/**
*
* @author Daniel Chang Yan
*/
public class CustomHandler implements SOAPHandler<SOAPMessageContext> {
public boolean handleMessage(SOAPMessageContext context) {
Boolean isOutbound
= (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (isOutbound != null && isOutbound) {
SOAPMessage soapMsg = context.getMessage();
try {
//Properties always rewritten by jaxws, no matter what is set here
//soapMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-16");
//soapMsg.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "false");
// get SOAP-Part
SOAPPart sp = soapMsg.getSOAPPart();
//edit Envelope
SOAPEnvelope env = sp.getEnvelope();
env.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
env.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
} catch (SOAPException e) {
throw new RuntimeException(e);
}
// print SOAP-Message
System.out.println("Direction=outbound (handleMessage)...");
dumpSOAPMessage(soapMsg);
} else {
// INBOUND
System.out.println("Direction=inbound (handleMessage)...");
SOAPMessage msg = ((SOAPMessageContext) context).getMessage();
dumpSOAPMessage(msg);
}
return true;
}
public Set<QName> getHeaders() {
return null;
}
public boolean handleFault(SOAPMessageContext context) {
System.out.println("ServerSOAPHandler.handleFault");
boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outbound) {
System.out.println("Direction=outbound (handleFault)...");
} else {
System.out.println("Direction=inbound (handleFault)...");
}
if (!outbound) {
try {
SOAPMessage msg = ((SOAPMessageContext) context).getMessage();
dumpSOAPMessage(msg);
if (context.getMessage().getSOAPBody().getFault() != null) {
String detailName = null;
try {
detailName = context.getMessage().getSOAPBody().getFault().getDetail().getFirstChild().getLocalName();
System.out.println("detailName=" + detailName);
} catch (Exception e) {
}
}
} catch (SOAPException e) {
e.printStackTrace();
}
}
return true;
}
public void close(MessageContext mc) {
}
/**
* Dump SOAP Message to console
*
* @param msg
*/
private void dumpSOAPMessage(SOAPMessage msg) {
if (msg == null) {
System.out.println("SOAP Message is null");
return;
}
//System.out.println("");
System.out.println("--------------------");
System.out.println("DUMP OF SOAP MESSAGE");
System.out.println("--------------------");
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
msg.writeTo(baos);
System.out.println(baos.toString(getMessageEncoding(msg)));
// show included values
String values = msg.getSOAPBody().getTextContent();
System.out.println("Included values:" + values);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Returns the message encoding (e.g. utf-8)
*
* @param msg
* @return
* @throws javax.xml.soap.SOAPException
*/
private String getMessageEncoding(SOAPMessage msg) throws SOAPException {
String encoding = "utf-8";
if (msg.getProperty(SOAPMessage.CHARACTER_SET_ENCODING) != null) {
encoding = msg.getProperty(SOAPMessage.CHARACTER_SET_ENCODING).toString();
}
return encoding;
}
}
这篇关于删除JAX-WS消息中的XML声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!