简体   繁体   中英

Removing XML declaration in JAX-WS message

I'm trying to invoke a webservice using Java code. So I used JAX-WS and JAXB to generate my object from wsdl file.

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)

So with wireshark I analysed the xml message that is being sent. And tried to resend it with soapUI.

And found out that my xml contains the xml declaration

<?xml version='1.0' encoding='UTF-8'?>

When I remove it from SoapUI and resend it. The message goes ok.

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);
}

How can I generate my message in Java without this xml declaration? because the xml message is all generated with JAX-WS and JAXB .

Thanks in advanced!

Found my own solution!

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");

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.

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");

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).

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.

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;
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM