首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 服务器 > Apache >

运用Jquery,Jackson JSON,JAX-RS,Apache Wink,Spring实现REST应用开发

2012-11-23 
使用Jquery,Jackson JSON,JAX-RS,Apache Wink,Spring实现REST应用开发简介 REST 是英文 Representational

使用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 {}

WinkApplication.java
--继承自javax.ws.rs.core.Application,并重写getSingletons(),在该方法中调用spring的getBean()接口,并过滤出所有实现了JaxRSResource接口的bean,然后返回给Application
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;}}

DemoResource.java
--具体的Resource实现,实现JaxRSResource接口,也是spring托管的一个bean
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;}}

TestBean.java
--Json序列化时要用到
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 + '\''  + '}';}*/}

MyBeanFactory.java
--这个大家都懂的,具体的实现自己看着办吧
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;}}

spring-application-context-jaxrs-demo.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: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>

index.jsp
<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()">


ok!代码演示完了,有几个注意点:
1. 如果遇到404 Not Found的错,肯定是Ajax请求找不到URL或者说那个resource里面的方法。
2. 不仅方法名,参数要匹配,而且参数类型也要匹配。
3. resource里面,@Consumes("application/json")表示请求的数据类型是json,@Produces("application/json")表示返回的数据类型是json
4. js里面,contentType:'application/json'表示发出的请求要以json为数据格式,dataType:'json'表示接收的数据类型为json
5. POST和GET都可以,但是js和resource两边要一致。

1 楼 lfy2008 2012-08-09   总算找了个可以用的 ,400报了一天的错误,JAXBException occurred : unexpected element (uri:"", local:"name"). ,用@FormParam总算可以了,楼主,@FormParam("name")里面写Bean怎么不支持啊?如果表单里面有很多参数,怎么封装提交啊?求解 2 楼 cuishen 2012-08-10   lfy2008 写道总算找了个可以用的 ,400报了一天的错误,JAXBException occurred : unexpected element (uri:"", local:"name"). ,用@FormParam总算可以了,楼主,@FormParam("name")里面写Bean怎么不支持啊?如果表单里面有很多参数,怎么封装提交啊?求解
请参考sample three。

可能你更想要的答案是sample four,但是sample four可能会导致乱码的问题,我一直没有很好的解决办法,所以我还是推荐sample three。

热点排行