Spring WS WS-Addressing @Action Example

本文是转载,原文地址

http://memorynotfound.com/spring-ws-username-password-authentication-wss4j/

 

Spring WS WS-Addressing @Action Example

BY MEMORYNOTFOUND · MARCH 24, 2016

This example shows how to use Spring WS WS-Addressing to send and receive SOAP requests or responses. We are not covering the details what WS-Addressing is, there are numerous papers describing this in detail.

Spring WS WS-Addressing Server

The @Endpoint annotation tells spring that this class is eligible for handling soap requests. Next, we create a method and annotate it with @Action. The @Action annotation maps this method with a particular soap action described in ws-addressing. For simplicity the method returns a simple POJO.

package com.memorynotfound.server;

import com.memorynotfound.beer.*;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.springframework.ws.soap.addressing.server.annotation.Action;

@Endpoint
public class BeerEndpoint {

    @Action("http://memorynotfound.com/getBeerRequest")
    public @ResponsePayload GetBeerResponse getBeer(@RequestPayload GetBeerRequest request) {
        GetBeerResponse response = new GetBeerResponse();
        Beer beer = new Beer();
        beer.setId(request.getId());
        beer.setName("La Chouffe");
        response.setBeer(beer);
        return response;
    }

}
Resolve empty soapAction

We configure spring ws with java configuration. By default, the generated WSDL contains an empty soapAction. We can override this by mapping the soapActions with the appropriate properties using the DefaultWsdl11Definition.setSoapActions(soapActions) method.

package com.memorynotfound.server;

import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;
import java.util.Properties;

@EnableWs
@Configuration
public class SoapServerConfig extends WsConfigurerAdapter {

    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext appContext){
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(appContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean(servlet, "/ws/*");
    }

    @Bean(name = "beers")
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema schema){
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("BeersPort");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setTargetNamespace("http://meorynotfound.com/beer");
        wsdl11Definition.setSchema(schema);

        // fix for adding soapAction to the dynamic generated wsdl
        Properties soapActions = new Properties();
        soapActions.setProperty("getBeer", "http://memorynotfound.com/getBeerRequest");
        wsdl11Definition.setSoapActions(soapActions);
        return wsdl11Definition;
    }

    @Bean
    public XsdSchema beersSchema(){
        return new SimpleXsdSchema(new ClassPathResource("xsd/beers.xsd"));
    }

}

Finally, we bootstrap the application using spring boot. Running this will initialize and start the server. Next, we will implement the client to leverage the ws-addressing features.

package com.memorynotfound.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RunServer {

    public static void main(String[] args) {
        SpringApplication.run(RunServer.class);
    }

}

Spring WS WS-Addressing Client

Previously we created a server which is configured with Spring WS to handle WS-Addressing requests. Now we will configure a client to make the WS-Addressing enabled soap requests. We create a client by extending from the WebServiceGateWaySupport, this gives easy acces to the WebServiceTemplatewhich we’ll be using to send soap requests to the server. First we create an ActionCallback class and provide the action URI location. This location is registered in the server method and WSDL. Finally we send the request using the WebServiceTemplate and marshal and return the response.

package com.memorynotfound.client;

import com.memorynotfound.beer.*;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.soap.addressing.client.ActionCallback;
import java.net.URI;
import java.net.URISyntaxException;

public class BeerClient extends WebServiceGatewaySupport {

    public GetBeerResponse getBeer(int id) throws URISyntaxException {
        GetBeerRequest request = new GetBeerRequest();
        request.setId(id);

        ActionCallback callback = new ActionCallback(
                new URI("http://memorynotfound.com/getBeerRequest"));

        return (GetBeerResponse) getWebServiceTemplate()
                .marshalSendAndReceive(request, callback);
    }
}

To configure the client we also use spring java configuration. We create a marshaller for marshalling the request and responses to and from XML. We also initialize our client to make the actual requests to the server.

package com.memorynotfound.client;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

@Configuration
public class SoapClientConfig {

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("com.memorynotfound.beer");
        return marshaller;
    }

    @Bean
    public BeerClient beerClient(Jaxb2Marshaller marshaller) {
        BeerClient client = new BeerClient();
        client.setDefaultUri("http://localhost:8080/ws/beers");
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);
        return client;
    }

}

We obtain a reference to our client by initializing spring using the AnnotationConfigApplicationContext.

package com.memorynotfound.client;

import com.memorynotfound.beer.GetBeerResponse;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.net.URISyntaxException;

public class RunClient {

    public static void main(String[] args) throws URISyntaxException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SoapClientConfig.class);
        BeerClient client = context.getBean(BeerClient.class);
        GetBeerResponse response = client.getBeer(1);
        System.out.println(response);
    }

}

Demo

When we run the client, it produces the following request and response.

Example Request
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:To SOAP-ENV:mustUnderstand="1">http://localhost:8080/ws/beers</wsa:To>
      <wsa:Action>http://memorynotfound.com/getBeerRequest</wsa:Action>
      <wsa:MessageID>urn:uuid:853dacfa-40ad-4248-8767-5ae694834cf9</wsa:MessageID>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      <ns2:getBeerRequest xmlns:ns2="http://memorynotfound.com/beer">
         <ns2:id>1</ns2:id>
      </ns2:getBeerRequest>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Example Response
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:To SOAP-ENV:mustUnderstand="1">http://www.w3.org/2005/08/addressing/anonymous</wsa:To>
      <wsa:Action>http://memorynotfound.com/getBeerRequestResponse</wsa:Action>
      <wsa:MessageID>urn:uuid:aa12d10c-82fa-41b8-b6f9-cced508b685f</wsa:MessageID>
      <wsa:RelatesTo>urn:uuid:853dacfa-40ad-4248-8767-5ae694834cf9</wsa:RelatesTo>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      <ns2:getBeerResponse xmlns:ns2="http://memorynotfound.com/beer">
         <ns2:beer>
            <ns2:id>1</ns2:id>
            <ns2:name>La Chouffe</ns2:name>
         </ns2:beer>
      </ns2:getBeerResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

转载于:https://my.oschina.net/itwangxinli/blog/850468

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值