`
cuishen
  • 浏览: 297314 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

	@Override
	public 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;
	}
	/**
	@Override
	public 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 container
		return null;
	}
	public static Object getBean(String beanName) {
		// do something to get bean by beanName from spring IOC container
		return 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" class="com.cuishen.jaxrs.demo.DemoResource">
	</bean>

</beans>

web.xml
--这个也不用说了吧
<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 one
jQuery.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两边要一致。

分享到:
评论
3 楼 three_st 2013-08-01  
请问楼主怎么支持的Map参数,谢谢
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。
1 楼 lfy2008 2012-08-09  
总算找了个可以用的 ,400报了一天的错误,JAXBException occurred : unexpected element (uri:"", local:"name"). ,用@FormParam总算可以了,楼主,@FormParam("name")里面写Bean怎么不支持啊?如果表单里面有很多参数,怎么封装提交啊?求解

相关推荐

    jackson-jaxrs-json-provider-2.7.8-API文档-中文版.zip

    赠送jar包:jackson-jaxrs-json-provider-2.7.8.jar; 赠送原API文档:jackson-jaxrs-json-provider-2.7.8-javadoc.jar; 赠送源代码:jackson-jaxrs-json-provider-2.7.8-sources.jar; 赠送Maven依赖信息文件:...

    jackson-jaxrs-json-provider-2.7.8-API文档-中英对照版.zip

    赠送jar包:jackson-jaxrs-json-provider-2.7.8.jar; 赠送原API文档:jackson-jaxrs-json-provider-2.7.8-javadoc.jar; 赠送源代码:jackson-jaxrs-json-provider-2.7.8-sources.jar; 赠送Maven依赖信息文件:...

    jax-rs jax-ws所需包,亲测可用

    标题"jax-rs jax-ws所需包,亲测可用"表明这个压缩包包含了用于开发Java RESTful Web服务(JAX-RS)和Java SOAP Web服务(JAX-WS)所需的库文件。这些库是Java应用程序进行Web服务交互的核心组件,确保了对HTTP协议...

    JAX-RS+spring

    3. **实体序列化与反序列化**: JAX-RS支持自动将Java对象转换为JSON或XML,反之亦然,这通常通过实现MessageBodyReader/Writer接口或者使用库如Jackson或Gson完成。 4. **提供者与容器**: JAX-RS不强制使用特定的...

    [Jax-RS] RESTful Java 开发 (Jax-RS 实现) (英文版)

    [奥莱理] RESTful Java 开发 (Jax-RS 实现) (英文版) [奥莱理] RESTful Java with Jax-RS (E-Book) ☆ 图书概要:☆ Learn how to design and develop distributed web services in Java using RESTful ...

    [Jax-RS] RESTful Java 开发 (Jax-RS 2.0 实现) (英文版)

    [奥莱理] RESTful Java 开发 (Jax-RS 2.0 实现) (英文版) [奥莱理] RESTful Java with JAX-RS 2.0 (E-Book) ☆ 图书概要:☆ Learn how to design and develop distributed web services in Java, using RESTful ...

    jackson-jaxrs-json-provider-2.2.4.zip

    3. **Jackson JAX-RS JSON Provider**:将Jackson的功能集成到JAX-RS应用中,使得REST服务能够方便地处理JSON输入和输出。 4. **Cloud Foundry**:一个流行的PaaS平台,支持多种语言的应用部署,包括Java。 5. **...

    jackson-jaxrs-providers:包含用于JSON,XML,YAML,Smile,CBOR格式的基于Jackson的JAX-RS提供程序的多模块项目

    概述这是一个多模块项目,包含用于以下数据格式的基于Jackson的JAX-RS提供程序:(二进制JSON) (另一种二进制JSON) 提供程序实现特定数据格式的JAX-RS MessageBodyReader和MessageBodyWriter处理程序。...

    Jax-RS所需要的依赖jar

    7. **其他依赖**:除了上述核心组件外,"JAX-RS-Lib"可能还包括其他必要的依赖,如XML解析库(如JAXB,用于对象到XML的绑定),JSON库(如Jackson或Gson,用于处理JSON数据),以及HTTP连接管理库(如Apache ...

    java_webservice_JAX-RS.zip_cxf_jax_jax-rs_spring cxf

    Java Web服务,特别是JAX-RS(Java API for RESTful Web Services)和Apache CXF,是企业级应用程序中实现服务接口的重要技术。本教程将深入探讨如何在SSH(Spring、Struts、Hibernate)架构中集成Web服务,以及如何...

    一个包含jax-ws和jax-rs的例子(含服务端和客户端)

    标题中的“一个包含jax-ws和jax-rs的例子(含服务端和客户端)”是指这是一个示例项目,它演示了如何使用Java API for XML Web Services (JAX-WS)和Java API for RESTful Web Services (JAX-RS)来创建和消费Web服务。...

    JAX-WS API, JAX-RS API

    JAX-RS的实现有多个,如Jersey、RESTEasy、RESTlet等,它们为开发人员提供了方便的工具集,使得构建RESTful服务变得更加简单和高效。 综上所述,JAX-WS和JAX-RS都是Java平台中处理Web服务的重要工具,但它们的侧...

    SpringMVC精品资源--JAX-RS &amp; SpringMVC supported maven buil.zip

    SpringMVC和JAX-RS是两种在Java世界中广泛使用的Web开发框架,它们都用于构建RESTful服务,但有着不同的设计哲学和技术实现。这个压缩包"SpringMVC精品资源--JAX-RS & SpringMVC supported maven build.zip"显然是一...

    jackson-jaxrs-json-provider-2.8.8.jar

    java运行依赖jar包

    Spring MVC与JAX-RS比较与分析

    目前共有4种JAX-RS实现,所有这些实现都支持Spring,Jersey则是JAX-RS的参考实现,也是本文所用的实现。 如果你使用Spring进行开发,那可能想知道(或者有人曾问过你)Spring MVC与JAX-RS有何异同点?更进一步,...

    JAX-RS入门jar包集合

    JAX-RS通过提供一套简单的注解和API,使得开发者能轻松地在Java应用中实现REST服务。 本资源“JAX-RS入门jar包集合”包含了开始学习和使用JAX-RS所需的基本库文件,这些jar包将帮助开发者快速搭建REST服务环境。...

    JAX-RS cxf web服务 rest简单增删改查 集成spring webService

    本篇文章将深入探讨如何使用CXF和Spring框架实现基于JAX-RS的Web服务,包括基本的增、删、改、查操作。 1. **环境准备** - **JDK**: 首先确保安装了支持JAX-RS的Java版本,通常JDK 8或以上。 - **Maven**: 项目...

    JAX-RS之rest接口实例

    **JAX-RS与REST接口实例详解** JAX-RS(Java API for RESTful Web Services)是Java平台上的一个标准,用于创建RESTful Web服务。REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式...

    JAX-RS包(内含1.0和1.4)

    JAX-RS通过提供一套简单易用的API,使得开发者可以轻松地在Java应用中创建REST接口。 本压缩包包含JAX-RS的两个版本,即1.0和1.4。这两个版本主要的区别在于功能的完善和对标准的遵循程度。JAX-RS 1.0是最初的规范...

    JAX-RS Extension

    4. **RESTlet框架**:RESTlet是一个开源的JAX-RS实现,它不仅提供了标准的REST服务开发支持,还引入了组件模型,允许更细粒度的服务构建。RESTlet支持多种角色,如客户端、服务器端和网关,使得开发者可以更轻松地...

Global site tag (gtag.js) - Google Analytics