假设我们要构建一个简单的Web Service,可以接收两个整数并返回它们的和。我们将在本例中使用SOAP协议。
SOAP(Simple Object Access Protocol)是一种基于XML(eXtensible Markup Language)的简单协议,用于在Web应用程序之间进行交互。SOAP协议定义了一组规则和标准,用于在Web上编写分布式应用程序和服务。
SOAP协议主要用于Web Services,用于在不同的Web应用程序之间传递消息。它使用XML格式来编码消息,并使用HTTP或其他协议来传输消息。
SOAP协议的主要组成部分包括:
- Envelope(信封):用于定义消息的开始和结束。它还包含必需的各种属性和命名空间。
- Header(报头):可选的消息头,包含与消息相关的其他信息。
- Body(正文):包含实际数据或响应。
SOAP协议有以下特点:
- 标准化:SOAP协议是一个标准的Web服务协议,它使用标准的 XML格式来传输消息。
- 独立性:SOAP协议独立于任何特定的编程语言和平台,可用于在任何Web应用程序之间进行通信。
- 安全性:SOAP协议可以使用安全措施来保护消息的机密性和完整性。
- 扩展性:SOAP协议可以扩展以适应新的Web服务需求和通信协议。
尽管SOAP协议在Web Services中得到了广泛应用,但它可能存在一些性能问题,例如慢速和高网络开销。因此,许多Web Services使用REST(Representational State Transfer)来实现轻量级和快速的通信。
- 在pom.xml文件中添加以下依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.messaging.saaj</groupId>
<artifactId>saaj-impl</artifactId>
<version>1.5.1</version>
</dependency>
</dependencies>
- 创建一个包含两个参数的Java类,可以将它们相加并返回结果。
public class Calculator {
public int add(int a, int b) {
return a + b;
}
}
- 创建一个类来实现Web Service:
@Service
@WebService(serviceName = "CalculatorService")
public class CalculatorService {
@Autowired
private Calculator calculator;
@WebMethod(operationName = "add")
@WebResult(name = "result")
public int add(@WebParam(name = "a") int a, @WebParam(name = "b") int b) {
return calculator.add(a, b);
}
}
这里我们使用@Service注解来标记该类是一个服务,使用@WebService注解来定义服务的名称和命名空间。然后,我们定义了add()方法,该方法接收两个整数,并使用@Autowired注解将Calculator类自动注入到它内部。
- 创建一个应用程序类,将该类注入到Spring应用程序中:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public Calculator calculator() {
return new Calculator();
}
}
这里我们使用@SpringBootApplication注解来标记该类是一个Spring Boot应用程序,并使用@Bean注解来定义calculator()方法,该方法将实例化Calculator类并将其注入到应用程序上下文中。
- 配置消息调度器,并将Web Service端点指向该消息调度器:
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
@Bean
public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet() {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean<>(servlet, "/ws/*");
}
@Bean(name = "Calculator")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema calculatorSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("CalculatorPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://localhost:8080/calculator");
wsdl11Definition.setSchema(calculatorSchema);
return wsdl11Definition;
}
@Bean
public XsdSchema calculatorSchema() {
return new SimpleXsdSchema(new ClassPathResource("calculator.xsd"));
}
}
在这个例子中,我们定义了一个消息调度器,将其Web Service端点指向/ws/*路径。然后我们定义了一个服务bean,并将它指向我们的XSD模式。
- 定义XSD模式文件calculator.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://localhost:8080/calculator"
targetNamespace="http://localhost:8080/calculator"
elementFormDefault="qualified">
<xs:element name="addRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="a" type="xs:int"/>
<xs:element name="b" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="addResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="result" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
在这个XSD模式文件中,我们定义了一个addRequest元素和一个addResponse元素,这些元素将作为我们Web接口的输入和输出参数。
接口的输入和输出参数。
- 启动应用程序并通过URL访问WSDL定义:
http://localhost:8080/ws/calculator.wsdl
在浏览器中访问上述URL将能看到生成的WSDL定义,它将包含add操作和输入/输出元素。
- 使用SOAP客户端调用Web Service:
使用SOAP客户端来调用我们的Web服务。例如,可以使用Spring的WebServiceTemplate类,将SOAP消息发送到我们的服务端点,并接收响应。
public class SoapClient {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
WebServiceTemplate template = (WebServiceTemplate) context.getBean("webServiceTemplate");
AddRequest request = new AddRequest();
request.setA(10);
request.setB(20);
AddResponse response = (AddResponse) template.marshalSendAndReceive("http://localhost:8080/ws/calculator", request);
System.out.println(response.getResult()); // 输出结果为 30
}
}
这里我们使用ApplicationContext类获取WebServiceTemplate bean。接下来,创建一个AddRequest对象,并设置两个整数参数。再调用WebServiceTemplate的marshalSendAndReceive方法向我们的服务端点发送SOAP请求。最后,解析响应并输出结果。
这就是一个简单的Spring Boot + Web Service的示例!