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