2017-07-28 3 views
0

Ich versuche, ein SOAPHandler auf meinem Server-Setup Dieser eingehenden AnfrageSOAPHandler: Wie automatisch hinzugefügt Namespace/Attribut aus geordnetes Elemente entfernen

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

auf diese Anforderung zu konvertieren.

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

Mein SOAPHandler sieht wie folgt aus.

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

} 

Nach der Bearbeitung des Antrags mit dem SOAPHandler sieht die Anfrage wie folgt aus:

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

Wie Sie ich bin in der Lage sehen das Namespacepräfix zum <getMachine> Tag hinzuzufügen, aber es dann Fügt dem untergeordneten Element <machineId> automatisch das Attribut xmlns hinzu. Wie kann ich dies vermeiden oder beheben?

Antwort

0

Nachdem ich mit der API herumgespielt habe, kam ich auf diese Lösung. Dies löst den beschriebenen Fall.

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

} 
Verwandte Themen