CXF 开发RESTful WebService服务(Spring+JPA服务端,JAXRS2.0+WebClient客户端)

上次介绍了使用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

相关文章

1.使用ajax调用varxhr;functioninvoke(){if(window.ActiveXO...
               好不容易把WebService服务器...
1新建一个工程项目用来做服务端增加一个MyService1类文件pac...
packagecom.transsion.util;importjava.io.BufferedReader;i...
再生产wsdl文件时重写描述文件1usingSystem;2usingSystem.Co...
一般情况下,使用eclipse自带的jax-ws生成webservice会自动生...