前言
Web Services 是特殊的网络服务,它允许位于不同地点的计算机程序通过互联网交流和共享数据。这些服务可以通过多种方式实现,其中包括使用SOAP协议和遵循REST原则。
在SOAP的实现中,Spring Web Services(Spring WS)和Java API for XML Web Services(JAX-WS)是两种主要的技术选择。Spring WS 是专为简化SOAP Web Services的开发而设计的,提供了一种创建文档驱动、基于SOAP的服务的方式,特别适合需要深度集成和复杂配置的企业级应用。相比之下,JAX-WS 是遵循WS-*标准的更为基础和轻量级的Java API,适用于需要标准Java支持且配置较少的场景。
本文主要展示这两种技术在Spring Boot环境中实现方式。
本文两种实现方式
@Endpoint 注解实现 SOAP Web Services
@WebService 注解实现 SOAP Web Services
版本
Java:8
Spring Boot:2.3.12.RELEASE
@Endpoint
@Endpoint注解来自Spring Web Services(Spring WS)项目,它专门用于处理SOAP Web服务的开发。Spring WS 不依赖于企业Java的标准,而是建立在Spring框架的基础之上,提供更灵活的配置和更好的集成。
@Endpoint示例参考此篇文件:https://www.baeldung.com/spring-boot-soap-web-service。但有几个点需要改动。

- Maven依赖。
org.springframework.boot spring-boot-starter-web-services
wsdl4j wsdl4j - 在src/main/resources目录下创建一个名为 countries.xsd 的XSD文件(XML Schema Definition),用于定义SOAP消息的结构。这个Schema将作为生成Java类的基础,用于请求和响应的数据结构。
- 配置jaxb maven插件,将定义的 XSD 文件生成对应的 Java 类。
org.codehaus.mojo jaxb2-maven-plugin 3.1.0 xjc xjc src/main/resources/countries.xsd src/main/java/endpoint false
source路径自己定义,相对路径绝对路径都可以。
控制台输入命令:
mvn package
则会生成对应的java类,拷贝到对应的目录下即可。 - 添加 SOAP Web 服务端点。
@Component
@Endpoint
public class CountryEndpoint { private static final String NAMESPACE_URI = “http://www.baeldung.com/springsoap/gen”; @PayloadRoot(namespace = NAMESPACE_URI, localPart = “getCountryRequest”)
@ResponsePayload
public JAXBElement getCountry(@RequestPayload JAXBElement request) {
GetCountryResponse response = new GetCountryResponse();
Country country = new Country();
country.setCapital(“12”);
country.setName(request.getValue().getName());
response.setCountry(country);
return new JAXBElement<>(new QName(NAMESPACE_URI, GetCountryResponse.class.getSimpleName()), GetCountryResponse.class, response);
}
}
注解含义:
@Endpoint:将类作为 Web 服务端点注册到 Spring WS。(端点可理解为处理特定类型的请求处理器)
@PayloadRoot:标记具体处理SOAP请求的方法。根据命名空间和 localPart 属性定义处理程序方法。
namespace:命名空间URI,用于标识特定的XML文档或元素集。
localPart:本地名称,指定在给定命名空间中的特定元素。
@ResponsePayload:处理将Java对象转换回SOAP消息的注解。
@RequestPayload:该注解将SOAP请求参数反序列化为java对象。
JAXBElement:相当于一个包装器,用来包含单个XML元素的信息。上述例子中创建JAXBElement是确保响应有正确的命令空间和本地名称。
namespace和localPart对应关系如下图:
- SOAP Web 服务配置 Bean。
WebServiceConfig类主要目的是配置和发布一个基于 SOAP 协议的 Web 服务。
@EnableWs //启用Spring Web Services的配置支持
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter { @Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
//定义一个servlet,用于处理soap消息
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean<>(servlet, “/ws/*”);
} @Bean(name = “countries”)
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
//公开一个标准的WSDL 1.1文档
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName(“CountriesPort”);
//定义服务的访问地址,即客户端访问Web服务的端点
wsdl11Definition.setLocationUri(“/ws”);
wsdl11Definition.setTargetNamespace(“http://www.baeldung.com/springsoap/gen”);
//关联xsd文件
wsdl11Definition.setSchema(countriesSchema);
return wsdl11Definition;
} @Bean
public XsdSchema countriesSchema() {
return new SimpleXsdSchema(new ClassPathResource(“countries.xsd”));
}
}
应用启动成功后,打开url来验证wsdl文件是否成功发布:http://localhost:18889/ws/countries.wsdl。(我本地应用端口非8080)
WSDL 文件如下:
<xs:element name="getCountryRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="getCountryResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="country" type="tns:country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="country">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="population" type="xs:int"/>
<xs:element name="capital" type="xs:string"/>
<xs:element name="currency" type="tns:currency"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="currency">
<xs:restriction base="xs:string">
<xs:enumeration value="GBP"/>
<xs:enumeration value="EUR"/>
<xs:enumeration value="PLN"/>
</xs:restriction>
</xs:simpleType>
文件内容:
types(类型):定义web服务之间传递的数据类型。
message(消息):定义web服务中用于通信的消息结构。
portType(端口类型):定义web服务接口,包含一组操作,每个操作定义了输入和输出得消息结构。
binding(绑定):定义web服务的通信协议和消息格式。
service(服务):定义web服务的实际访问地址。
- 用 postman 测试 SOAP 项目。
@WebService
@WebService注解来自JAX-WS(Java API for XML Web Services)标准,它是一个专门用于创建SOAP(Simple Object Access Protocol)Web服务的API。这种方法通常用于实现符合WS-标准的Web服务,并且是Java EE规范的一部分。
- Maven依赖。
org.springframework.boot spring-boot-starter-web-services
org.apache.cxf cxf-spring-boot-starter-jaxws 3.4.4 - 定义webservices接口。
@WebService(name = “PersonnelInfo”,
targetNamespace = “http://service.manage.com/”)
public interface PersonnelInfoService { @WebMethod
String syncPersonnelInfo(@WebParam(name = “xmlData”, targetNamespace = “http://service.manage.com/”) String jsonData);
}
@WebService:标记一个接口或类作为Web服务的服务端点。
name:指定服务的名称。
targetNamespace:定义了这个Web服务所使用的XML命名空间。
@WebMethod 和 @WebParam 注解用于定义 Web 服务中的方法和参数。 - 定义webservices实现类。
//endpointInterface:服务接口全路径
@Slf4j
@Component
@WebService(name = “PersonnelInfo”,
targetNamespace = “http://service.manage.com/”,
endpointInterface = “com.manage.service.PersonnelInfoService”)
public class PersonnelInfoServiceImpl implements PersonnelInfoService {
@Override
public String syncPersonnelInfo(@WebParam(name = "xmlData", targetNamespace = "http://service.manage.com/") String xmlData) {
String result = "success";
log.info("三方信息调用入参:{}", xmlData);
}
}
- 发布webservices服务。
@Configuration
public class CxfConfig { @Autowired
private Bus bus;
@Autowired
private PersonnelInfoService personnelInfoService; @Bean(name = “wsBean”)
public ServletRegistrationBean dispatcherServlet() {
//注册servlet,用于处理web服务请求
ServletRegistrationBean wbsServlet = new ServletRegistrationBean(new CXFServlet(), “/ws/*”);
return wbsServlet;
} /**- JAX-WS
- 站点服务
**/
@Bean
public Endpoint endpoint() {
//发布Web服务的类,将请求都交给personnelInfoService类处理
EndpointImpl endpoint = new EndpointImpl(bus, personnelInfoService);
//将当前端点发布到URL路径/data上
endpoint.publish(“/data”);
return endpoint;
}
}
输入下面url检查程序发布是否正常:http://localhost:8080/ws/countries.wsdl
- 用 postman 测试 SOAP 项目。
总结
@Endpoint 和 @WebService 这两种方式都可以实现接收 XML 请求的需求。其中一个依赖于 JAX-WS 标准,更适合定制化和特殊需求的 Web 服务实现;另一个依赖于 JAX-WS 标准,适用于遵循规范和标准化的项目。具体可根据实际需求和开发栈来选择合适的实现方式。
参考资料
https://www.baeldung.com/spring-boot-soap-web-service
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/415030.html