2008-09-15 6 views
6

Ich erhalte SOAP-Anforderungen von einem Client, der die Axis 1.4-Bibliotheken verwendet. Die Anforderungen haben die folgende Form:Wie kann ich Axis 1.4 dazu bringen, mehrere Präfixe für denselben XML-Namespace nicht zu generieren?

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <soapenv:Body> 
    <PlaceOrderRequest xmlns="http://example.com/schema/order/request"> 
     <order> 
     <ns1:requestParameter xmlns:ns1="http://example.com/schema/common/request"> 
      <ns1:orderingSystemWithDomain> 
      <ns1:orderingSystem>Internet</ns1:orderingSystem> 
      <ns1:domainSign>2</ns1:domainSign> 
      </ns1:orderingSystemWithDomain> 
     </ns1:requestParameter> 
     <ns2:directDeliveryAddress ns2:addressType="0" ns2:index="1" 
            xmlns:ns2="http://example.com/schema/order/request"> 
      <ns3:address xmlns:ns3="http://example.com/schema/common/request"> 
      <ns4:zipcode xmlns:ns4="http://example.com/schema/common">12345</ns4:zipcode> 
      <ns5:city xmlns:ns5="http://example.com/schema/common">City</ns5:city> 
      <ns6:street xmlns:ns6="http://example.com/schema/common">Street</ns6:street> 
      <ns7:houseNum xmlns:ns7="http://example.com/schema/common">1</ns7:houseNum> 
      <ns8:country xmlns:ns8="http://example.com/schema/common">XX</ns8:country> 
      </ns3:address> 
[...] 

Wie Sie sehen können, sind mehrere Präfixe für den gleichen Namensraum definiert, z.B. Der Namespace http://example.com/schema/common hat die Präfixe ns4, ns5, ns6, ns7 und ns8. Einige lange Anfragen definieren mehrere hundert Präfixe für denselben Namensraum.

Das verursacht ein Problem mit dem Saxon XSLT-Prozessor, den ich verwende, um die Anforderungen zu transformieren. Saxon begrenzt die Anzahl unterschiedlicher Präfixe für denselben Namespace auf 255 und löst eine Ausnahme aus, wenn Sie weitere Präfixe definieren.

Kann Axis 1.4 konfiguriert werden, um intelligentere Präfixe zu definieren, so dass nur ein Präfix für jeden Namespace existiert?

+1

Ich habe genau das gleiche Problem. Ich werde diesen Thread genau beobachten. –

Antwort

3

Ich habe das gleiche Problem. Im Moment habe ich daran gearbeitet, indem ich eine BasicHandler-Erweiterung geschrieben habe und dann das SOAPPart selbst durchlaufen und den Namespace-Verweis auf einen übergeordneten Knoten verschoben habe. Ich nicht wie diese Lösung, aber es scheint zu funktionieren.

Ich hoffe wirklich, dass jemand kommt und uns sagt, was wir zu tun haben.

EDIT

Das ist viel zu kompliziert, und wie ich schon sagte, ich es nicht mögen, aber hier gehen wir. Ich habe die Funktionalität in ein paar Klassen aufgeteilt (das war nicht die einzige Manipulation, die wir in diesem Projekt machen mussten, also gab es andere Implementierungen) Ich hoffe wirklich, dass jemand das bald beheben kann. Dies verwendet dom4j, um den XML-Prozess zu verarbeiten, der den SOAP-Prozess durchläuft. Daher benötigen Sie dom4j, damit es funktioniert.

public class XMLManipulationHandler extends BasicHandler { 
private static Log log = LogFactory.getLog(XMLManipulationHandler.class); 
private static List processingHandlers; 

public static void setProcessingHandlers(List handlers) { 
    processingHandlers = handlers; 
} 

protected Document process(Document doc) { 
    if (processingHandlers == null) { 
     processingHandlers = new ArrayList(); 
     processingHandlers.add(new EmptyProcessingHandler()); 
    } 
    log.trace(processingHandlers); 
    treeWalk(doc.getRootElement()); 
    return doc; 
} 

protected void treeWalk(Element element) { 
    for (int i = 0, size = element.nodeCount(); i < size; i++) { 
     Node node = element.node(i); 
     for (int handlerIndex = 0; handlerIndex < processingHandlers.size(); handlerIndex++) { 
      ProcessingHandler handler = (ProcessingHandler) processingHandlers.get(handlerIndex); 
      handler.process(node); 
     } 
     if (node instanceof Element) { 
      treeWalk((Element) node); 
     } 
    } 
} 

public void invoke(MessageContext context) throws AxisFault { 
    if (!context.getPastPivot()) { 
     SOAPMessage message = context.getMessage(); 
     SOAPPart soapPart = message.getSOAPPart(); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

     try { 
      message.writeTo(baos); 
      baos.flush(); 
      baos.close(); 

      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 
      SAXReader saxReader = new SAXReader(); 
      Document doc = saxReader.read(bais); 
      doc = process(doc); 
      DocumentSource ds = new DocumentSource(doc); 
      soapPart.setContent(ds); 
      message.saveChanges(); 
     } catch (Exception e) { 
      throw new AxisFault("Error Caught processing document in XMLManipulationHandler", e); 
     } 
    } 
} 

} 


public interface ProcessingHandler { 
    public Node process(Node node); 
} 


public class NamespaceRemovalHandler implements ProcessingHandler { 
private static Log log = LogFactory.getLog(NamespaceRemovalHandler.class); 
private Namespace namespace; 
private String targetElement; 
private Set ignoreElements; 

public NamespaceRemovalHandler() { 
    ignoreElements = new HashSet(); 
} 

public Node process(Node node) { 
    if (node instanceof Element) { 
     Element element = (Element) node; 
     if (element.isRootElement()) { 
      // Evidently, we never actually see the root node when we're called from 
      // SOAP... 
     } else { 
      if (element.getName().equals(targetElement)) { 
       log.trace("Found the target Element. Adding requested namespace"); 
       Namespace already = element.getNamespaceForURI(namespace.getURI()); 
       if (already == null) { 
        element.add(namespace); 
       } 
      } else if (!ignoreElements.contains(element.getName())) { 
       Namespace target = element.getNamespaceForURI(namespace.getURI()); 
       if (target != null) { 
        element.remove(target); 
        element.setQName(new QName(element.getName(), namespace)); 
       } 
      } 
      Attribute type = element.attribute("type"); 
      if (type != null) { 
       log.trace("Replacing type information: " + type.getText()); 
       String typeText = type.getText(); 
       typeText = typeText.replaceAll("ns[0-9]+", namespace.getPrefix()); 
       type.setText(typeText); 
      } 
     } 
    } 

    return node; 
} 

public Namespace getNamespace() { 
    return namespace; 
} 

public void setNamespace(Namespace namespace) { 
    this.namespace = namespace; 
} 

/** 
* @return the targetElement 
*/ 
public String getTargetElement() { 
    return targetElement; 
} 

/** 
* @param targetElement the targetElement to set 
*/ 
public void setTargetElement(String targetElement) { 
    this.targetElement = targetElement; 
} 

/** 
* @return the ignoreElements 
*/ 
public Set getIgnoreElements() { 
    return ignoreElements; 
} 

/** 
* @param ignoreElements the ignoreElements to set 
*/ 
public void setIgnoreElements(Set ignoreElements) { 
    this.ignoreElements = ignoreElements; 
} 

public void addIgnoreElement(String element) { 
    this.ignoreElements.add(element); 
} 
} 

Keine Garantie, etc, etc.

1

Ihres Kunden WSDD Alter enableNamespacePrefixOptimization zu true

<globalConfiguration > 
    <parameter name="enableNamespacePrefixOptimization" value="true"/> 
+0

Ist das irgendwo dokumentiert? Ich hätte gerne eine gute Liste, was ich tun kann, um den Client zu konfigurieren, vorzugsweise ohne den eigentlichen Quellcode zu lesen. –

+0

Ich habe diesen Parameter gefunden, indem ich durch ein altes Projekt geschaut habe. Funktioniert es? –

2

für die Anforderung ich diese Typen entfernen Namespaces zu setzen:

String endpoint = "http://localhost:5555/yourService"; 

// Parameter to be send 
Integer secuencial = new Integer(11); // 0011 

// Make the call 
Service service = new Service(); 

Call call = (Call) service.createCall(); 

// Disable sending Multirefs 
call.setOption(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, new java.lang.Boolean(false)); 

// Disable sending xsi:type 
call.setOption(org.apache.axis.AxisEngine.PROP_SEND_XSI, new java.lang.Boolean(false)); 

// XML with new line 
call.setOption(org.apache.axis.AxisEngine.PROP_DISABLE_PRETTY_XML, new java.lang.Boolean(false)); 

// Other Options. You will not need them 
call.setOption(org.apache.axis.AxisEngine.PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION, new java.lang.Boolean(true)); 
call.setOption(org.apache.axis.AxisEngine.PROP_DOTNET_SOAPENC_FIX, new java.lang.Boolean(true)); 

call.setTargetEndpointAddress(new java.net.URL(endpoint)); 
call.setSOAPActionURI("http://YourActionUrl");//Optional 

// Opertion Name 
//call.setOperationName("YourMethod"); 
call.setOperationName(new javax.xml.namespace.QName("http://yourUrl", "YourMethod"));  

// Do not send encoding style 
call.setEncodingStyle(null); 

// Do not send xmlns in the xml nodes 
call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE); 

/////// Configuration of namespaces 
org.apache.axis.description.OperationDesc oper; 
org.apache.axis.description.ParameterDesc param; 
oper = new org.apache.axis.description.OperationDesc(); 
oper.setName("InsertaTran"); 
param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("http://yourUrl", "secuencial"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "int"), int.class, false, false); 
oper.addParameter(param); 

oper.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "int")); 
oper.setReturnClass(int.class); 
oper.setReturnQName(new javax.xml.namespace.QName("http://yourUrl", "yourReturnMethod")); 
oper.setStyle(org.apache.axis.constants.Style.WRAPPED); 
oper.setUse(org.apache.axis.constants.Use.LITERAL); 

call.setOperation(oper); 

Integer ret = (Integer) call.invoke(new java.lang.Object [] 
      { secuencial }); 
Verwandte Themen