网络服务模板:如何在网络服务模板中传递 headers

Webservice template : How to pass headers in webservice template

我在企业级使用以下 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 并将整个请求(包括 Headers 和 Body)传递给它

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 响应代码)。无论如何通过网络服务客户端分别传递 headers 和 body ?或者我们如何编组 headers?

无法在网络服务调用中分别传递 header 和 body。相反,有一些机制可以改变构造的消息,我们可以利用这些机制向 header 添加身份验证,也可以向 header 添加自定义元素。为此,我们需要额外的 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>

然后创建一个做auth的bean(这里,我给出一个基本auth的例子)

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