2

我已经使用 Spring-WS 创建了 Web 服务。当我向 Web 服务发送请求时,这是我在 soap-ui 中得到的响应:

enter code here
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns2:SendResponse xmlns:ns2="http://mycompany.com/schema/">
         <ns2:SendResult>
            <ns2:Token>A00179-02</ns2:Token>
         </ns2:SendResult>
      </ns2:SendResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

有什么办法可以摆脱响应中的“ns2”命名空间前缀?我尝试了几个选项:1)手动更新 package-info.java 将前缀设置为“”:

@XmlSchema(namespace = "http://mycompany.com/schema/",  
    xmlns = {   
        @XmlNs(namespaceURI = "http://mycompany.com/schema/", prefix = "")  
    },  
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)  

package com.example.foo.jaxb; 

2)在端点类的QName对象中设置前缀为“”:

return new JAXBElement<SendAndCommitResponse>(new QName("http://mycompany.com/schema/",
"SendResponse",""), SendResponse.class, response);

两者都没有工作。如何摆脱“ns2”命名空间前缀?

4

4 回答 4

2

我最终找到了解决方案。

我的问题是由于 JDK 6 没有提供完整版本的 rt.jar ( http://www.oracle.com/technetwork/java/javase/compatibility-137541.html )。

我将以下内容添加到我的 Maven 配置中

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.6</version>
</dependency>

然后添加

@XmlSchema(namespace = "http://mycompany.com/schema/", 
   elementFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED).

在 package-info.java 中(就像上面的@acdcjunior 建议的那样)

于 2013-06-25T20:16:02.263 回答
2

我尝试了这里讨论的一些方法,但没有任何效果......

链接中的以下课程 - https://zhuanlan.zhihu.com/p/35298171解决了我的问题

添加了以下拦截器以删除命名空间 -

public class PayloadPrefixInterceptor extends TransformerHelper implements EndpointInterceptor {

    public static final String NAMESPACE = ObjectFactory.class.getPackage().getAnnotation(XmlSchema.class).namespace();
    public static final String XMLNS = "xmlns:";

    @Override
    public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
        return true;
    }

    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
        WebServiceMessage response = messageContext.getResponse();
        Source payloadSource = response.getPayloadSource();
        DOMResult result = new DOMResult();
        transform(payloadSource, result);
        removePrefix(result.getNode());
        transform(new DOMSource(result.getNode()), response.getPayloadResult());
        return true;
    }

    private void removePrefix(Node node) {
        if (node == null) {
            return;
        }

        if (node.getNodeType() == Node.ELEMENT_NODE) {
            removeNamespaceDeclaration(node);
        }
        if (node.getPrefix() != null) {
            node.setPrefix(null);
        }
        NodeList childNodes = node.getChildNodes();
        if (childNodes != null) {
            IntStream.of(0, childNodes.getLength()).forEach(index -> removePrefix(childNodes.item(index)));
        }
        Node nextSibling = node.getNextSibling();
        if (nextSibling != null) {
            removePrefix(nextSibling);
        }
    }

    private void removeNamespaceDeclaration(Node node) {
        NamedNodeMap attributes = node.getAttributes();
        IntStream.range(0, attributes.getLength()).forEach(index -> {
            Node attribute = attributes.item(index);
            if (StringUtils.startsWith(attribute.getNodeName(), XMLNS) &&
                    StringUtils.equals(attribute.getNodeValue(), NAMESPACE)) {
                attributes.removeNamedItemNS(attribute.getNamespaceURI(), attribute.getLocalName());
            }
        });
    }

    @Override
    public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
        return true;
    }

    @Override
    public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {
    }
}

使用以下注册拦截器 -

@EnableWs
@Configuration
public class Config extends WsConfigurerAdapter {

    @Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {
        interceptors.add(new PayloadPrefixInterceptor());
        super.addInterceptors(interceptors);
    }

}
于 2019-06-19T05:29:10.270 回答
0

那个挺难

首先:创建一个拦截soap请求和响应的类:

package examples.webservices.handler;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
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 org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class CorrigirConteudoRequisicaoSOAP implements SOAPHandler<SOAPMessageContext> {
    public Set<QName> getHeaders() {
        return Collections.emptySet();
    }

    public boolean handleMessage(SOAPMessageContext messageContext) {
        this.corrigirConteudoRequisicaoSOAP(messageContext);
        return true;
    }

    private void corrigirConteudoRequisicaoSOAP(SOAPMessageContext messageContext){
        SOAPMessage msg = messageContext.getMessage();
        try {
            NodeList childNodes = msg.getSOAPBody().getChildNodes();

            for(int k = 0; k < childNodes.getLength(); k++){
                Node item = childNodes.item(k);
                String localName = item.getLocalName();
                {
                    item.setPrefix("");
                    Method m = SOAPElement.class.getDeclaredMethod("setElementQName", QName.class);
                    //I was forced to use reflection because the method setElementQname is not //visible, neither the class that implements it
                    m.invoke(item, new QName("", item.getLocalName()));
                    msg.saveChanges();
                }

            }
        } catch (Exception e) {
            try {
                msg.writeTo(System.out);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            System.out.println();
        }
    }

    public boolean handleFault(SOAPMessageContext messageContext) {
        return true;
    }

    public void close(MessageContext messageContext) {
    }

    public static void main(String[] args)throws Exception {
    }
}

第二:将服务关联到肥皂句柄

public class PortalFornecedor {

    public Usuario getUsuario(){
        XIF367Afae09A3344Fbf2E1De819D6EcbaService classeComNomeFeio = new XIF367Afae09A3344Fbf2E1De819D6EcbaService();

        Usuario service = classeComNomeFeio.getHTTPPort();
        BindingProvider bp = (BindingProvider)service;
        Map<String, Object> requestContext = bp.getRequestContext();
        requestContext.put(BindingProvider.USERNAME_PROPERTY, "user");
        requestContext.put(BindingProvider.PASSWORD_PROPERTY, "pass");
        this.handle(service);
        return service;
    }

    public Object getDashboard(){
        return "";
    }
    // here we associate the service to soap handle
    private BindingProvider handle(Usuario service) {
        BindingProvider bp = (BindingProvider)service;
        @SuppressWarnings("rawtypes")
        List<Handler> chain = new ArrayList<Handler>();
        chain.add(new CorrigirConteudoRequisicaoSOAP());
        bp.getBinding().setHandlerChain(chain);
        return bp;
    }

    public static void main(String[] args) {

        PortalFornecedor pf = new PortalFornecedor();
        Usuario usuario = pf.getUsuario();
        LoginExecutarIN in = new LoginExecutarIN();
        generated.Usuario user = new generated.Usuario();
        user.setLogin("onias");
        user.setSenha("12345");
        user.setCodigoUsuario(0);
        in.setParametroEntrada(user);
        try {
            LoginExecutarOUT out = usuario.loginExecutar(in);
            // SOAPMessageContext.getMessage();

            System.out.println(out.getRegistroSelecionado().getNome());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
于 2014-12-11T23:59:42.207 回答
0

这是该问题的简单和最简单的解决方案。在您的模型包中创建 Package-Info.Java 文件并将以下脚本添加到该文件中。

@javax.xml.bind.annotation.XmlSchema(namespace = "http://mycompany.com/schema", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = { @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://mycompany.com/schema", prefix = "") })
package my.com.scicom.stars.model;

并在您的 xsd 或 wsdl 文件中将 elementFormDefault 添加为“合格”。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://mycompany.com/schema"
           targetNamespace="http://mycompany.com/schema"
           elementFormDefault="qualified">
于 2020-10-03T04:26:05.473 回答