浅谈REST原理
REST与RPC(Rmote Procedure Call)几乎没有任何关系,RPC是面向服务的,并关注行为和动作;而REST是面向资源的,强调描述应用程序的事物和名词。尽管URL在REST中起了关键作用,但它们仅仅是整体的一部分而已。
更简洁的讲,REST就是将资源的状态以合适的形式从服务端转移到客户端(或者反之)。
【Spring本身也提供对REST的支持,但本章我们只是对CXF的RESTful进行简单应用】
环境
JDK7.0 + Tomcat7.x + Spring4.1.8
项目结构
服务端代码
a) IRESTfulWebService
package com.restful.base.service;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import com.restful.base.vo.LoginUser;
public interface IRESTfulWebService {
@GET
@Path(value = "/{id}/info")
@Consumes( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
String findById(@PathParam("id") String id);
@GET
@Path(value = "/search")
@Consumes( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
String findByAll();
@GET
@Path(value = "/{loginId}/user")
@Consumes( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
LoginUser findUserById(@PathParam("loginId") String loginId);
}
b) RESTfulWebServiceImp(接口实现类)
package com.restful.base.service.imp;
import org.apache.log4j.Logger;
import com.restful.base.service.IRESTfulWebService;
import com.restful.base.vo.LoginUser;
public class RESTfulWebServiceImp implements IRESTfulWebService {
private static final Logger log = Logger.getLogger(RESTfulWebServiceImp.class);
@Override
public String findById(String id) {
log.info("---RESTful webservice测试--- param:"+id);
return "restful webservice test success! id="+id;
}
@Override
public String findByAll() {
log.info("---RESTful webservice测试---");
return "restful webservice test success!";
}
@Override
public LoginUser findUserById(String loginId) {
log.info("---RESTful webservice测试--- loginid:"+loginId);
return this.getUserInfo();
}
//模拟数据库赋值
private LoginUser getUserInfo(){
LoginUser user = new LoginUser();
user.setId("123");
user.setLoginid("login1");
user.setPwd("pwd123");
user.setRegisterDate("2015-11-04");
user.setStatus("1");
return user;
}
}
指定多个MIME类型
@Produces({“application/json”,“application/xml”})
@Consumes
@Consumes与@Produces相反,用来指定可以接受client发送过来的MIME类型,也可以指定多个MIME类型
c) applicationContext-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:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd ">
<!-- 日志拦截 -->
<bean id="inMessageInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="outMessageInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<!-- RESTful webservice -->
<bean id="service" class="com.restful.base.service.imp.RESTfulWebServiceImp" />
<jaxrs:server id="rest1" address="/hello">
<jaxrs:serviceBeans>
<ref bean="service" />
</jaxrs:serviceBeans>
<jaxrs:inInterceptors>
<ref bean="inMessageInterceptor"/>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<ref bean="outMessageInterceptor"/>
</jaxrs:outInterceptors>
</jaxrs:server>
</beans>
访问页面
客户端代码
a)RESTfullCilent
package com.restful.base.webclient;
import java.lang.reflect.Field;
import javax.ws.rs.core.MediaType;
import org.apache.cxf.jaxrs.client.WebClient;
import com.restful.base.vo.LoginUser;
public class RESTfullCilent {
private static final String CATEGORY_URL = "http://localhost:8080/cxfrestful/webservice";
private static final String path1 = "/hello/005/info";
private static final String path2 = "/hello/search";
private static final String path3 = "/hello/log1/user";
public static void main(String[] args) throws Exception {
String str = webClient(path1,String.class);
System.out.println("RESTful 测试1,服务端返回信息:"+str);
str = webClient(path2,String.class);
System.out.println("RESTful 测试2,服务端返回信息:"+str);
LoginUser user = null;
user = webClient(path3,LoginUser.class);
System.out.println("RESTful 测试3,服务端返回信息:");
Field[] file = LoginUser.class.getDeclaredFields();
for (int i = 0; i < file.length; i++) {
Field f = file[i];
f.setAccessible( true ); // 设置些属性是可以访问的
Object val = f.get(user); // 得到此属性的值
System.out.print(" "+f.getName()+"="+val);
}
}
private static <T> T webClient(String path,Class<T> c){
T t =null;
WebClient client = WebClient.create(CATEGORY_URL).path(path);
t = client.accept(MediaType.APPLICATION_XML).get(c);
return t;
}
}