【问题标题】:Webservice template : How to pass headers in webservice templateWeb 服务模板:如何在 Web 服务模板中传递标头
【发布时间】:2020-06-22 07:07:36
【问题描述】:

我在企业级使用以下 SOAP 请求

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
      ....
  </soapenv:Header>
   <soapenv:Body>
<UserRQ xmlns="http://www.user.org/USER/INFO" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
  ...

为了使用邮递员(或其他)访问 API,我正在使用 WebServiceClient 并且当前将整个请求(包括标头和正文)传递给它

ApplicationClient.java

    public class ApplicationClient extends WebServiceGatewaySupport  {
       
        //Envelope is the whole request
        public ResponseEntity<String> getResults(Envelope envelope) {
            WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
            Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
            marshaller.setContextPath("org.test.wsdl");
            webServiceTemplate.setMarshaller(marshaller);
            webServiceTemplate.setUnmarshaller(marshaller);
          
            ResponseEntity<String> response = (ResponseEntity<String>) webServiceTemplate.marshalSendAndReceive("<URL>", envelope);
            log.info(response.getStatusCode());
            return response;
        }
    }
    

响应正确(得到 200 响应码)。无论如何通过Web服务客户端分别传递标头和正文?或者我们如何编组标题?

【问题讨论】:

    标签: java web-services soap soap-client webservice-client


    【解决方案1】:

    无法在 Web 服务调用中分别传递标头和正文。相反,有一些机制可以改变构造的消息,我们可以利用这些机制将身份验证添加到标头,也可以将自定义元素添加到标头。为此,我们需要额外的 spring-ws 依赖项。

    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-security</artifactId>
        <version>3.0.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-support</artifactId>
        <version>3.0.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.apache.wss4j</groupId>
        <artifactId>wss4j-parent</artifactId>
        <version>2.3.0</version>
        <type>pom</type>
    </dependency>
    

    然后创建一个进行身份验证的 bean(这里,我给出了一个基本身份验证的示例)

     @Bean
     public Wss4jSecurityInterceptor wsSecurityInterceptor() {
       Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
       wss4jSecurityInterceptor.setSecurementActions(WSHandlerConstants.USERNAME_TOKEN);
       wss4jSecurityInterceptor.setSecurementPasswordType(WSConstants.PW_TEXT);
       wss4jSecurityInterceptor.setSecurementUsername("abc");
       wss4jSecurityInterceptor.setSecurementPassword("xxxxxxxx");
       return wss4jSecurityInterceptor;
    }
    

    然后添加一个 WebServiceMessageCallback 实例来覆盖完成的消息,

    webServiceTemplate.marshalSendAndReceive(url, request, new CustomWebServiceMessageCallback());
    

    在CustomWebServiceMessageCallback里面,通过下面的方式,我们可以访问header并修改它。

    @Override
    public void doWithMessage(WebServiceMessage webServiceMessage) throws IOException, TransformerException {
       SoapMessage soapMessage = (SoapMessage) webServiceMessage;
       SoapHeader header = soapMessage.getSoapHeader();
       StringSource headerSource = new StringSource("<additional-header-element>HEADER_TEXT</additional-header-element>");
       Transformer transformer =   TransformerFactory.newInstance().newTransformer();
       transformer.transform(headerSource, header.getResult());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多