使用Jquery,Jackson JSON,JAX-RS,Apache Wink,Spring实现REST应用开发
简介
REST 是英文 Representational State Transfer 的缩写,有中文翻译为“具象状态传输”。相较于基于 SOAP 和 WSDL 的 Web 服务,REST 模式提供了更为简洁的实现方案。目前,越来越多的 Web 服务开始采用 REST 风格设计和实现。
REST中的一个重要概念是资源的存在性,每个资源都一个全局引用标识符,即URI。特别是数据和函数都被认为是可通过URI识别和访问的资源。为了操纵这些资源,网络组件,客户端和服务器通过一个标准的接口通信,如HTTP和一个组固定的动词 — GET,PUT,POST和DELETE — 交换这些资源。
JAX-RS为在Java中构建RESTful Web服务提供了标准化API,API提供了一组注解,以及相关的类和接口。对POJO应用注解允许你暴露Web资源,这个方法使得在Java中创建RESTful Web服务变得简单。
Apache Wink是一个简单而强大的RESTful Web服务创建框架。它由一个服务器端模块和一个客户端模块组成。Apache Wink的服务器端模块是JAX-RS1.0规范的一个完全实现。除了对基本协议的实现外,Apache Wink服务器端模块还提供了一系列便于开发RESTful Web服务的新特性。Apache Wink客户端模块提供了调用RESTful Web服务的相关功能,该模块基于JDK HttpURLConnection实现。
简单的说:REST是一种Web Service的设计模式,本文提到的实现方式,是从浏览器客户端借用jQuery发送Ajax请求到server端的Apache Wink提供的JAX-RS服务 (每个Resource是由spring负责实例化的) 从而实现WebService。
好了,废话不多说了,现在贴出具体的代码样例。
开发环境:
JDK1.5以上
Jquery1.4以上
jackson-all-1.6.2.jar
jsr311-api.jar
wink-server-1.1.2-incubating.jar
Spring2.0以上
JaxRSResource.java
--该接口没有任何方法,只是为了让spring过滤所有实现该接口的Resource
package com.cuishen.jaxrs.demo;public interface JaxRSResource {}
package com.cuishen.jaxrs.demo;import java.util.HashSet;import java.util.Set;import javax.ws.rs.core.Application;import com.cuishen.jaxrs.demo.factory.MyBeanFactory;;public class WinkApplication extends Application {public WinkApplication() { }@Overridepublic Set<Object> getSingletons() {String beans[] = MyBeanFactory.getBeanNamesForType(JaxRSResource.class);Set<Object> result = new HashSet<Object>();if (beans != null) {for (int i = 0; i < beans.length; i++) {String beanName = beans[i];result.add(MyBeanFactory.getBean(beanName));}}return result;}}
package com.cuishen.jaxrs.demo;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.ws.rs.*;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.codehaus.jackson.map.ObjectMapper;import com.cuishen.jaxrs.demo.bean.TestBean;@Path("/accountDemo")public class DemoResource implements JaxRSResource {private static final Log log = LogFactory.getLog(DemoResource.class);@POST@Path("/transactions/{id}")@Produces("application/json")public Map<String, String> getTransactions(@PathParam("id") String id) throws Exception {log.error("============================= successful getTransactions =================");Map<String, String> map = new HashMap<String, String>();map.put("id", id);return map;}@POST@Path("/transactions/")@Consumes("application/json")@Produces("application/json")public String getTransactions(HashMap<String, String> params) throws Exception {log.error("============================= successful getTransactions 2 =================");List<TestBean> list = new ArrayList<TestBean>();TestBean bean = new TestBean();String id = (String) params.get("id");bean.setId(id);bean.setName("xiao ming");list.add(bean);bean = new TestBean();bean.setId("222");bean.setName("xiao zhang");list.add(bean);ObjectMapper objectMapper = new ObjectMapper();String listJson = objectMapper.writeValueAsString(list);return listJson;}@POST@Path("/demoData")@Consumes("application/x-www-form-urlencoded")@Produces("application/json")public String getDemoData(@FormParam("id") String id, @FormParam("name") String name) throws Exception {log.error("============================= successful getDemoData =================");List<TestBean> list = new ArrayList<TestBean>();TestBean bean = new TestBean();bean.setId(id);bean.setName(name);list.add(bean);bean = new TestBean();bean.setId("222");bean.setName("xiao zhang");list.add(bean);ObjectMapper objectMapper = new ObjectMapper();String listJson = objectMapper.writeValueAsString(list);return listJson;}@POST@Path("/demoData")@Consumes("application/json")@Produces("application/json")public String getDemoData(HashMap<String, String> params) throws Exception {log.error("============================= successful getDemoData 2 =================");List<TestBean> list = new ArrayList<TestBean>();TestBean bean = new TestBean();String id = (String) params.get("id");bean.setId(id);String name = (String) params.get("name");bean.setName(name);String birthday = (String) params.get("birthday");bean.setBirthday(birthday);list.add(bean);bean = new TestBean();bean.setId("222");bean.setName("xiao zhang");list.add(bean);ObjectMapper objectMapper = new ObjectMapper();String listJson = objectMapper.writeValueAsString(list);return listJson;}}
package com.cuishen.jaxrs.demo.bean;import java.io.Serializable;//import org.codehaus.jackson.annotate.JsonProperty;public class TestBean implements Serializable {private static final long serialVersionUID = -8079868256837582676L;//@JsonProperty("id")private String id;//@JsonProperty("name")private String name;private String birthday;public String getBirthday() {return birthday;}public void setBirthday(String birthday) {this.birthday = birthday;}//@JsonProperty("id")public String getId() {return id;}//@JsonProperty("id")public void setId(String id) {this.id = id;}//@JsonProperty("name")public String getName() {return name;}//@JsonProperty("name")public void setName(String name) {this.name = name;}/**@Overridepublic String toString() {return "TestBean{" + "id='" + id + '\'' + ",name='" + name + '\'' + '}';}*/}
package com.cuishen.jaxrs.demo.factory;public class MyBeanFactory {public static String[] getBeanNamesForType(Class clazz) {// do something to get bean names for bean type from spring IOC containerreturn null;}public static Object getBean(String beanName) {// do something to get bean by beanName from spring IOC containerreturn null;}}
<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"><bean name="jaxrs.demo.accountDemo" name="code"><servlet><servlet-name>jaxrs</servlet-name><servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class><init-param><param-name>javax.ws.rs.Application</param-name><param-value>com.cuishen.jaxrs.demo.WinkApplication</param-value></init-param><load-on-startup>10</load-on-startup></servlet><servlet-mapping><servlet-name>jaxrs</servlet-name><url-pattern>/REST/*</url-pattern></servlet-mapping>
<form id="formDemo" name="formDemo" action="/DomainID/REST/accountDemo/demoData" method=post><input type="text" value="333333" id="id" name="id"><input type="text" value="ZhangSan" id="name" name="name"><input type="text" value="1981" id="birthday" name="birthday"></form><script type="text/javascript">function form2Json() {var formObj = $("#formDemo");var JsonObj = "'{";var a = formObj.serializeArray();var index = 0;$.each(a, function() {index++;JsonObj += """ + this.name + "":"" + this.value + """;if(a.length != 1 && a.length != index) {JsonObj += ",";}});JsonObj += "}'";return eval(JsonObj);}function doit() {// sample onejQuery.ajax({url:'/DomainID/REST/accountDemo/transactions/111111', type:'POST', dataType:'json', success:function(data, status, xhr) { // here you can do whatever is necessary with the data. alert("sample one"); alert(data.id); }, error:function(xhr,error,exception) { // handle the error. alert(exception.toString()); }});// sample two$.ajax({url:'/DomainID/REST/accountDemo/transactions', data:'{"id":222222}', type:'POST', dataType:'json', contentType:'application/json', success:function(data, status, xhr) { // here you can do whatever is necessary with the data. alert("sample two"); alert(data[0].id); alert(data[0].name); }, error:function(xhr,error,exception) { // handle the error. alert(exception.toString()); }});// sample three$.ajax({url:$("#formDemo").attr('action'),type:'POST',data:$("#formDemo").serialize(),dataType:'json',contentType:'application/x-www-form-urlencoded',success:function(data, status, xhr) {// here you can do whatever is necessary with the data.alert("sample three");alert(data[0].id);alert(data[0].name);},Error:function(xhr,error,exception) {// handle the error.alert(exception.toString());}});// sample four$.ajax({url:$("#formDemo").attr('action'),type:'POST',data:form2Json(),dataType:'json',contentType:'application/json',success:function(data, status, xhr) {// here you can do whatever is necessary with the data.alert("sample four");alert(data[0].id);alert(data[0].name);alert(data[0].birthday);},Error:function(xhr,error,exception) {// handle the error.alert(exception.toString());}});}</SCRIPT><input type="button" value="click me" onclick="doit()">