上次介绍了使用CXF框架开发SOAP WebService服务,接下来介绍如何使用CXF框架开发RESTful风格的WebService服务.
这里就不罗嗦介绍restful是什么云云的话了(因为我也不理解..),或者说官方的话读起来觉得隐晦难懂,REST -- REpresentational State Transfer 直接翻译:表现层状态转移(这偷猫的谁能懂???),所以呢,我觉得就是一句话:用URL定位资源,用HTTP来描述CRUD操作.
所以必须知道一下几点:
1.服务端每一个对象,每一个资源都可以通过唯一的URL来进行寻址.
2.基于HTTP协议来进行资源请求{GET(查),POST(增),PUT(改),DELETE(删)}.或许这就是REST的奥妙所在吧.
3.访问的每一个资源都可以使用不同的形式加以表示(XML/JSON).
CXF框架支持RESTful风格的编程,发布了JAX-RS规范(http://cxf.apache.org/docs/jax-rs.html).
======================================================================================================================================好了,如何发布一个REST服务并调用呢?
服务端(Spring继承JPA与数据库交互):
1.实体类(加上@XmlRootElement注解,方便对象与XML之间转换)
@XmlRootElement @Entity public class User { private Integer uno; private String uname; }2.定义一个REST服务接口
public interface IUserService { @GET//请求的方法 @Path("sayHi")//方法的路径名(独一无二) String sayHi(@QueryParam("name") String name); @GET @Path("queryById") @Produces(MediaType.APPLICATION_JSON)//输出数据的格式 @Consumes(MediaType.APPLICATION_JSON)//接受数据的格式 User queryById(@QueryParam("uno") Integer uno);//方法中的查询参数,注意与@PathParam的区别,前者是键值对的形式出现的,本人喜欢用前者. @GET @Path("queryAll") @Produces(MediaType.APPLICATION_JSON) List<User> queryAll(); @POST @Path("addUser") @Consumes(MediaType.APPLICATION_JSON) void addUser(User user); @PUT @Path("updUser") @Consumes(MediaType.APPLICATION_JSON) void updUser(User user); @DELETE @Path("delUser") @Consumes(MediaType.APPLICATION_JSON) void delUser(@QueryParam("uno") Integer uno); }3.实现接口(其实rest不要求一定要有接口,所以可以直接实现方法)的部分省略,我是利用jpaRepository提供的方法实现的,有兴趣可以参照之前的博客.
@Component public class UserServiceImpl implements IUserService{
......
}
4.发布REST服务(与Spring结合)
spring-cxf.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: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/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <jaxrs:server address="/user"> <jaxrs:serviceBeans> <ref bean="userServiceImpl"/> </jaxrs:serviceBeans> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/> </jaxrs:providers> </jaxrs:server> </beans>
web.xml:
<!-- Spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- CXF --> <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>客户端(JAXRS2.0+WebClient两种方式实现CRUD):
1.JAXRS2.0(推荐使用)
//使用JAXRS2.0发布REST服务 public class JAXRSClientTest { private static final String url = "http://localhost:8080/restfulServer/ws/user"; private static final JacksonJsonProvider jsonProvider = new JacksonJsonProvider(); @Test public void sayHiTest() { String result = ClientBuilder.newClient() .target(url).path("/sayHi").queryParam("name", "呢喃北上") .request().get(String.class); System.out.println(result); } @Test public void queryByIdTest() { System.out.println("根据id查询用户"); Client client = ClientBuilder.newClient().register(jsonProvider);// 注册json 支持 WebTarget target = client.target(url + "/queryById").queryParam("uno", 2); Invocation.Builder builder = target.request(); Response response = builder.get(); User user = response.readEntity(User.class); System.out.println(user.getUname()); response.close(); System.out.println("over"); } @Test public void queryAllTest(){ System.out.println("查询所有的用户"); List<User> users = ClientBuilder.newClient().register(jsonProvider) .target(url).path("/queryAll") .request().get(new GenericType<List<User>>() {}); for (User user : users) { System.out.println(user); } System.out.println("over"); } @Test public void addUserTest(){ System.out.println("增加一位用户"); User user = new User(0, "mokeychan"); Client client = ClientBuilder.newClient().register(jsonProvider); WebTarget target = client.target(url+"/addUser"); Response response = target.request().buildPost(Entity.entity(user, MediaType.APPLICATION_JSON)).invoke(); response.close(); System.out.println("over"); } @Test public void updUserTest(){ System.out.println("更新一名用户"); User user = new User(21,"雷蒙磨咯"); Client client = ClientBuilder.newClient().register(jsonProvider); WebTarget target = client.target(url+"/updUser"); Response response = target.request().buildPut(Entity.entity(user, MediaType.APPLICATION_JSON)).invoke(); response.close(); queryAllTest(); System.out.println("over");; } @Test public void delUser(){ System.out.println("删除一名用户"); Client client = ClientBuilder.newClient().register(jsonProvider); WebTarget target = client.target(url+"/delUser?uno=18"); Response response = target.request().delete(); response.close(); System.out.println("over"); } }2.WebClient实现
//通用的WebClient方式发布 public class WebClientTest { private static final String url = "http://localhost:8080/restfulServer/ws/user"; public static void main(String[] args) { List<Object> providerList = new ArrayList<Object>(); providerList.add(new JacksonJsonProvider()); WebClient client = WebClient.create(url,providerList); User user = client.path("/queryById").query("uno", 2).accept(MediaType.APPLICATION_JSON).get(User.class); System.out.println(user.toString()); /*List users = client.path("/queryAll").accept(MediaType.APPLICATION_JSON).get(List.class); for (Object user : users) { System.out.println(user.toString()); }*/ } }好了,发布与调用RESTful风格的WebService服务就实现了,不得不说利用URL来访问资源真的是妙啊.
感谢黄勇大神的启发博文,链接:https://my.oschina.net/huangyong/blog/294324
项目参考地址:http://download.csdn.net/download/qq_33764491/10180087