2008-09-15 25 views
6

我正在接收來自使用Axis 1.4庫的客戶端的SOAP請求。這些請求具有以下形式:如何讓Axis 1.4不爲相同的XML名稱空間生成多個前綴?

<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> 
[...] 

正如您所看到的,爲相同的命名空間定義了若干個前綴,例如,命名空間http://example.com/schema/common的前綴爲ns4,ns5,ns6,ns7和ns8。一些長請求爲相同的名稱空間定義了幾百個前綴。

這導致了我用來轉換請求的XSLT處理器的Saxon問題。撒克遜將相同名稱空間的不同前綴數量限制爲255,並在定義更多前綴時引發異常。

Can Axis 1.4可以配置爲定義更智能的前綴,以便每個名稱空間只有一個前綴?

+1

我有完全相同的問題。我會密切關注這個話題。 – 2008-10-07 17:19:14

回答

3

我有同樣的問題。目前,我通過編寫一個BasicHandler擴展來解決這個問題,然後自己遍歷SOAPPart並將名稱空間引用移動到一個父節點。我沒有這種解決方案,但它似乎工作。

我真的希望有人過來告訴我們我們該做什麼。

編輯

這是太複雜了,就像我說的,我不喜歡它,但在這裏我們去。我實際上把功能分成了幾個類(這不是我們在該項目中需要做的唯一操作,所以還有其他實現),我真的希望有人能夠儘快解決這個問題。這使用dom4j來處理通過SOAP過程的XML,因此您需要dom4j才能使其工作。

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

沒有擔保,等等,等等

1

改變客戶的WSDD設置enableNamespacePrefixOptimizationtrue

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

這是記錄在任何地方嗎?我想要一個我能做些什麼來配置客戶端的清單,最好不要閱讀實際的源代碼。 – 2008-10-09 20:53:06

2

對於請求我使用它來刪除命名空間類型:

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 }); 
相關問題