WebService技术
WebService的概述
1. 需求描述
* 我们经常查询的便民的网站上,都包含一些功能,例如:日常天气,手机归属地等功能,那么这些功能是如何实现的呢?
* 如果是你开发的网站,那么你本地的数据库中肯定是没有天气或者手机归属地相关的信息的,是需要从国家气象局等地获取到天气的信息,然后显示给用户的,那么想获取到国家气象局的数据?要怎么获取呢?
* Socket编程
* 通过Http调用实现
* 通过WebService技术实现(推荐使用的方式)
* WebService即Web的服务
* 它是一种跨编程语言的和操作系统平台的远程调用技术
* RMI(也是一种远程调用的技术)
2. WebService的概述
* Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。
* Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。
* 依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。
* Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。
3. WebService在商务综合管理平台的应用场景
* 之前的海关报运是打印出报运单,然后线下到海关处进行审批
* 假如海关报运平台,提供了海关报运的服务,咱们的系统只要通过海关报运的服务就可以网上进行海关报运操作了
WebService的规范(了解)及三要素(重点)
1. WebService的规范(了解)
* JAX-WS
* JAXM&SAAJ
* JAX-RS
2. WebService的三要素(重点)
* 第一要素:soap协议
* soap:simple object access protocal
* soap协议是WebService的传输协议,即简单对象访问协议。
* soap协议是XML格式,基于http协议来传输XML数据,可以理解为:soap = http + xml
* 特点:跨平台、跨语言、w3c指定的标准
* 各个开发语言都按着相同的标准实现WebService的开发
* 第二要素:WSDL
* WSDL指网络服务描述语言,是一种使用XML编写的文档,用于描述网络服务,也可以用于定位网络服务。
* WSDL是WebService的使用说明书。
* 第三要素:UDDI(了解)
* UDDI 是一种目录服务,企业可以使用它对 Web services 进行注册和搜索。
* UDDI统一描述、发现和集成协议是一个目录服务,存储了全球的WebService的服务
* UDDI旨在将全球的WebService资源所共享,促进全球经济合作
WebService的入门(使用的是JaxWs规范)
WebService服务端入门
1. CXF框架的概述
* CXF是apache下的WebService的开源框架
* CXF可以帮助您构建和开发WebService的服务,支持多种协议。
2. CXF框架的入门(服务端代码的编写)
* 1. 创建web工程,导入CXF框架的坐标依赖(本地仓库中没有,需要联网下载),不要忘记导入log4j的配置文件
<dependencies>
<!-- 要进行jaxws 服务开发 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 内置jetty web服务器 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 日志实现 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
* 2. 从资料中导入User和Car的类
* 3. 从资料中导入service接口和serviceImpl实现类(一会需要把该接口中的方法发布成WebService的服务)
* 4. 在接口上添加@WebService的注解,准备把IUserService中2个方法发布成WebService的服务
* 5. 编写服务端发布WebService
/**
* 发布服务
* @author Administrator
*/
public class Server {
public static void main(String[] args) {
// 创建服务器工厂对象
JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean();
// 设置请求地址
bean.setAddress("http://localhost:12345/user");
// 设置实现类
bean.setServiceBean(new UserServiceImpl());
// 开启服务
bean.create();
}
}
WebService客户端入门
1. 创建客户端的Java工程,导入CXF的坐标依赖
2. 使用JDK自带的wsimport命令来生成客户端的代码(强调:服务不能关闭)
* 先进入到src目录下:cd D:\workspace\JavaEE_demo\ws231_client\src 回车
* 再次输入:d: 回车
* 再次输入:wsimport -s . http://localhost:12345/user?wsdl 回车
* 此时该命令会根据发布的WebService服务来创建客户端的代码程序代码
3. 有了客户端的程序代码,可以开始编写客户端的程序了
public class Demo1 {
@Test
public void run1(){
// 创建代理工厂对象
JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
// 设置服务端地址
factoryBean.setAddress("http://localhost:12345/user");
// 设置接口
factoryBean.setServiceClass(IUserService.class);
// 生成代理对象
IUserService ws = (IUserService) factoryBean.create();
// 调用服务器端的方法了
String result = ws.sayHi("美美");
System.out.println(result);
User u = new User();
u.setUsername("宋江");
List<Car> list = ws.findCarsByUser(u);
for (Car car : list) {
System.out.println(car.getCarName());
}
}
}
Spring框架与CXF框架的整合
Spring整合CXF框架的服务端开发
1. 创建WEB项目,导入坐标依赖
<dependencies>
<!-- CXF WS开发 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
</dependencies>
2. 拷贝之前编写的服务接口和实现类
3. 创建applicationContext.xml的配置文件,注意约束的信息(注意:自己配置提示)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
">
</beans>
4. 在applicationContext.xml配置文件中配置WebService的服务(目的:之前是手动编写服务端的代码,现在使用Spring的配置文件方式发布Web服务)
* 具体的配置如下
<!-- 配置服务接口的实现类 -->
<bean id="userService" class="cn.itcast.service.UserServiceImpl"/>
<!-- 配置服务端的工厂,地址强调:因为是web项目,最终需要放入到tomcat服务器中运行,那么端口默认是8080 -->
<jaxws:server address="/user">
<jaxws:serviceBean>
<ref bean="userService"/>
</jaxws:serviceBean>
</jaxws:server>
5. 在web.xml配置文件配置Spring的监听器,服务器启动,就加载applicationContext.xml配置文件
* 加载Spring配置文件的监听器
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-cxf.xml</param-value>
</context-param>
* 配置CXF的Servlet程序
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
6. 打开浏览器,访问
* http://localhost:8080/ee66ws_jaxws_server_spring/ws/user?wsdl
Spring整合CXF框架的客户端开发
1. 创建web项目,导入CXF的所有的jar包
2. 使用wsimport来生成新的客户端的代码(强调:服务器不能是关闭状态)
* 先进入到src目录下:cd D:\workspace\JavaEE_demo\web231_client\src 回车
* 再次输入:d: 回车
* 再次输入:wsimport -s . http://localhost:8080/web231_server/ws/weather?wsdl 回车
* 此时该命令会根据发布的WebService服务来创建客户端的代码程序代码
3. 创建applicationContext.xml的配置文件,配置客户端
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
">
<!-- 配置ws的客户端 -->
<jaxws:client id="myClient" address="http://localhost:8080/web231_server/ws/weather?wsdl" serviceClass="cn.itcast.ws.WeatherService"/>
</beans>
4. 编写测试程序
@Test
public void run1(){
// 获取Spring的工厂
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext-cxf.xml");
IUserService ws = (IUserService) ac.getBean("myClient");
String result = ws.sayHi("小凤");
System.out.println(result);
}
Restful的编程风格
Restful的概述
1. 概述
* 一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。
* 它主要用于客户端和服务器交互类的软件。
* 基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
2. JaxRs的WebService服务发布方式就是采用的Restful的风格。
使用JaxRs规范发布Restful风格的WebService服务
1. 创建Maven工程,导入如下坐标依赖
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
2. 从资料中导入User和Car的类(强调:从jaxrs的素材中导入)
* @XmlRootElement(name = "Car"),以后把User类转换成XML格式的数据时候,Car作为根节点,例如
<Car>
<id>1</id>
</Car>
3. 从资料中导入service接口和serviceImpl实现类(强调:从jaxrs的素材中导入)
* @Path("/userService") -- 请求的路径
* @Produces("*/*") -- 响应的MIME类型
* @POST -- 请求方式,适合于新增
* @PUT -- 请求方式,适合于修改
* @GET -- 请求方式,适合于查询
* @DELETE -- 请求方式,适合于删除
* @Path("/user/{id}") -- 查询id为xxx的对象,例如:/user/1 查询id为1的用户
* @Consumes({ "application/xml", "application/json" }) -- 客户端发送的参数类型
4. 编写服务端发布WebService
/**
* 发布服务
* @author Administrator
*/
public class Server {
public static void main(String[] args) {
// 创建服务器工厂对象
JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean();
// 设置实体类,可以帮助转换json字符串
bean.setResourceClasses(User.class,Car.class);
// 设置请求地址
bean.setAddress("http://localhost:12345");
// 设置实现类
bean.setServiceBean(new UserServiceImpl());
// 开启服务
bean.create();
}
}
5. 客户端的程序
@Test
public void run1(){
User user = new User();
user.setId(1);
user.setUsername("aaa");
WebClient.create("http://localhost:12345/userService/user").type(MediaType.APPLICATION_XML).post(user);
}
Spring整合JaxRs规范的WebService
Spring整合JaxRs
1. 创建Maven项目,导入坐标依赖
<dependencies>
<!-- cxf 进行rs开发 必须导入 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 日志引入 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<!-- 客户端 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 扩展json提供者 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 转换json工具包,被extension providers 依赖 -->
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.7</version>
</dependency>
<!-- spring 核心 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- spring web集成 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- spring 整合junit -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- junit 开发包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2. 导入相关的domain和service
3. 把 UserService接口的 @Path("/userService") 注释掉,因为准备使用配置文件来描述路径
4. 编写配置文件
<bean id="userService" class="cn.itcast.service.UserServiceImpl"/>
<jaxrs:server address="/userService">
<jaxrs:serviceBeans>
<ref bean="userService"/>
</jaxrs:serviceBeans>
</jaxrs:server>
5. 在web.xml配置文件配置Spring的监听器,服务器启动,就加载applicationContext.xml配置文件
* 加载Spring配置文件的监听器
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-cxf.xml</param-value>
</context-param>
* 配置CXF的Servlet程序
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
6. 编写客户端的代码
@Test
public void run1(){
User user = new User();
user.setId(1);
user.setUsername("aaa");
// WebClient.create("http://localhost:8080/demo1/ws/userService/user").type(MediaType.APPLICATION_XML).post(user);
// WebClient.create("http://localhost:8080/demo1/ws/userService/user").type(MediaType.APPLICATION_XML).put(user);
User u = WebClient.create("http://localhost:8080/demo1/ws/userService/user/1").accept(MediaType.APPLICATION_XML).get(User.class);
System.out.println(u);
}