REST(三)Restlet实现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依赖:

	
		maven-restlet
		Restlet repository
		https://maven.restlet.com
	


	2.3.5
	1.2.7

	
	...
	
	
		org.restlet.jee
		org.restlet
		${restlet.version}
	
	
		org.restlet.jee
		org.restlet.ext.json
		${restlet.version}
	
	
		org.restlet.jee
		org.restlet.ext.spring
		${restlet.version}
	
	
		org.restlet.jee
		org.restlet.ext.servlet
		${restlet.version}
	
	
		org.restlet.jee
		org.restlet.ext.xml
		${restlet.version}
	
	
		org.restlet.jee
		org.restlet.ext.oauth
		${restlet.version}
	
	
	
		com.alibaba
		fastjson
		${fastjson.version}
	
	
		com.google.guava
		guava
		${guava.version}
	
	
	...

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

4.Servlet
配置Restlet访问入口。


	restlet
	org.restlet.ext.spring.SpringServerServlet
	
		org.restlet.component
		component
	


	restlet
	/restlet/*


Restlet Servlet将拦截/restlet/*下的所有访问。
Restlet与web、spring集成后,不需要再自己实现Router、Application、Component。但需要在spring中进行配置。
在配置文件目录src\main\resources\下创建restlet配置目录config\restlet,并创建配置文件restlet.xml:



	
		
	
	



此处定义的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中增加配置:
	
	
	
	


6.js测试
使用上一节的测试页面src\main\webapp\rest\index.jsp进行测试:
...
	
                    
                    

你可能感兴趣的:(rest,spring,restlet)