您的位置:

Spring Boot调用Web Service接口

一、Spring Boot集成WebService

Web Service是一种跨平台、跨语言的远程调用技术,它实现了不同系统之间的互操作。

Spring Boot可以通过一个叫做JAX-WS的标准API来调用Web Service接口。

下面是一个简单的示例代码,在Spring Boot中引入JAX-WS依赖,并通过@WebServiceClient注解指定要调用的Web Service接口地址及命名空间:

@Configuration
public class WebServiceConfig {

    @Bean(name="helloWorld")
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema helloWorldSchema){
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("HelloWorldPort");
        wsdl11Definition.setTargetNamespace("http://spring.io/guides/gs-producing-web-service");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setSchema(helloWorldSchema);
        return wsdl11Definition;
    }

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

}

在Controller中通过@Autowired注入要调用的Web Service接口,然后就可以愉快地调用了:

@RestController
@RequestMapping("/api")
public class HelloWorldController {

    @Autowired
    private HelloWorldPortType helloWorldPortType;

    @GetMapping("/hello")
    public String sayHello() {
        String response = helloWorldPortType.sayHello("World");
        return response;
    }

}

二、指定Web Service接口方法

在一个Web Service接口中可能会有多个方法,我们可以通过@SOAPBinding注解的参数来指定要调用的方法:

@WebService(targetNamespace="http://spring.io/guides/gs-producing-web-service", name="HelloWorld")
@SOAPBinding(style=Style.RPC)
public interface HelloWorldPortType {

    @WebMethod(operationName="sayHello")
    String sayHello(@WebParam(name="arg0") String arg0);

    @WebMethod(operationName="getHelloWorldAsString")
    String getHelloWorldAsString();

}

注意上面的Web Service接口的注解,其中我们通过@SOAPBinding注解的style参数来指定为RPC模式。

三、传递复杂类型参数

有时候我们需要调用一个Web Service接口方法,需要传递一个复杂类型的参数。比如下面的Account类:

public class Account {

    private String accountNumber;

    private String accountHolderName;

    private String branch;

    private String location;

    // getter & setter

}

在Web Service接口中我们可以通过@XmlRootElement注解将Account类转换为XML格式:

@XmlRootElement
public class Account {

    private String accountNumber;

    private String accountHolderName;

    private String branch;

    private String location;

    // getter & setter

}

然后将Account类作为Web Service方法的参数:

public interface Bank {

    @WebMethod(operationName="getAccountDetails")
    AccountDetails getAccountDetails(@WebParam(name="account") Account account);

}

在调用Web Service接口方法时,我们同样需要将Account对象转换为XML格式。Spring Boot提供了一个JAXB2 Marshaller来完成这个任务:

@Configuration
public class WebServiceConfig {

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("com.example.wsdl.demo");
        return marshaller;
    }

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

}

然后就可以愉快地调用Web Service接口方法了:

@Service
public class BankService {

    private final SoapClient soapClient;

    @Autowired
    public BankService(SoapClient soapClient) {
        this.soapClient = soapClient;
    }

    public AccountDetails getAccountDetails(String accountNumber) {
        Account account = new Account();
        account.setAccountNumber(accountNumber);
        AccountDetails accountDetails = (AccountDetails) soapClient.callWebService("http://spring.io/guides/gs-producing-web-service", account);
        return accountDetails;
    }

}

四、使用Cxf客户端

除了上文提到的JAX-WS API外,Spring Boot还可以使用Apache CXF这个强大的Web Service框架来调用Web Service接口。

我们可以通过Maven引入如下两个依赖:

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
    <version>3.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>3.2.5</version>
</dependency>

然后就可以愉快地使用CXF客户端来调用Web Service接口了:

@Service
public class BankService {

    private final Bank bank;

    @Autowired
    public BankService(JaxWsProxyFactoryBean proxyFactoryBean) {
        this.bank = proxyFactoryBean.create(Bank.class);
    }

    public AccountDetails getAccountDetails(String accountNumber) {
        Account account = new Account();
        account.setAccountNumber(accountNumber);
        AccountDetails accountDetails = bank.getAccountDetails(account);
        return accountDetails;
    }

}

可以看到,在CXF客户端中我们可以直接通过Bank类来调用Web Service接口方法。