REST的架构设计与实现
REST(Representational State Transfer)是一种轻量级的Web Service架构风格,其实现和操作明显比SOAP和XML-RPC更为简洁,可以完全通过HTTP协议实现,还可以利用缓存Cache来提高响应速度,性能、效率和易用性上都优于SOAP协议。
REST架构遵循了CRUD原则,CRUD原则对于资源只需要四种行为:Create(创建)、Read(读取)、Update(更新)和Delete(删除)就可以完成对其操作和处理。这四个操作是一种原子操作,即一种无法再分的操作,通过它们可以构造复杂的操作过程,正如数学上四则运算是数字的最基本的运算一样。
REST架构让人们真正理解我们的网络协议HTTP本来面貌,对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法:
1) 使用HTTP POST方法去创建 资源
2) 使用HTTP GET方法去读取 资源
3) 使用HTTP PUT 方法去更新 资源
4) 使用HTTP DELETE方法去删除 资源
因此REST把HTTP对一个URL资源的操作限制在GET、POST、PUT和DELETE这四个之内。这种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
REST的设计准则
REST架构是针对Web应用而设计的,其目的是为了降低开发的复杂性,提高系统的可伸缩性。REST提出了如下设计准则:
网络上的所有事物都被抽象为资源(resource);
每个资源对应一个唯一的资源标识符(resource identifier);
通过通用的连接器接口(generic connector interface)对资源进行操作;
采用通用的连接器接口HTTP。
对资源的各种操作不会改变资源标识符;
所有的操作都是无状态的(stateless)。
客户端发送的请求中包含足够多的信息让服务器理解此次请求,而服务器端不保存上下文信息,只负责提供resource以及操作resource的服务,而client要根据resource中的data和representation自己做render,这就减少了服务器的开销。
使用REST架构
对于开发人员来说,关心的是如何使用REST架构,这里我们来简单谈谈这个问题。REST不仅仅是一种崭新的架构,它带来的更是一种全新的Web开发过程中的思维方式:通过URL来设计系统结构。REST是一套简单的设计原则、一种架构风格(或模式),不是一种具体的标准或架构。REST有很多成功的使用案例,著名的Delicious和Flickr都提供基于REST风格的API使用,客户端调用也极其方便,下面是我用JSP写的一个很简单的REST举例,从中可以看出REST是多么的简单易用。
客户端脚本采用Javascript:
/* * 函数名:getTransport * 功能: 根据不同的浏览器对象创建 XMLHttpRequest对象并返回,如果浏览器不支持该对象,则返回undefined. */ function getHttpRequest() { var xmlhttp; try { xmlhttp=new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) { try { xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); } catch(e1) { xmlhttp=new XMLHttpRequest(); } } return xmlhttp; } function httpGet(url,method,data) { var httpget=null; var xmlhttp=getHttpRequest(); xmlhttp.open(method,url +"?"+data,false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.setRequestHeader("Content-Length",data.length); xmlhttp.send (null); if (xmlhttp.readyState==4) { if(xmlhttp.Status ==200) {httpget=xmlhttp.responseText; } else { httpget="error"; } xmlhttp =null; } return httpget; } function httpPut(url, method, data){ var httpget=null; var xmlhttp=getHttpRequest(); xmlhttp.open(method,url,false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.setRequestHeader("Content-Length", data.length); xmlhttp.send(data); if (xmlhttp.readyState==4) { if(xmlhttp.Status >=400 && xmlhttp.Status <=599) httpget="Error Occurred : "& xmlhttp.Status & "-" & xmlhttp.statusText; else httpget=xmlhttp.responseText; xmlhttp =null; } return httpget; } function httpPost(url, method, data){ var httpget=null; var xmlhttp=getHttpRequest(); xmlhttp.open(method, url,false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.setRequestHeader("Content-Length",data.length); xmlhttp.send(data); if (xmlhttp.readyState==4) { if(xmlhttp.Status ==200) { httpget=xmlhttp.responseText; } else { httpget="error"; } xmlhttp=null; } return httpget; } function httpDelete(url, method, data){ var httpget=null; var xmlhttp=getHttpRequest(); xmlhttp.open(method, url + "?" + data,false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.setRequestHeader("Content-Length", data.length); xmlhttp.send(null); if (xmlhttp.readyState==4) { if(xmlhttp.Status >=400 && xmlhttp.Status <=599) httpget="Error Occurred : "& xmlhttp.Status & "-" & xmlhttp.statusText; else httpget=xmlhttp.responseText; xmlhttp =null; } return httpget; }
客户端调用:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>REST 架构测试页面</title> <script type="text/javascript" src="script/ajaxRequest.js"></script> <script type="text/javascript"> function sendHttpGet() { document.getElementById("showinfo").innerHTML+=httpGet("handlerestquest", "GET", "do=你向服务器发送了GET请求"); } function sendHttpPut() { document.getElementById("showinfo").innerHTML+=httpPut("handlerestquest", "PUT", "你向服务器发送了PUT请求"); } function sendHttpPost() { document.getElementById("showinfo").innerHTML+=httpPost("handlerestquest", "POST", "do=你向服务器发送了POST请求"); } function sendHttpDelete() { document.getElementById("showinfo").innerHTML+=httpDelete("handlerestquest", "DELETE", "do=你向服务器发送了DELETE请求"); } </script> </head> <body> <input type="button" value="GET操作" onclick="sendHttpGet()"> <input type="button" value="PUT操作" onclick="sendHttpPut()"> <input type="button" value="POST操作" onclick="sendHttpPost()"> <input type="button" value="DELETE操作" onclick="sendHttpDelete()"> <hr> <div id="showinfo"></div> </body> </html>
web.xml配置文件:
httpGet("handlerestquest", "GET", "do=你向服务器发送了GET请求");是发送请求的url与web.xml配置文件中的<url-pattern>一致。
<servlet-class>中字段值是服务器servlet的类名。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <servlet> <servlet-name>HandleRestServlet</servlet-name> <servlet-class>com.my.RestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HandleRestServlet</servlet-name> <url-pattern>/handlerestquest</url-pattern> </servlet-mapping> </web-app>
服务器端:
package com.my; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.io.*; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class RestServlet extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { //指定 去除客户端页面的缓存 //指定 去除客户端页面的缓存 ClearCache(response); request.setCharacterEncoding("utf-8"); String operation=new String((request.getParameter("do")).getBytes("iso-8859-1")); response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); PrintWriter out=response.getWriter(); out.println(operation+"<br>"); System.out.println(operation); out.flush(); out.close(); } public void doPut(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { //指定 去除客户端页面的缓存 ClearCache(response); BufferedReader sis = request.getReader(); String operation1=new String(sis.readLine().getBytes("iso-8859-1"),"utf-8"); System.out.println(operation1); //sb为POST过来的数据 response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); PrintWriter out=response.getWriter(); out.println(operation1+"<br>"); out.flush(); out.close(); } public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { //指定 去除客户端页面的缓存 ClearCache(response); String operation=new String(request.getParameter("do").getBytes("iso-8859-1"),"utf-8"); response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); PrintWriter out=response.getWriter(); out.println(operation+"<br>"); System.out.println(operation); out.flush(); out.close(); } public void doDelete(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } public void ClearCache(HttpServletResponse response) { //指定 去除客户端页面的缓存 response.setHeader("pragma", "no-cache"); response.setHeader("cache-control", "no-cache"); response.setHeader("expires", "0"); } }
关于更多关于REST方面的知识,建议阅读《RESTful Web Services》这本书。
本文参照:http://www.williamlong.info/archives/1728.html
转载本文请标明出处。
来源:https://www.cnblogs.com/cxtczzy/archive/2012/12/20/2827144.html