在使用 wsdl 文件生成的 soap 请求中自定义前缀和命名空间位置

Customizing prefix and namespace location in soap request generated using wsdl file

我很难理解为什么左侧的代码生成的 soap 请求不起作用,但如果我将其调整为右侧的内容,那么它就起作用了?

既然我知道需要做什么才能让它发挥作用,我该如何解决它?

我将 jaxws-maven-plugin 添加到我的 java 项目中:

     <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jaxws-maven-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                   <sourceDestDir>src/main/java</sourceDestDir>
                   <wsdlDirectory>src/main/resources/wsdl</wsdlDirectory>
                   <wsdlFiles>
                       <wsdlFile>Flattened_Integrator7.0.wsdl</wsdlFile>
                   </wsdlFiles>
                   <keep>true</keep>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>wsimport</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

注意上图中没有prefix wsse,是不行的。

一定是那个词。它存在于 wsdl 文件中。 有谁知道怎么做:

  1. 我可以将“http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”的 namespace prefix 强制为 wsse
  2. 强制代码在 soap envelope 而不是 Security 部分中生成命名空间

因此,我不得不手动将 prefix/namespace 添加到信封并将所有子项的前缀重命名为 wsse

这是我的做法:

@Component
public class RequestClient {

    private static final String WSSE_PREFIX = "wsse";
    private static final String WSSE_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
    private static final String NS2_PREFIX = "ns2";
    private static final String NS2_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";

    private buildSoaprequest(){
        ...
        SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
        soapEnvelope.addNamespaceDeclaration(WSSE_PREFIX, WSSE_NAMESPACE);
        soapEnvelope.addNamespaceDeclaration(NS2_PREFIX, NS2_NAMESPACE);
        SOAPHeader soapHeader = soapMessage.getSOAPHeader();
        removeUndesiredBodyNamespaceEntries(soapHeader.getChildElements());
        soapHeader.setPrefix(WSSE_PREFIX);
        addDesiredBodyNamespaceEntries(soapHeader.getChildElements());              
        soapMessage.saveChanges();
        ...
    }

    private void addDesiredBodyNamespaceEntries(Iterator childElements) {
        while (childElements.hasNext()) {
          final Object childElementNode = childElements.next();
          if (childElementNode instanceof SOAPElement) {
            SOAPElement soapElement = (SOAPElement) childElementNode;
            soapElement.setPrefix(WSSE_PREFIX); 
            addDesiredBodyNamespaceEntries(soapElement.getChildElements());
          }
        }
      }

    private void removeUndesiredBodyNamespaceEntries(Iterator childElements) {
        while (childElements.hasNext()) {
          final Object childElementNode = childElements.next();
          if (childElementNode instanceof SOAPElement) {
            SOAPElement soapElement = (SOAPElement) childElementNode;

            //remove any prefix/namespace entries added by JAX-WS in the body element
            //it cannot be null, so it will leave wsse
            for (String prefix : getNamespacePrefixList(soapElement.getNamespacePrefixes())) {
              if (prefix != null) {
                soapElement.removeNamespaceDeclaration(prefix);
              }
            }
            // recursively remove prefix/namespace entries in child elements
            removeUndesiredBodyNamespaceEntries(soapElement.getChildElements());
          }
        }
      }

     private Set<String> getNamespacePrefixList(Iterator namespacePrefixIter) {
        Set<String> namespacePrefixesSet = new HashSet<>();
        while (namespacePrefixIter.hasNext()) {
          namespacePrefixesSet.add((String) namespacePrefixIter.next());
        }
        return namespacePrefixesSet;
      }