一、簡介
資源驅動。基於HTTP協議[按照標准指定URL,就可以訪問數據]以XML|JSON格式傳輸數據。
二、quickstart
1、創建maven project[Packaging:jar]


2、導入依賴
1 <!-- CXF的rs開發 --> 2 <dependency> 3 <groupId>org.apache.cxf</groupId> 4 <artifactId>cxf-rt-frontend-jaxrs</artifactId> 5 <version>3.0.1</version> 6 </dependency> 7 <!-- 內置jetty的web服務器 --> 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>
3、搭建服務端
3.1、導入實體bean

參考CXF-JAX-WS開發(一)入門案例,2.4.1、導入實體bean目錄下的實體類Car.java和User.java
3.2、構建服務bean
3.2.1、IUserService.java
1 package org.cxf_rs.service; 2 3 import java.util.List; 4 import org.cxf_rs.domain.User; 5 6 public interface IUserService { 7 //增 8 public void saveUser(User user); 9 //刪 10 public void deleteUser(Integer id); 11 //改 12 public void updateUser(User user); 13 //查-查詢所有 14 public List<User> findAllUsers(); 15 //查-根據id查詢 16 public User finUserById(Integer id); 17 }
3.2.2、UserServiceImpl.java
1 package org.cxf_rs.service; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.cxf_rs.domain.Car; 7 import org.cxf_rs.domain.User; 8 9 10 public class UserServiceImpl implements IUserService { 11 //增 12 public void saveUser(User user) { 13 System.out.println("save user:" + user); 14 } 15 //刪 16 public void deleteUser(Integer id) { 17 System.out.println("delete user id :" + id); 18 } 19 //改 20 public void updateUser(User user) { 21 System.out.println("update user:" + user); 22 } 23 //查-查詢所有 24 public List<User> findAllUsers() { 25 List<User> users = new ArrayList<User>(); 26 User user1 = new User(); 27 user1.setId(1); 28 user1.setUsername("小明"); 29 user1.setCity("北京"); 30 31 List<Car> carList1 = new ArrayList<Car>(); 32 Car car1 = new Car(); 33 car1.setId(101); 34 car1.setCarName("保時捷"); 35 car1.setPrice(1000000d); 36 carList1.add(car1); 37 Car car2 = new Car(); 38 car2.setId(102); 39 car2.setCarName("寶馬"); 40 car2.setPrice(400000d); 41 carList1.add(car2); 42 user1.setCars(carList1); 43 44 users.add(user1); 45 46 User user2 = new User(); 47 user2.setId(2); 48 user2.setUsername("小麗"); 49 user2.setCity("上海"); 50 users.add(user2); 51 52 return users; 53 } 54 //查-根據id查詢 55 public User finUserById(Integer id) { 56 if (id == 1) { 57 User user1 = new User(); 58 user1.setId(1); 59 user1.setUsername("小明"); 60 user1.setCity("北京"); 61 return user1; 62 } 63 return null; 64 } 65 }
3.3、添加注解
3.3.1、domain[加@XmlRootElement注解]


未加的話報如下錯誤:

3.3.2、service
①常用注解

②IUserService.java帶注解
1 package org.cxf_rs.service; 2 3 import java.util.List; 4 5 import javax.ws.rs.Consumes; 6 import javax.ws.rs.DELETE; 7 import javax.ws.rs.GET; 8 import javax.ws.rs.POST; 9 import javax.ws.rs.PUT; 10 import javax.ws.rs.Path; 11 import javax.ws.rs.PathParam; 12 import javax.ws.rs.Produces; 13 14 import org.cxf_rs.domain.User; 15 16 17 @Path("/userService") 18 @Produces("*/*") 19 public interface IUserService { 20 //增 21 @POST 22 @Path("/user") 23 @Consumes({ "application/xml", "application/json" }) 24 public void saveUser(User user); 25 //刪 26 @DELETE 27 @Path("/user/{id}") 28 @Consumes("application/xml") 29 public void deleteUser(@PathParam("id") Integer id); 30 //改 31 @PUT 32 @Path("/user") 33 @Consumes({ "application/xml", "application/json" }) 34 public void updateUser(User user); 35 //查-查詢所有 36 @GET 37 @Path("/user") 38 @Produces({ "application/xml", "application/json" }) 39 public List<User> findAllUsers(); 40 //查-根據id查詢 41 @GET 42 @Path("/user/{id}") 43 @Consumes("application/xml") 44 @Produces({ "application/xml", "application/json" }) 45 public User finUserById(@PathParam("id") Integer id); 46 }
4、發布服務
1 package org.cxf_rs.server; 2 3 import org.apache.cxf.interceptor.LoggingInInterceptor; 4 import org.apache.cxf.interceptor.LoggingOutInterceptor; 5 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; 6 import org.cxf_rs.domain.Car; 7 import org.cxf_rs.domain.User; 8 import org.cxf_rs.service.IUserService; 9 import org.cxf_rs.service.UserServiceImpl; 10 11 12 public class JAX_RS_Server { 13 public static void main(String[] args) { 14 // 創建業務接口實現類對象 15 IUserService userService = new UserServiceImpl(); 16 // 服務器FactoryBean創建服務 17 JAXRSServerFactoryBean restServer = new JAXRSServerFactoryBean(); 18 restServer.setResourceClasses(User.class, Car.class); 19 restServer.setServiceBean(userService); 20 restServer.setAddress("http://localhost:9999/"); 21 // 打印日志 22 restServer.getInInterceptors().add(new LoggingInInterceptor()); 23 restServer.getOutInterceptors().add(new LoggingOutInterceptor()); 24 // 發布服務 25 restServer.create(); 26 System.out.println("服務器啟動成功!"); 27 } 28 }
5、客戶端測試
5.1、瀏覽器測試
5.1.1、查詢所有
查詢所有:http://localhost:9999/userService/user

5.1.2、根據id查詢
根據id查詢:http://localhost:9999/userService/user/1

5.2、WebClient 工具類[CXF 自帶的工具包]
5.2.1、導入依賴
1 <!-- 導入CXF-Client依賴 --> 2 <dependency> 3 <groupId>org.apache.cxf</groupId> 4 <artifactId>cxf-rt-rs-client</artifactId> 5 <version>3.0.1</version> 6 </dependency>
5.2.2、目錄結構

5.2.3、JAX_RS_Client.java
① 測試新增
1 // 測試新增 2 @Test 3 public void test_save(){ 4 /** 5 * create :建立與調用服務資源路徑連接 6 * path :訪問服務器的路徑--->@Path 7 * type :發送給服務器數據格式--->@Consumes 8 * accept :接收服務器傳輸數據格式--->@Produces 9 */ 10 User user = new User(); 11 user.setId(3); 12 user.setUsername("小美"); 13 user.setCity("深圳"); 14 WebClient.create("http://localhost:9999/").path("userService/user").type(MediaType.APPLICATION_JSON).post(user); 15 }

②測試刪除
1 // 測試刪除 2 @Test 3 public void test_delete(){ 4 /** 5 * create :建立與調用服務資源路徑連接 6 * path :訪問服務器的路徑--->@Path 7 * type :發送給服務器數據格式--->@Consumes 8 * accept :接收服務器傳輸數據格式--->@Produces 9 */ 10 // 刪除 11 WebClient.create("http://localhost:9999/").path("userService/user/1").type(MediaType.APPLICATION_XML).delete(); 12 }

③測試修改
1 // 測試修改 2 @Test 3 public void test_update(){ 4 /** 5 * create :建立與調用服務資源路徑連接 6 * path :訪問服務器的路徑--->@Path 7 * type :發送給服務器數據格式--->@Consumes 8 * accept :接收服務器傳輸數據格式--->@Produces 9 */ 10 User user = new User(); 11 user.setId(3); 12 user.setUsername("小美"); 13 user.setCity("深圳"); 14 // 修改 15 WebClient.create("http://localhost:9999/").path("userService/user").type(MediaType.APPLICATION_JSON).put(user); 16 }

④測試查詢所有
1 // 測試查詢所有 2 @Test 3 public void test_findAll() { 4 /** 5 * create :建立與調用服務資源路徑連接 6 * path :訪問服務器的路徑--->@Path 7 * type :發送給服務器數據格式--->@Consumes 8 * accept :接收服務器傳輸數據格式--->@Produces 9 */ 10 // 查詢所有用戶 11 Collection<? extends User> users = WebClient.create("http://localhost:9999/userService/user").accept(MediaType.APPLICATION_XML).getCollection(User.class); 12 System.out.println("查詢所有用戶" + users); 13 }

⑤測試根據id查詢
1 // 測試根據id查詢 2 @Test 3 public void test_findById() { 4 /** 5 * create :建立與調用服務資源路徑連接 6 * path :訪問服務器的路徑--->@Path 7 * type :發送給服務器數據格式--->@Consumes 8 * accept :接收服務器傳輸數據格式--->@Produces 9 */ 10 WebClient client = WebClient.create("http://localhost:9999/"); 11 User responseUser = client.path("userService/user/1").accept(MediaType.APPLICATION_XML).get(User.class); 12 System.out.println("根據id查詢" + responseUser); 13 }

5.2.4、測試新增報異常
①異常描述
Caused by: javax.ws.rs.ProcessingException: No message body writer has been found for class cn.itcast.cxf.domain.User, ContentType: application/json

②出現原因
測試時傳輸JSON格式的數據
③解決方案
引入json轉換器的依賴
1 <!-- CXF的json轉換器,拓展json --> 2 <dependency> 3 <groupId>org.apache.cxf</groupId> 4 <artifactId>cxf-rt-rs-extension-providers</artifactId> 5 <version>3.0.1</version> 6 </dependency> 7 <!-- 轉換json的工具包,被cxf-rt-rs-extension-providers包依賴 --> 8 <dependency> 9 <groupId>org.codehaus.jettison</groupId> 10 <artifactId>jettison</artifactId> 11 <version>1.3.7</version> 12 </dependency>
