CXF WebService開發
很多個系統,進行分佈的部署,分佈的系統資料通訊 解決技術就是 WebService。
CXF 是目前最主流 WebService 開發框架
CXF主要分為兩種服務
JAX-WS 傳輸資料,就是 XML 格式,基於 SOAP 協議
JAX-RS 傳輸資料,傳輸 XML 格式或者 JSON 格式,基於 HTTP 協議
JAX-WS獨立服務使用
匯入CXFjar包支援 Maven座標
<dependencies>
<!-- 進行jaxes 服務開發 -->
<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>
</dependencies>
編寫服務端的程式碼
-
實體類
Carprivate Integer id; private String carName; private Double price;
User
private Integer id; private String carName; private Double price;
-
服務端程式
IUserService介面@WebService //用來標記類是WebService服務提供物件 public interface IUserService { @WebMethod //用來標記方法是WebService提供的方法 public String sayHello(String name); @WebMethod public List<Car> findCarsByUser(User user); }
UserServiceImpl
@WebService(endpointInterface = "cn.lzh.cxf.service.IUserService", serviceName = "userService") //endpointInterface介面服務完整全類名 //serviceName服務名稱 public class UserServiceImpl implements IUserService { //簡單引數傳遞 public String sayHello(String name) { return "Hello," + name; } //複雜引數 傳遞 public List<Car> findCarsByUser(User user) { // 這裡本應該查詢資料庫的,為了演示,做一些假資料 if ("xiaoming".equals(user.getUsername())) { List<Car> cars = new ArrayList<Car>(); Car car1 = new Car(); car1.setId(1); car1.setCarName("大眾途觀"); car1.setPrice(200000d); cars.add(car1); Car car2 = new Car(); car2.setId(2); car2.setCarName("現代ix35"); car2.setPrice(170000d); cars.add(car2); return cars; } else { return null; } } }
-
將userService註冊到網上
//將CXY 將 UserServer註冊到網路上 //1.服務實現物件 IUserService userService = new UserServiceImpl(); //2釋出服務地址 String address = "http://localhost:8888/userService"; //3釋出服務 Endpoint.publish(address, userService); System.out.println("服務已經啟動...");
成功介面
-
客戶端
//ws客戶端 public class WS_Client { public static void main(String[] args) { //編寫客戶端 呼叫釋出WebService服務 JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); jaxWsProxyFactoryBean.setServiceClass(IUserService.class); jaxWsProxyFactoryBean.setAddress("http://localhost:9999/userService"); //呼叫遠端服務代理物件 IUserService proxy = (IUserService) jaxWsProxyFactoryBean.create(); //呼叫代理物件任何一個方法,都將網路呼叫web服務 System.out.println(proxy.sayHello("你好")); } }
服務啟動成功 可以用網路呼叫該服務
注意
可以通過
jaxWsProxyFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
jaxWsProxyFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
開啟日誌資訊
JAX-WS和Spring整合開發WebService
匯入CXF_WS的Maven座標 與tomcat外掛
<dependencies>
<!-- CSF WS開發核心 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<port>9800</port>
</configuration>
</plugin>
</plugins>
</build>
配置web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- spring核心監聽器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- CXF WS基於web訪問的servlet -->
<servlet>
<servlet-name>CXFService</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFService</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
application的配置
<?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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<!--
address 客戶端訪問伺服器路徑
serviceClass 配置介面
serviceBean 配置實現
-->
<jaxws:server id="userService" address="/userService" serviceClass="cn.lzh.cxf.service.IUserService">
<jaxws:serviceBean>
<bean class="cn.lzh.cxf.service.UserServiceImpl" />
</jaxws:serviceBean>
</jaxws:server>
</beans>
客戶端的測試
application-test的配置
<?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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<!--
serviceClass :服務介面
address 服務訪問地址
-->
<jaxws:client id="userServiceClient" serviceClass="cn.lzh.cxf.service.IUserService"
address="http://localhost:9800/cxf_ws_spring/services/userService" >
<!-- 來源訊息攔截器 -->
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
</jaxws:inInterceptors>
<!-- 輸出訊息攔截器 -->
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:outInterceptors>
</jaxws:client>
</beans>
測試程式碼:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-test.xml")
public class WS_spring_test {
@Autowired
private IUserService proxy;
@Test
public void testCXF(){
System.out.println(proxy.sayHello("你好"));
}
}
結果:
服務訪問成功
JAX-RS獨立使用
重點
要先了解restful風格:
在我認為restful是通過資源進行定位或進行操作的,不是什麼標準,也不是什麼協議,網際網路的任何事物都是
資源,比如說網路上有張圖片,我只需要知道那張圖片的名字,通過圖片名字的url來定位到這張圖片,
資源操作 我們用資料庫的crud 對應htpp方法,比如put修改 post儲存 get查詢,delete刪除,這樣我們能建立
統一的介面,減少程式碼的開發,提升開發效率 而且基於http協議,支援多種訊息格式,比如xml jason 更容
易實現快取機制,tomcat有快取機制,第一次訪問資源,第二次訪問資源,返回304客戶端呼叫本地
- 新增Maven依賴
<dependencies>
<!-- 使用CXF RS開發 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</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>
</dependencies>
- 編寫實體類
car
@XmlRootElement(name = "Car")
//指定序列化時(轉換xml json)物件名字
public class Car {
private Integer id;
private String carName;
private Double price;
public Integer getId() {
return id;
}
注意要寫@XMLRootElement註解
User
@XmlRootElement(name = "User")
public class User {
private Integer id;
private String username;
private String city;
private List<Car> cars = new ArrayList<Car>();
- 編寫服務端程式
IUserService
@Path("/userService")
//服務訪問資源路徑
@Produces("*/*")
//生成(返回值) 指定能夠生成哪種格式資料返回給客戶端
public interface IUserService {
@POST
//請求http協議的 增加
@Path("/user")
@Consumes({ "application/xml", "application/json" })
//方法的引數 指定能夠處理客戶端傳遞過來的資料格式
public void saveUser(User user);
@PUT
@Path("/user")
//請求http協議的 修改
@Consumes({ "application/xml", "application/json" })
public void updateUser(User user);
@GET
@Path("/user")
//請求http協議的 查詢
@Produces({ "application/xml", "application/json" })
public List<User> findAllUsers();
//生成(返回值) 指定能夠生成哪種格式資料返回給客戶端
@GET
@Path("/user/{id}")
@Consumes("application/xml")
@Produces({ "application/xml", "application/json" })
public User finUserById(@PathParam("id") Integer id);
@DELETE
@Path("/user/{id}")
//請求http協議的 刪除
@Consumes("application/xml")
public void deleteUser(@PathParam("id") Integer id);
}
注意 如果要返回資料要加@Produces註解 引數為可以處理的資料格式
注意 如果要接受引數要加@Consumes註解 引數為可以處理的資料格式
將服務釋出到網路
//建立業務介面實現類物件
IUserService userService = new UserServiceImpl();
//伺服器FactoryBean建立服務
JAXRSServerFactoryBean restServer = new JAXRSServerFactoryBean();
//將那些實體轉換成xml、json傳送
restServer.setResourceClasses(User.class,Car.class);
//設定服務的bean
restServer.setServiceBean(userService);
//設定地址
restServer.setAddress("http://localhost:9999");
//列印日誌
restServer.getInInterceptors().add(new LoggingInInterceptor());
restServer.getOutInterceptors().add(new LoggingOutInterceptor());
//釋出服務
restServer.create();
客戶端程式碼
首先要在maven新增WebClient依賴
<!-- 使用rs客戶端 裡面有個工具包為rs client -->
<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<