簡體   English   中英

SOAPHandler:如何從子元素中刪除自動添加的名稱空間/屬性

[英]SOAPHandler: How to remove automatically added namespace/attribute from child element

我正在嘗試在服務器上設置SOAPHandler來轉換此傳入請求

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <getMachine xmlns="http://machine.soap.webservices.product.company.at/">
            <machineId>92623-15853588</machineId>
        </getMachine>
    </S:Body>
</S:Envelope>

對此請求。

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <enns1:getMachine xmlns:enns1="http://machine.soap.webservices.product.company.at/">
            <machineId>92623-15853588</machineId>
        </enns1:getMachine>
    </S:Body>
</S:Envelope>

我的SOAPHandler看起來像這樣。

package at.company.product.webservices.soap;

import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class SOAPValidationHandler implements SOAPHandler<SOAPMessageContext> {

    private static final String PREFIX = "enns1";

    @Override
    public boolean handleMessage(SOAPMessageContext context) {

        System.out.println("Server : handleMessage()......");

        Boolean isRequest = (Boolean) context
                .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        // inbound
        if (!isRequest) {

            try {
                SOAPMessage soapMsg = context.getMessage();

                SOAPBody body = soapMsg.getSOAPBody();
                Iterator<SOAPElement> it = body.getChildElements();

                // Look for all body elements who have a "xmlns" attribute and
                // add a namespace prefix to it
                while (it.hasNext()) {

                    SOAPElement elem = it.next();
                    addNamespacePrefix(elem);

                    Iterator itChildren = elem.getChildElements();

                    while (itChildren.hasNext()) {
                        Object child = itChildren.next();

                        if (child instanceof SOAPElement) {
                            SOAPElement cElem = ((SOAPElement) child);

                            // TODO: Remove the namespace from the child
                            // cElem.removeNamespaceDeclaration(""); => Does not
                            // work
                        }
                    }

                }

                // tracking
                soapMsg.writeTo(System.out);

            } catch (SOAPException e) {
                System.err.println(e);
            } catch (IOException e) {
                System.err.println(e);
            }
        }

        return true;
    }

    private void addNamespacePrefix(SOAPElement elem) throws SOAPException {
        Iterator<Object> it = elem.getAllAttributes();

        QName name = new QName("xmlns");
        String value = elem.getAttributeValue(name);

        if (value != null) {
            elem.addNamespaceDeclaration(PREFIX, elem.getNamespaceURI());
            elem.removeNamespaceDeclaration("");
            elem.setPrefix(PREFIX);
        }

    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        System.out.println("Server : handleFault()......");
        return true;
    }

    @Override
    public void close(MessageContext context) {
        System.out.println("Server : close()......");
    }

    @Override
    public Set<QName> getHeaders() {
        System.out.println("Server : getHeaders()......");
        return null;
    }

}

在使用SOAPHandler處理請求之后,請求看起來像這樣:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <enns1:getMachine xmlns:enns1="http://machine.soap.webservices.product.company.at/">
             <machineId xmlns="http://machine.soap.webservices.product.company.at/">92623-15853588</machineId>
        </enns1:getMachine>
    </S:Body>
</S:Envelope>

如您所見,我能夠將名稱空間前綴添加到<getMachine>標記中,但是隨后它會自動將xmlns屬性添加到子元素<machineId> 如何避免或解決此問題?

在研究了API之后,我想到了這個解決方案。 這解決了所描述的情況。

package at.company.product.webservices.soap;

import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.ws.soap.SOAPFaultException;

public class SOAPValidationHandler implements SOAPHandler<SOAPMessageContext> {

    private static final String PREFIX = "enns1";

    @Override
    public boolean handleMessage(SOAPMessageContext context) {


        Boolean isRequest = (Boolean) context
                .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        // for response message only, true for outbound messages, false for
        // inbound
        if (!isRequest) {

            try {
                SOAPMessage soapMsg = context.getMessage();
                SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();
                SOAPHeader soapHeader = soapEnv.getHeader();

                // if no header, add one
                if (soapHeader == null) {
                    soapHeader = soapEnv.addHeader();
                    // throw exception
                    generateSOAPErrMessage(soapMsg, "No SOAP header.");
                }

                SOAPBody body = soapMsg.getSOAPBody();
                Iterator<SOAPElement> it = body.getChildElements();

                while (it.hasNext()) {
                    SOAPElement elem = it.next();
                    addNamespacePrefix(elem);


                    Iterator itChildChildren = elem.getChildElements();
                    while (itChildChildren.hasNext()) {
                        Object obj = itChildChildren.next();
                        if ((obj instanceof SOAPElement)) {
                            SOAPElement soapElem = (SOAPElement) obj;
                            String name = soapElem.getElementName().getLocalName();

                            QName qName = new QName(name);
                            ((SOAPElement) obj).setElementQName(qName);
                        }
                    }
                }

                // tracking
                soapMsg.writeTo(System.out);

            } catch (SOAPException e) {
                System.err.println(e);
            } catch (IOException e) {
                System.err.println(e);
            }

        }

        // continue other handler chain
        return true;
    }

    private void addNamespacePrefix(SOAPElement elem) throws SOAPException {
        Iterator<Object> it = elem.getAllAttributes();

        QName name = new QName("xmlns");
        String value = elem.getAttributeValue(name);

        if (value != null) {
            elem.addNamespaceDeclaration(PREFIX, elem.getNamespaceURI());
            elem.removeNamespaceDeclaration("");
            elem.setPrefix(PREFIX);
        }

    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return true;
    }

    @Override
    public void close(MessageContext context) {
    }

    @Override
    public Set<QName> getHeaders() {
        return null;
    }

    private void generateSOAPErrMessage(SOAPMessage msg, String reason) {
        try {
            SOAPBody soapBody = msg.getSOAPPart().getEnvelope().getBody();
            SOAPFault soapFault = soapBody.addFault();
            soapFault.setFaultString(reason);
            throw new SOAPFaultException(soapFault);
        } catch (SOAPException e) {
        }
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM