欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > SpringBoot扩展——应用Web Service!

SpringBoot扩展——应用Web Service!

2025/6/20 17:58:12 来源:https://blog.csdn.net/IT_1024/article/details/148776132  浏览:    关键词:SpringBoot扩展——应用Web Service!

应用Web Service

Web Service是一个SOA(面向服务的编程)架构,这种架构不依赖于语言,不依赖于平台,可以在不同的语言之间相互调用,通过Internet实现基于HTTP的网络应用间的交互调用。Web Service是一个可以远程调用的类,即它可以让项目使用其他资源,如在网页上显示天气、地图、微博上的最新动态等,这些都是调用的其他资源。

Web Service简介

在Web Service体系架构中有3个角色:

服务提供者(Service Provider),也称为服务生产者;

服务请求者(Service Requester),也称为服务消费者;

服务注册中心(Service Register),服务提供者在这里发布服务,

服务请求者在这里查找服务,获取服务的绑定信息。

上述3个角色的请求过程如图6.20所示。

Web Service的3个角色间主要有3个操作:

发布(Publish):服务提供者把服务按照规范格式发布到服务注册中心。

查找(Find):服务请求者根据服务注册中心提供的规范接口发出查找请求,获取绑定服务所需的相关信息。

绑定(Bind):服务请求者根据服务绑定信息配置自己的系统,从而可以调用服务提供者提供的服务。

说明:Web Service是通过SOAP方式在Web上提供软件服务,使用WSDL文件说明提供的软件服务的具体信息,并通过UDDI进行注册。

Web Service的主要适用场景是软件的集成和复用,如气象局(服务端系统)、天气查询网站等,具体如下:

当发布一个服务(对内/对外),不考虑客户端类型和性能时,建议使用Web Service。

如果服务端已经确定使用Web Service,则客户端不能再选择其他框架,必须使用Web Service。

在Java项目开发中,Web Service框架主要包括Axis2和CXF,如果需要多语言的支持,建议选择Axis2。如果想和Spring集成或者其他程序集成,建议使用CXF,它们之间的区别如表6.4所示。

表6.4 Axis2和CXF区别

Spring Web Service简介

Spring Web Service(Spring-WS)是Spring团队开发的一个Java框架,其专注于创建文档驱动的Web服务。Spring Web Service的目的是促进契约优先的SOAP服务开发,通过配置XML文件的方式,创建灵活的Web服务,简化WebService的开发。

Spring Web Service有以下几个功能:

XML映射到对象:可以使用Message Payload和SOAP Action Header中存储的信息或使用XPath Expression将基于XML的请求映射给任何对象。

用于解析XML的多API支持:除了用于解析传入XML请求的标准JAXPAPI(DOM、SAX、StAX)之外,还支持其他库,如JDOM、dom4j、XOM。

用于划分多分组XML的多API支持:Spring Web Service使用其Object/XML Mapping模块支持JAXB 1和2、Castor、XMLBeans、JiBX和XStream库。Object/XML Mapping模块也可以用在非Web服务代码中。

基于Spring的配置:在Spring Web Service应用中可以方便、快速地使用Spring配置进行项目的自定义配置。

使用WS-Security模块:可以签名、加密、解密SOAP消息或对其进行身份验证。

支持Acegi安全性:使用Spring Web Service的WS-Security实现,Acegi配置可用于SOAP服务。

Spring Web Service是由5个模块组成的,各模块的功能如下:

Spring-WS Core:是主要模块,提供WebServiceMessage和SoapMessage等中央接口、服务器端框架、强大的消息调度功能及实现Web服务端点的支持类。它还提供Web Service使用者客户端作为WebServiceTemplate。

Spring-WS支持:为JMS和电子邮件等提供支持。

Spring-WS Security:负责提供与核心Web服务模块集成的WSSecurity实现。此模块允许使用现有的Spring SecurityImplementation进行身份验证和授权。Spring XML:为Spring Web Service提供XML支持类。该模块由Spring-WS框架内部使用。

Spring OXM:提供XML与对象映射的支持类。

这5个组件的关系如图6.21所示。

实战:Spring Web Service服务端发布项目

下面新建一个项目,并通过Spring Web Service服务端(功能提供者)发布。

(1)新建一个Web Service的提供者(provider),在pom.xml中添加Spring Web Service依赖如下:

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.2.10.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<groupId>com.example</groupId><artifactId>web-services-provider</artifactId>

<version>0.0.1-SNAPSHOT</version>

<name>web-services-provider</name>

<description>Demo project for Spring Boot</description>

<properties>

<java.version>1.8</java.version>

</properties>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web-services</artifactId>

</dependency>

<dependency>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-rt-frontend-jaxws</artifactId>

<version>3.3.5</version>

</dependency>

<dependency>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-rt-transports-http</artifactId>

<version>3.3.5</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

<exclusions>

<exclusion>

<groupId>org.junit.vintage</groupId>

<artifactId>junit-vintage-engine</artifactId>

</exclusion>

</exclusions>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId> </plugin>

</plugins>

</build>

(2)新建Web Service的配置类,在其中配置请求地址信息如下:

package com.example.webservicesprovider.config;

import com.example.webservicesprovider.service.DemoService;

import com.example.webservicesprovider.service.impl.DemoServiceImpl;

import org.apache.cxf.Bus;

import org.apache.cxf.bus.spring.SpringBus;

import org.apache.cxf.jaxws.EndpointImpl;

import org.apache.cxf.transport.servlet.CXFServlet;

import org.springframework.boot.web.servlet.ServletRegistrationBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import javax.xml.ws.Endpoint;

@Configuration

public class CxfConfig {

@Bean

public ServletRegistrationBean<CXFServlet> cxfServlet() {

/**

* ServletRegistrationBean是Servlet注册类,

* 参数1为Servlet对象,参数2为请求到Servlet的地址

*/

return new ServletRegistrationBean<>(new CXFServlet(),

"/demo/*");

}

@Bean(name = Bus.DEFAULT_BUS_ID)

public SpringBus springBus() {

return new SpringBus();

} /**

* 类的注册

* @return

*/

@Bean

public DemoService demoService() {

return new DemoServiceImpl();

}

/**

* 发布多个服务时,创建多个接触点,并使用@Qualifier指定不同的名称

* @return

*/

@Bean

public Endpoint endpoint() {

EndpointImpl endpoint = new EndpointImpl(springBus(),

demoService());

endpoint.publish("/api");

return endpoint;

}

}

(3)新建Web Service提供服务的接口:

package com.example.webservicesprovider.service;

import javax.jws.WebService;

/**

* name: Web Service的名称;

* targetNamespace: 指定名称空间,一般使用接口实现类的包名的反缀

*/

@WebService(name = "DemoService", targetNamespace =

"http://impl.service.

server.example.com")

public interface DemoService { String sayHello(String user);

}

(4)新建接口的实现类,对外提供的功能的实现代码如下:

package com.example.webservicesprovider.service.impl;

import com.example.webservicesprovider.service.DemoService;

import javax.jws.WebService;

import java.time.LocalDateTime;

/**

* serviceName: 对外发布的服务名;

* targetNamespace: 指定名称空间,一般使用接口实现类的包名的反缀;

* endpointInterface: 服务接口的全类名;

*/

@WebService(serviceName = "DemoService"

, targetNamespace = "http://impl.service.server.example.com"

, endpointInterface =

"com.example.webservicesprovider.service.DemoService")

public class DemoServiceImpl implements DemoService {

@Override

public String sayHello(String user) {

return user + ",接收到了请求, 现在的时间是: " +

LocalDateTime.now();

}

}

(5)新建Spring Boot的启动类:

package com.example.webservicesprovider;

import org.springframework.boot.SpringApplication;

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

public class WebServicesProviderApplication {

public static void main(String[] args) {

SpringApplication.run(WebServicesProviderApplication.class,

args);

}

}

(6)在application.properties中设置项目端口为8080:

server.port=8080

实战:Spring Web Service客户端调用项目

完成了服务提供者的创建后,新建一个Spring Web Service的消费者(client),在pomx.xml中添加Spring Web Service依赖如下:

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.3.10.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<groupId>com.example</groupId>

<artifactId>web-services-client</artifactId>

<version>0.0.1-SNAPSHOT</version>

<name>web-services-client</name>

<description>Demo project for Spring Boot</description>

<properties>

<java.version>1.8</java.version>

</properties> <dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web-services</artifactId>

</dependency>

<dependency>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-rt-frontend-jaxws</artifactId>

<version>3.3.5</version>

</dependency>

<dependency>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-rt-transports-http</artifactId>

<version>3.3.5</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

<exclusions>

<exclusion>

<groupId>org.junit.vintage</groupId>

<artifactId>junit-vintage-engine</artifactId>

</exclusion>

</exclusions>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

(1)在客户端中新建一个测试服务调用的TestController入口,请求

Web Service的提供者对返回的信息进行解析并打印结果。

package com.example.webservicesclient;

import org.apache.cxf.endpoint.Client;

import

org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

import org.apache.cxf.transport.http.HTTPConduit;

import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.net.URL;

import java.net.URLConnection;

import java.nio.charset.StandardCharsets;

@RestController

public class TestController {

@GetMapping("/test")

public void test() throws Exception {

//创建动态客户端

JaxWsDynamicClientFactory factory =

JaxWsDynamicClientFactory.newInstance();

//访问自己的服务端

Client client =

factory.createClient("http://localhost:8080/demo/api?wsdl");

// 需要密码时要加上用户名和密码

// client.getOutInterceptors().add(new

ClientLoginInterceptor(USER_NAME,PASS_WORD));

HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();


httpClientPolicy.setConnectionTimeout(2000); //连接超时


httpClientPolicy.setAllowChunking(false); //取消块编


httpClientPolicy.setReceiveTimeout(120000); //响应超时

conduit.setClient(httpClientPolicy);


//client.getOutInterceptors().addAll(interceptors); //设置拦

截器

try {

Object[] objects;

// 调用方式invoke("方法名",参数1,参数2,参数3....);

objects = client.invoke("sayHello", "cc, i miss you ");

System.out.println("返回数据:" + objects[0]);

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 测试第三方的Web Service接口,测试天气

*/

@GetMapping("/testWeather")

public void testWeather() {

String weatherInfo = getWeather("北京");

System.out.println(weatherInfo);

}

/**

* 对服务器端返回的XML进行解析

*

* @param city用户输入的城市名称

* @return字符串用#分割

*/

private static String getWeather(String city) {

Document doc;

DocumentBuilderFactory dbf =

DocumentBuilderFactory.newInstance();

dbf.setNamespaceAware(true);

try {

DocumentBuilder db = dbf.newDocumentBuilder();

InputStream is = getSoapInputStream(city); assert is != null;

doc = db.parse(is);

NodeList nl = doc.getElementsByTagName("string");

StringBuffer sb = new StringBuffer();

for (int count = 0; count < nl.getLength(); count++) {

Node n = nl.item(count);

if ("查询结果为

空!".equals(n.getFirstChild().getNodeValue())) {

sb = new StringBuffer(" ");

break;

}

sb.append(n.getFirstChild().getNodeValue()).append("

\n");

}

is.close();

return sb.toString();

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

/**

* 从接口文档中获取SOAP的请求头,并替换其中的标志符号为用户输入的城市

* (方法的接口文档:

* http://ws.webxml.com.cn/WebServices/WeatherWebService.asmx?

op=getWeatherbyCityName)

*

* @param city用户输入的城市名称

* @return客户将要发送给服务器的SOAP请求

*/

private static String getSoapRequest(String city) {

String sb = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +

"<soap:Envelope

xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +

"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +

"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +

"<soap:Body> <getWeatherbyCityName

xmlns=\"http://WebXml.com.cn/\">" +

"<theCityName>" + city +

"</theCityName> </getWeatherbyCityName>" +

"</soap:Body></soap:Envelope>";

return sb;

}

/**

* 通过接口文档的请求头构建SOAP请求,向服务器端发送SOAP请求,并返回流

*

* @param city用户输入的城市名称

* @return服务器端返回的输入流,供客户端读取

* @throws Exception异常

*/

private static InputStream getSoapInputStream(String city) throws

Exception {

try {

String soap = getSoapRequest(city);

// 通过请求的服务地址(即Endpoint)构建URL对象,并使用URL对象开启连接

URL url = new

URL("http://ws.webxml.com.cn/WebServices/WeatherWebService.asmx");

URLConnection conn = url.openConnection();

conn.setUseCaches(false);

conn.setDoInput(true);

conn.setDoOutput(true);

// 为连接设置请求头属性

conn.setRequestProperty("Content-Length",

Integer.toString(soap.length()));

conn.setRequestProperty("Content-Type", "text/xml;

charset=utf-8");

conn.setRequestProperty("SOAPAction",

"http://WebXml.com.cn/getWeatherbyCityName");

// 将请求的XML信息写入连接的输出流

OutputStream os = conn.getOutputStream();

OutputStreamWriter osw = new OutputStreamWriter(os,

StandardCharsets.UTF_8);

osw.write(soap);

osw.flush();

osw.close();

// 获取连接中请求得到的输入流

return conn.getInputStream();

} catch (Exception e) { e.printStackTrace();

return null;

}

}

}

(2)新建Spring Boot启动类:

package com.example.webservicesclient;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class WebServicesClientApplication {

public static void main(String[] args) {

SpringApplication.run(WebServicesClientApplication.class,

args);

}

}

(3)在application.properties中添加当前项目端口为8080:

server.port=8081

(4)启动项目服务端provider和客户端client服务,打开浏览器并且访问网址localhost: 8080/demo/api?wsdl,可以看到服务端提供的WebService的说明,如图6.22所示。

图6.22 服务端提供的Web Service说明详情

(5)访问localhost:8081/test,可以测试Web Service的调用,client完成了provider的功能调用,可以在控制台上看到打印信息,如图6.23所示,表明Web Service调用成功。

图6.23 测试Web Service调用

(6)访问
localhost:8081/testWeather,调用一个公开的Web Service方法可以查询北京市的天气,显示结果如图6.24所示。

图6.24 调用Web Service查询天气

至此完成了Web Service调用的演示。在开发中使用Web Service对外提供接口,能够更好地对外提供数据,实现特定的功能。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词