一、Web Service
1、定义
W3C定义,Web服务(Web service)应当是一个软件系统,用以支持网络间不同机器的互动操作。
2、作用
多系统间数据通信
二、CXF是什么?
CXF是目前最主流Web Service 开源的开发框架 ,由Apache提供。支持JAX-WS 和 JAX-RS。
三、CXF-JAX-WS入门案例
1、简介
方法驱动。基于SOAP协议[SOAP=HTTP+XML ]以XML格式传输数据。
2、quickstart
2.1、创建maven project[Packaging:jar]
1 <groupId>org.cxf.maven</groupId> 2 <artifactId>cxf_ws_helloworld</artifactId> 3 <version>1.0.0-SNAPSHOT</version> 4 <name>cxf_ws_helloworld</name> 5 <description>CXF开发(一)JAX-WS快速入门</description>
2.2、添加依赖
1 <dependencies> 2 <!-- JAX-WS --> 3 <dependency> 4 <groupId>org.apache.cxf</groupId> 5 <artifactId>cxf-rt-frontend-jaxws</artifactId> 6 <version>3.0.1</version> 7 </dependency> 8 <dependency> 9 <groupId>org.apache.cxf</groupId> 10 <artifactId>cxf-rt-transports-http-jetty</artifactId> 11 <version>3.0.1</version> 12 </dependency> 13 <!-- 日志 --> 14 <dependency> 15 <groupId>org.slf4j</groupId> 16 <artifactId>slf4j-log4j12</artifactId> 17 <version>1.7.12</version> 18 </dependency> 19 </dependencies>
2.3、引入 log4j.properties ,放置到resoiurces下
1 ### direct log messages to stdout ### 2 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 log4j.appender.stdout.Target=System.out 4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 6 7 ### direct messages to file mylog.log ### 8 log4j.appender.file=org.apache.log4j.FileAppender 9 log4j.appender.file.File=c:/mylog.log 10 log4j.appender.file.layout=org.apache.log4j.PatternLayout 11 log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 12 13 ### set log levels - for more verbose logging change 'info' to 'debug' ### 14 15 log4j.rootLogger=info, stdout
2.4、搭建服务端
2.4.1、导入实体bean
①Car.java
1 package org.cxf_ws.domain; 2 3 public class Car { 4 private Integer id; 5 private String carName; 6 private Double price; 7 8 public Integer getId() { 9 return id; 10 } 11 12 public void setId(Integer id) { 13 this.id = id; 14 } 15 16 public String getCarName() { 17 return carName; 18 } 19 20 public void setCarName(String carName) { 21 this.carName = carName; 22 } 23 24 public Double getPrice() { 25 return price; 26 } 27 28 public void setPrice(Double price) { 29 this.price = price; 30 } 31 32 @Override 33 public String toString() { 34 return "Car [id=" + id + ", carName=" + carName + ", price=" + price + "]"; 35 } 36 37 }
②User.java
1 package org.cxf_ws.domain; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class User { 7 private Integer id; 8 private String username; 9 private String city; 10 11 private List<Car> cars = new ArrayList<Car>(); 12 13 public Integer getId() { 14 return id; 15 } 16 17 public void setId(Integer id) { 18 this.id = id; 19 } 20 21 public String getUsername() { 22 return username; 23 } 24 25 public void setUsername(String username) { 26 this.username = username; 27 } 28 29 public String getCity() { 30 return city; 31 } 32 33 public void setCity(String city) { 34 this.city = city; 35 } 36 37 public List<Car> getCars() { 38 return cars; 39 } 40 41 public void setCars(List<Car> cars) { 42 this.cars = cars; 43 } 44 45 }
2.4.2、构建服务bean
①IUserService.java
1 package org.cxf_ws.service; 2 3 import java.util.List; 4 5 import javax.jws.WebMethod; 6 import javax.jws.WebService; 7 8 import org.cxf_ws.domain.Car; 9 import org.cxf_ws.domain.User; 10 11 @WebService 12 // @WebService,该注解使用在类上面,标记类是WebService服务提供对象(必须填写) 13 public interface IUserService { 14 @WebMethod 15 // 传递字符串的名称,返回字符串的值 16 public String sayHello(String name); 17 18 // @WebMethod,该注解使用在方法上面,标记方法是WebService服务提供的方法(可省略) 19 // 传递User对象,返回当前用户拥有的车 20 public List<Car> findCarsByUser(User user); 21 }
②UserServiceImpl.java
1 package org.cxf_ws.service; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import javax.jws.WebService; 7 8 import org.cxf_ws.domain.Car; 9 import org.cxf_ws.domain.User; 10 11 @WebService(endpointInterface/* 接口服务完整类名 */= "org.cxf_ws.service.IUserService", serviceName/* 服务名称 */= "userService") 12 public class UserServiceImpl implements IUserService { 13 14 public String sayHello(String name) { 15 // 执行查询数据库的逻辑 16 return "Hello," + name; 17 } 18 19 public List<Car> findCarsByUser(User user) { 20 // 执行查询数据库的逻辑 21 // 这里本应该查询数据库的,为了演示,做一些假数据 22 if ("xiaoming".equals(user.getUsername())) { 23 List<Car> cars = new ArrayList<Car>(); 24 Car car1 = new Car(); 25 car1.setId(1); 26 car1.setCarName("大众"); 27 car1.setPrice(200000d); 28 cars.add(car1); 29 Car car2 = new Car(); 30 car2.setId(2); 31 car2.setCarName("现代"); 32 car2.setPrice(170000d); 33 cars.add(car2); 34 return cars; 35 } else { 36 return null; 37 } 38 } 39 }
2.4.3、配置jre环境1.5以上[使注解@WebService和@WebMethod生效]
①方案一、在pom.xml中配置plugin(本文采用)
1 <build> 2 <plugins> 3 <plugin> 4 <groupId>org.apache.maven.plugins</groupId> 5 <artifactId>maven-compiler-plugin</artifactId> 6 <version>2.3.2</version> 7 <configuration> 8 <source>1.7</source> 9 <target>1.7</target> 10 </configuration> 11 </plugin> 12 </plugins> 13 </build>
②方案二、eclipse配置
(1)全局配置
(2)项目配置
2.5、发布服务
2.5.1、方案一、Jdk
1 package org.cxf_ws.server; 2 3 import javax.xml.ws.Endpoint; 4 5 import org.cxf_ws.service.IUserService; 6 import org.cxf_ws.service.UserServiceImpl; 7 8 public class JAX_WS_Server_Jdk { 9 10 /** 11 * JDK发布webservice 12 * * 生成客户端的代码wsimport 13 */ 14 public static void main(String[] args) { 15 // 1、创建服务实现类对象 16 IUserService userService = new UserServiceImpl(); 17 // 2、定义服务地址 18 String address = "http://localhost:9999/userService"; 19 // 3、发布服务 20 Endpoint.publish(address, userService); 21 // 4、打印信息 22 System.out.println("helloService 服务已经启动 ..."); 23 } 24 }
2.5.2、案二、CXF_JaxWsServerFactoryBean
1 package org.cxf_ws.server; 2 3 import org.apache.cxf.interceptor.LoggingInInterceptor; 4 import org.apache.cxf.interceptor.LoggingOutInterceptor; 5 import org.apache.cxf.jaxws.JaxWsServerFactoryBean; 6 import org.cxf_ws.service.IUserService; 7 import org.cxf_ws.service.UserServiceImpl; 8 9 public class JAX_WS_Server_JaxWsServerFactoryBean { 10 11 /** 12 * CXF发布 13 */ 14 public static void main(String[] args) { 15 // 1、创建服务实现类 对象 16 IUserService userService = new UserServiceImpl(); 17 // 2、定义服务地址 18 String address = "http://localhost:9999/userService"; 19 // 3、创建JaxWsServer对象 20 JaxWsServerFactoryBean jaxWsServer = new JaxWsServerFactoryBean(); 21 jaxWsServer.setServiceBean(userService); 22 jaxWsServer.setAddress(address); 23 // 4、打印日志,可以让我们看到传输的数据,SOAP协议=HTTP协议+XML数据 24 jaxWsServer.getInInterceptors().add(new LoggingInInterceptor()); 25 jaxWsServer.getOutInterceptors().add(new LoggingOutInterceptor()); 26 // 5、发布服务 27 jaxWsServer.create(); 28 // 6、打印信息 29 System.out.println("CXF服务发布成功!"); 30 } 31 }
2.5.3、测试发布服务是否成功(webservice的使用说明书)
输入地址localhost:9999/userService?wsdl
2.6、搭建客户端
2.6.1、JDK的wsimport命令生成本地调用WebService服务的代码
使用wsimport命令解析WSDL文档:wsimport -s . http://localhost:9999/userService?wsdl[webservice说明书地址]
名称 | 含义 |
wsimport |
JDK命令 |
-s |
生成代码 |
. |
当前路径,I.e. D: estcxf |
http://localhost:9999/userService?wsdl |
webservice说明书地址 |
2.6.2、创建客户端maven project[Packaing:jar]
1 <groupId>org.cxf.maven</groupId> 2 <artifactId>cxf_ws_helloworld_client</artifactId> 3 <version>1.0.0-SNAPSHOT</version> 4 <name>cxf_ws_helloworld_client</name> 5 <description>CXF开发(一)JAX-WS快速入门之客户端</description>
2.6.3、复制调用WebService服务的代码到客户端工程
2.7、测试客户端工程访问服务端工程
2.7.1、JDK-TestWebService.java
1 package org.cxf_ws.service; 2 3 import java.util.List; 4 5 /** 6 * 基于JDK提供的wsimport命令解析WSDL文档生成本地代码 7 * 使用本地代码生成一个代理对象,通过代理对象可以发送HTTP请求 8 * 请求webservice服务 9 */ 10 public class TestWebService { 11 public static void main(String[] args) { 12 UserService userService = new UserService(); 13 IUserService proxy = userService.getUserServiceImplPort(); 14 System.out.println(proxy.sayHello("张无忌")); 15 User user = new User(); 16 user.setUsername("xiaoming"); 17 List<Car> list = proxy.findCarsByUser(user); 18 for (Car car : list) { 19 System.out.println(car.getId() + ":" + car.getCarName() + ":" + car.getPrice()); 20 } 21 } 22 }
2.7.2、CXF
①引入依赖
1 <dependencies> 2 <!-- JAX-WS --> 3 <dependency> 4 <groupId>org.apache.cxf</groupId> 5 <artifactId>cxf-rt-frontend-jaxws</artifactId> 6 <version>3.0.1</version> 7 </dependency> 8 <dependency> 9 <groupId>org.apache.cxf</groupId> 10 <artifactId>cxf-rt-transports-http-jetty</artifactId> 11 <version>3.0.1</version> 12 </dependency> 13 <!-- 日志 --> 14 <dependency> 15 <groupId>org.slf4j</groupId> 16 <artifactId>slf4j-log4j12</artifactId> 17 <version>1.7.12</version> 18 </dependency> 19 </dependencies>
②CXF测试类
1 package org.cxf_ws.service; 2 3 import java.util.List; 4 5 import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; 6 7 8 /** 9 * 基于JDK提供的wsimport命令解析WSDL文档生成本地代码 10 * 使用本地代码生成一个代理对象,通过代理对象可以发送HTTP请求 11 * 请求webservice服务 12 */ 13 public class CXF_JAX_WS_Client { 14 public static void main(String[] args) { 15 // 1、编写客户端调用发布webservice的服务 16 JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); 17 jaxWsProxyFactoryBean.setServiceClass(IUserService.class); 18 jaxWsProxyFactoryBean.setAddress("http://localhost:9999/userService"); 19 // 2、创建调用远程服务的代理对象 20 IUserService proxy = (IUserService) jaxWsProxyFactoryBean.create(); 21 // 3、调用远程服务上的sayHello方法 22 System.out.println(proxy.sayHello("CXF_JAX_WS")); 23 // 4、调用远程服务上的findCarsByUser方法 24 User user = new User(); 25 user.setUsername("xiaoming"); 26 List<Car> list =proxy.findCarsByUser(user); 27 for (Car car : list) { 28 System.out.println(car.getId() + ":" + car.getCarName() + ":" + car.getPrice()); 29 } 30 } 31 }
2.7.3、用日志查看soap协议内容
3、JAX-WS 原理