REST架构设计与实现

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

 

转载本文请标明出处。

posted @ 2012-12-20 21:50  方子格  阅读(2291)  评论(0编辑  收藏  举报