一、简介
资源驱动。基于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>