`
sb33060418
  • 浏览: 152239 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

REST(三)Restlet实现REST

    博客分类:
  • REST
阅读更多
Restlet项目为“建立REST概念与Java类之间的映射”提供了一个轻量级而全面的框架。它可用于实现任何种类的REST式系统,而不仅仅是REST式Web服务。
Restlet参考REST标准的术语,如:资源(resource)、表示(representation)、连接器(connector)、组件(component)、媒体类型(media type)、语言(language),等等。Restlet增加了一些专门的类(如Application、Filter、Finder、Router和Route),用以简化restlets的彼此结合,以及简化把收到的请求(incoming requests)映射为处理它们的资源。

其他Restlet介绍见:Restlet 入门。本节简单介绍restlet2+spring4的集成及客户端访问。

1.spring web基础环境
见上一节Jersey创建的web工程testRest。

2.REST地址
与上一节类似,设计restlet模块rest接口地址:
/restlet/teachers GET 获取所有资源
/restlet/teachers POST 创建新资源,content中包含资源内容
/restlet/teacher/{id} GET 获取编号为id的资源
/restlet/teacher/{id} PUT 更新编号为id的资源,content中包含资源内容
/restlet/teacher/{id} DELETE 删除编号为id的资源

3.restlet库
在项目pom.xml中加入Restlet依赖:
<repositories>
	<repository>
		<id>maven-restlet</id>
		<name>Restlet repository</name>
		<url>https://maven.restlet.com</url>
	</repository>
</repositories>
<properties>
	<restlet.version>2.3.5</restlet.version>
	<fastjson.version>1.2.7</fastjson.version>
</properties>
<dependencies>	
	...
	<!-- restlet begin -->
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.json</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.spring</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.servlet</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.xml</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.oauth</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<!-- json 相关jar包 -->
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>fastjson</artifactId>
		<version>${fastjson.version}</version>
	</dependency>
	<dependency>
		<groupId>com.google.guava</groupId>
		<artifactId>guava</artifactId>
		<version>${guava.version}</version>
	</dependency>
	<!-- restlet end -->
	...

Restlet使用版本2.3.5,并加入servlet、spring、json、xml等包。因Restlet库不在中央仓库中,所以要加入https://maven.restlet.com仓库。

4.Servlet
配置Restlet访问入口。
<!-- restlet -->
<servlet>
	<servlet-name>restlet</servlet-name>
	<servlet-class>org.restlet.ext.spring.SpringServerServlet</servlet-class>
	<init-param>
		<param-name>org.restlet.component</param-name>
		<param-value>component</param-value>
	</init-param>
</servlet>
<servlet-mapping>
	<servlet-name>restlet</servlet-name>
	<url-pattern>/restlet/*</url-pattern>
</servlet-mapping>

Restlet Servlet将拦截/restlet/*下的所有访问。
Restlet与web、spring集成后,不需要再自己实现Router、Application、Component。但需要在spring中进行配置。
在配置文件目录src\main\resources\下创建restlet配置目录config\restlet,并创建配置文件restlet.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:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
						http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
	default-autowire="byName" default-lazy-init="true">

	<bean id="component" class="org.restlet.ext.spring.SpringComponent">
		<property name="defaultTarget" ref="router" />
	</bean>
	<bean id="router" class="org.restlet.ext.spring.SpringBeanRouter"></bean>

</beans>

此处定义的component bean将被web.xml配置的Restlet servlet引用。

5.实现api
在com.sunbin.test.restlet新增TeachersResource类,以实现/teachers路径的接口:
package com.sunbin.test.restlet;

import java.util.HashMap;
import java.util.Map;

import org.restlet.data.Form;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.sunbin.test.teacher.pojo.Teacher;
import com.sunbin.test.teacher.service.TeacherService;

public class TeachersResource extends ServerResource {

	@Autowired
	private TeacherService teacherService;

	@Get
	public Representation get() {
		System.out.println("Restlet TeachersResource.get");
		Map map = new HashMap();
		map.put("teachers", teacherService.list());
		return new JsonRepresentation(JSON.toJSONString(map));
	}
	
	@Post("*:json")
	public Representation post(Representation entity){
		Map map = new HashMap();
		try {
			Form form = new Form(entity);
			System.out.println("Restlet TeachersResource.post:"+form);
			Teacher teacher = new Teacher();
			teacher.setName(form.getFirstValue("name"));
			teacher.setAge(Integer.parseInt(form.getFirstValue("age")));
			teacherService.save(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new JsonRepresentation(JSON.toJSONString(map));
	}
}

用到了以下Restlet自带注解:
@Get:GET请求的响应方法。
@Post("*:json"):POST请求的响应方法,指定*可接受各种Content-Type的请求数据,json可返回Content-Type:application/json数据。

需要注意的是,Restlet自带的json返回new JsonRepresentation(map)会对Map中的键值简单调用toString,再返回json串例如:{"teachers":["Teacher [id=1, age=1, name=a]","Teacher [id=2, age=2, name=b]"]},这就不是标准json了。所以干脆使用阿里的fastjson库先将结果转成JSONString,再返回:{"teachers":[{"age":1,"id":1,"name":"a"},{"age":2,"id":2,"name":"b"}]}。

新增TeacherResource类,以实现/teacher/{id}路径的接口:
package com.sunbin.test.restlet;


import java.util.HashMap;
import java.util.Map;


import org.restlet.data.Form;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Put;
import org.restlet.resource.ServerResource;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.sunbin.test.teacher.pojo.Teacher;
import com.sunbin.test.teacher.service.TeacherService;

public class TeacherResource extends ServerResource{

	@Autowired
	private TeacherService teacherService;

	@Get
	public Representation get(){
		String id = (String)getRequest().getAttributes().get("id");
		System.out.println("Restlet TeacherResource.get:"+id);
		Teacher teacher = new Teacher();
		teacher.setId(Integer.parseInt(id));
		Map map = new HashMap();
		map.put("teacher", teacherService.get(teacher));
		return new JsonRepresentation(JSON.toJSONString(map));
	}

	@Put	
	public Representation put(Representation entity){
		Map map = new HashMap();
		try {
			String id = (String)getRequest().getAttributes().get("id");
			Form form = new Form(entity);
			System.out.println("Restlet TeacherResource.put:"+id+":"+form);
			Teacher teacher = new Teacher();
			teacher.setId(Integer.parseInt(id));
			teacher.setName(form.getFirstValue("name"));
			teacher.setAge(Integer.parseInt(form.getFirstValue("age")));
			teacherService.update(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new JsonRepresentation(JSON.toJSONString(map));
	}

	@Delete
	public Representation delete(){
		Map map = new HashMap();
		try {
			String id = (String)getRequest().getAttributes().get("id");
			System.out.println("Restlet TeacherResource.delete:"+id);
			Teacher teacher = new Teacher();
			teacher.setId(Integer.parseInt(id));
			teacherService.remove(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new JsonRepresentation(JSON.toJSONString(map));
	}
}

同样使用的不是JAX-RS注解,而是Restlet自带注解(大小写不同)。

restlet的路径绑定需要配置在spring文件中。在restlet.xml中增加配置:
	<bean name="/teacher/{id}" id="teacherResource"
		class="com.sunbin.test.restlet.TeacherResource" scope="prototype">
	</bean>
	<bean name="/teachers" id="teachersResource"
		class="com.sunbin.test.restlet.TeachersResource" scope="prototype">
	</bean>


6.js测试
使用上一节的测试页面src\main\webapp\rest\index.jsp进行测试:
...
	<script type="text/javascript">
		// 测试框架
		//var restType = "jersey";
		var restType = "restlet";
		//var restType = "resteasy";
		//var restType = "restCxf";
		//var restType = "restMvc";
...

重新部署后,使用浏览器访问http://localhost:8080/testRest/rest,测试内容和jersey测试相同。

7.RestletClient测试
Restlet提供Client库用于测试REST接口。
新建TestRestlet类,代码如下:
package com.sunbin.test.restlet;

import java.io.IOException;

import org.restlet.resource.ClientResource;
import org.restlet.resource.ResourceException;

public class TestRestlet {

	public static final String URL_BASE = "http://localhost:8080/testRest/restlet/";

	/**
	 * @param args
	 * @throws IOException
	 * @throws ResourceException
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		String module = "teacher";
		String url = "";
		ClientResource client = null;
		String entity = "";
		String result = "";

		url = URL_BASE + module + "s";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("post\t " + url);
		client = new ClientResource(url);
		entity = "name=a&age=1";
		result = client.post(entity).getText();
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);

		url = URL_BASE + module + "/1";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);

		url = URL_BASE + module + "/1";
		System.out.println("put\t " + url);
		client = new ClientResource(url);
		entity = "name=aa&age=11";
		result = client.put(entity).getText();
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);

		url = URL_BASE + module + "/1";
		System.out.println("delete\t " + url);
		client = new ClientResource(url);
		result = client.delete().getText();
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);
	}

}

测试结果与Jersey类似。

8.部署至jboss
将Restlet Web工程部署至jboss,会因为jboss类加载配置导致无法启动。
需要修改jboss目录/modules/system/layers/base/sun/jdk/main下的module.xml文件:
<dependencies>
	<system export="true">
		<paths>
			...
			<path name="com/sun/net/httpserver"/>
			...

加入httpserver配置行。

9.Restlet访问session
Restlet不推荐在Resource中访问会话信息,因为这是违背REST的无状态设计的。
但如果需要在Resource中访问Session,可以按以下代码获取:
import org.restlet.Request;
import org.restlet.engine.adapter.HttpRequest;
import org.restlet.engine.adapter.ServerCall;
import org.restlet.ext.servlet.internal.ServletCall;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

...
Request request = getRequest();
if (request instanceof HttpRequest) {
	final ServerCall httpCall = ((HttpRequest) request)
			.getHttpCall();
	if (httpCall instanceof ServletCall) {
		HttpServletRequest httpServletRequest = ((ServletCall) httpCall)
				.getRequest();
		HttpSession session = httpServletRequest.getSession();
...
分享到:
评论

相关推荐

    restlet实现最简单的restful webservice

    本文将深入探讨如何使用Restlet来实现一个最简单的RESTful Web服务。 首先,了解REST的基本概念是必要的。REST强调的是资源的概念,通过URI(Uniform Resource Identifier)来标识,使用HTTP协议中的方法(如GET、...

    restlet restful

    在Restlet框架中,"RestApplication"可能是一个实现了Restlet Application接口的类,负责初始化和管理REST服务的路由和行为。 总的来说,"restlet restful"项目是一个基于RESTlet框架的RESTful Web服务实现,提供了...

    RESTLET开发(三)

    ### RESTLET开发(三):基于Spring的REST服务 #### 一、基于Spring配置的Rest简单服务 在本文档中,我们将深入探讨如何利用RESTlet框架与Spring框架结合,构建高效的RESTful服务。Spring框架因其强大的功能和灵活...

    Restlet Client - REST API Testing

    Restlet Client - REST API Testing,用来发送请求,可用于测试后端代码,简单易用

    Restlet学习的三篇文章

    Restlet框架提供了更底层的REST服务实现,它不仅支持JAX-RS规范,还提供了自己的API。Restlet组件模型包括客户端和服务器端的部分,如代表资源的`Representation`、处理请求的`Resource`、管理网络连接的`Connector...

    JAX-RS Rest RestLet项目源码

    RESTLet是JAX-RS的一个实现,它提供了一种灵活的方式来构建RESTful应用程序。RESTLet框架支持多种功能,包括URI模板、过滤器、客户端代理、安全性和国际化。这个框架特别适合于那些希望以更直接和自定义的方式处理...

    Restlet Client - REST API Testing(DHC)

    **REST API 测试工具——Restlet Client (DHC)** 在现代软件开发中,REST (Representational State Transfer) API已经成为构建分布式系统和服务交互的主要方式。它们提供了轻量级、无状态和基于HTTP协议的接口,...

    Restlet开发实例

    最后,"RESTLET开发实例(三)基于spring的REST服务.doc"会介绍如何将Restlet与Spring框架集成。Spring是Java企业级应用开发的主流框架,提供了丰富的功能和优秀的依赖注入机制。结合Spring,Restlet服务可以利用...

    Restlet Client 插件安装包

    6. **自动化测试**: 虽然`Restlet Client`主要作为手动测试工具,但通过编写脚本,也可以实现一定程度的自动化测试。 7. **安全性**: 支持OAuth 2.0和其他身份验证机制,保障API测试的安全性。 ### 使用场景 - **...

    Restlet-Client-REST-API-Testing_v2.8.0.1

    Restlet Client是一款强大的REST API测试工具,尤其在与Chrome浏览器结合使用时,它能为开发者提供便捷的API接口测试和调试功能。此版本为v2.8.0.1,表明这是一个更新到一定稳定性的软件,可能包含了之前版本的改进...

    chromecj.com-Restlet-Client-REST-API-Testing_v2.8.0.1.zip

    "chromecj.com-Restlet-Client-REST-API-Testing_v2.8.0.1.zip" 是一个针对 Chrome 浏览器的扩展程序包,主要用于 REST API 的测试。Restlet Client 是一个强大的工具,它使得开发者和测试人员能够轻松地进行 ...

    Restlet Client - REST API Testing.crx

    Chrome插件 Visually create and run single HTTP requests as well as complex scenarios. Automate your API tests with our CI/CD plugin.

    Web Api调试工具 Chrome插件Restlet-Client-REST-API-Testing

    Chrome插件Restlet Client - REST API Testing是一款非常实用的工具,专为Web API的调试和测试设计。这款插件支持多种HTTP方法(如GET、POST、PUT、DELETE等),并提供了丰富的功能,使得API测试过程更加高效和便捷...

    restlet

    RESTlet是一款开源框架,专为构建基于REST(Representational State Transfer)原则的Web服务和应用程序设计。REST是一种轻量级的架构风格,广泛应用于互联网应用的开发,它强调通过简单的HTTP方法(如GET、POST、...

    restlet-jee-2.0.6.zip_Restlet 2..0_Restlet framework2.0_org.rest

    1. **组件模型**:Restlet框架采用组件模型,使得开发者可以轻松地定义资源(Resource)和代表资源的服务器端点(ServerResource)以及客户端代理(ClientProxy),以实现REST原则。 2. **统一API**:Restlet提供了...

    restlet-client-rest-api-t.crx

    restlet-client 谷歌插件 接口调试 最新

    chromecj.com-Restlet-Client-REST-API-Testing_v2.8.0.1.rar

    6. **自动化测试**:虽然不如Postman的脚本功能强大,但Restlet Client仍然允许进行基本的测试脚本编写,以实现简单的自动化测试。 7. **安全性**:它支持HTTPS,确保敏感信息在传输过程中的安全。 8. **API文档...

    restlet-jse-2.1.1.zip

    Restlet项目为“建立REST概念与Java类之间的映射”提供了一个轻量级而全面的框架。它可用于实现任何种类的REST式系统,而不仅仅是REST式Web服务;而且,事实证明它自从2005年诞生之时起,就是一个可靠的软件。 ...

Global site tag (gtag.js) - Google Analytics