基於REST的Web服務及基於Ajax的用戶端

來源:互聯網
上載者:User
引言

  在 Roy Fielding 的論文中,他將 REST 作為目前 Web 體繫結構的一種基礎概念進行了詳細介紹。他為 REST 提出了下列標準:

  1、為現代 Web 體繫結構進行建模的一組約束。
  2、REST 原則已應用於 HTTP 和 URI 規範。
  3、在 HTTP 的發展過程中是可見的。

  REST 不是一種協議,而是一種體繫結構風格,這是非常重要的區別。

  對於 Web 服務,W3C 對 Web 服務的正式定義如下所示:

   “Web 服務是由 URI 標識的一個軟體系統,並且使用 XML 對它的公用介面和綁定進行定義和描述。其他軟體系統可以發現它的定義。然後,這些系統就可以按照 Web 服務預先確定的方式與它進行互動,並使用通過 網際網路通訊協定 (IP)傳輸的基於 XML 的訊息。”

  常識告訴我們,Web 服務主要用於電腦與電腦之間的通訊,而不是電腦與使用者之間的通訊。基於 REST 的 Web 服務是使用 REST 體繫結構風格建立的 Web 服務,下一個部分中將通過一個樣本來說明如何構建基於 REST 的 Web 服務。要掌握這一內容,您首先需要瞭解 Ajax,這是很重要的。(如果您是 Ajax 方面的新手,那麼請參考參考資料以擷取一些有價值的資訊的連結。)

  建立基於 REST 的 Web 服務

   要建立基於 REST 的 Web 服務,您首先需要確定希望作為 Web 服務進行公開的所有資源。一些資源的樣本包括僱員列表、僱員詳細資料、訂購單,等等。在 REST 中,每種資源都是通過唯一的統一資源識別項(Uniform Resource Identifier,URI)來標識的。您需要為每種資源確定唯一的 URI。例如,僱員列表可以標識如下:http://www.employee-details.com/employees-list。僱員詳細資料可 以使用如下所示的 URI 進行標識:http://www.employee-details.com/employees/01234。

  使用 HTTP 操作 GET、PUT、POST 和 DELETE 以檢索和修改您的資源。在您的資源表示中提供一些超連結,以提供更多的相關資訊。為這些資源的請求和響應資料指定格式,這需要 PUT 和 POST 操作。

  實現基於 REST 的 Web 服務

   您可以使用 HTTP Servlet 來實現基於 REST 的 Web 服務。本文使用一個虛擬服務示範了實現的過程,而這個服務提供了有關公司僱員的詳細資料。僱員列表資源使用一個邏輯 URI 進行表示,http://localhost:9080/AJAX_REST_Demo/RESTDemoServlet/employee-list。 當通過 HTTP GET 調用這個服務時,它將返回如清單 1 中所示的僱員列表。

  清單 1. 使用 HTTP GET 調用僱員列表

<?xml version='1.0' encoding='UTF-8'?>
<p:Employees xmlns:p='http://www.employee-details.com'>
 <Employee id='00345' href='/employees/00345'/>
 <Employee id='00346' href='/employees/00346'/>
 <Employee id='00347' href='/employees/00347'/>
 <Employee id='00348' href='/employees/00348'/>
</p:Employees>

   類似地,僱員詳細資料可以使用一個邏輯 URI 進行表示,如 http://localhost:9080/AJAX_REST_Demo/RESTDemoServlet/employee/0124。當通過 HTTP GET 調用這個服務時,它將返回如清單 2 中所示的僱員詳細資料。

  清單 2. 使用 HTTP GET 調用僱員詳細資料

<?xml version='1.0' encoding='UTF-8'?>
< EmpDetail xmlns:p='http://www.employee-details.com'>
<<Emp-ID>00345</Emp-ID>
<Name>David Henry</Name>
<Department>Finance</ Department>
</p:EmpDetail>

  清單 3 顯示了這個 Servlet 的代碼。其中,所有操作都採用了寫入程式碼方式,但是可以很容易地將其擴充為與資料庫進行互動,以便成為一個即時的、基於 REST 的服務。

  清單 3. Servlet 代碼

public class RESTDemoServlet extends HttpServlet implements Servlet {
 /* (non-Java-doc)
 * @see javax.servlet.http.HttpServlet#HttpServlet()
 */
 Map map =new HashMap();

 /* (non-Javadoc)
 * @see javax.servlet.GenericServlet#init()
 */
 public void init() throws ServletException {
  // TODO Auto-generated method stub
  super.init();

  Employee emp0 =new Employee("David","Finance");
  Employee emp1 =new Employee("Smith","HealthCare");
  Employee emp2 =new Employee("Adam","Information technology");
  Employee emp3 =new Employee("Stephan","Life Sciences");

  map.put("00345",emp0);
  map.put("00346",emp1);
  map.put("00347",emp2);
  map.put("00348",emp3);
 }

 /* (non-Java-doc)
 * @see javax.servlet.http.HttpServlet#doGet
 (HttpServletRequest arg0, HttpServletResponse arg1)
 */
 protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1)
 throws ServletException, IOException {
  // TODO Auto-generated method stub
  arg1.setContentType("text/xml");
  PrintWriter out=arg1.getWriter();
  System.out.println(map);
  if(arg0.getPathInfo()!= null){
   String EmpId=arg0.getPathInfo().substring(1,arg0.getPathInfo().length());
   System.out.println(EmpId);

   out.write("<?xml version='1.0' encoding='UTF-8'?>"+"/n");
   out.write("<p:EmpDetail xmlns:p='http://www.employee-details.com'>"+"/n");
   out.write("<Emp-ID>"+EmpId+" </Emp-ID>"+"/n");
   out.write("<Name>"+((Employee)map.get(EmpId)).name+" </Name>"+"/n");
   out.write("<Department>"+((Employee)map.get(EmpId)).dept+" </Department>"+"/n");
   out.write("</p:EmpDetail>"+"/n");
   out.flush();
  }else{
   out.write("<?xml version='1.0' encoding='UTF-8'?>"+"/n");
   out.write("<p:Employees xmlns:p='http://www.employee-details.com'>"+"/n");
   out.write("<Employee id='00345' href='http://localhost:9080/
AJAX_REST_Demo/RESTDemoServlet/employees/00345'/>"+"/n");
   out.write("<Employee id='00346' href='http://localhost:9080/
AJAX_REST_Demo/RESTDemoServlet/employees/00346'/>"+"/n");
   out.write("<Employee id='00347' href='http://localhost:9080/
AJAX_REST_Demo/RESTDemoServlet/employees/00347'/>"+"/n");
   out.write("<Employee id='00348' href='http://localhost:9080/
AJAX_REST_Demo/RESTDemoServlet/employees/00348'/>"+"/n");
   out.write("</p:Employees>");
   out.flush();
  }
 }

 /* (non-Java-doc)
 * @see javax.servlet.http.HttpServlet#doPost
 (HttpServletRequest arg0, HttpServletResponse arg1)
 */
 protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1)
throws ServletException, IOException {
  // TODO Auto-generated method stub
 }

}

  在下一個部分中,瞭解如何為這個基於 REST 的 Web 服務編寫 Ajax 用戶端。

  為基於 REST 的 Web 服務編寫 Ajax 用戶端

   如前所述,Ajax 表示 Asynchronous JavaScript + XML。它有時也稱為 XML HTTP 技術。在 Ajax 中,核心的技術主要是圍繞實現與伺服器的非同步通訊,而無需頁面重新整理。XMLHTTPRequest 對象支援對伺服器進行非同步 GET、POST、PUT 和 DELETE。這並不向使用者顯示任何內容,換句話說,不會顯示狀態訊息。您可以為狀態更改指定一個處理常式方法,並且當發生如下請求時將通知這個處理程 序:

   初始化
   啟動
   在返回的過程中
   完全完成

  清單 4 顯示了一個基於 Ajax 的 HTML 頁面的代碼,它可以用作上述基於 REST 的 Web 服務的用戶端:

  清單 4. 基於 Ajax 的 HTML 頁面的代碼

<SCRIPT language="javascript" type="text/javascript">
var req=null;
//This function initializes XHR
function initXHR() {
 if (navigator.appName.indexOf("Microsoft")> -1 ) {
  try{
   req=new ActiveXObject("Microsoft.XMLHTTP");
  }catch(e1){
   alert("failed to create XHR in IE");
  }
 }else{
  try{
   req=new XMLHttpRequest();
  }catch(error){
   alert("failed to create XHR in FireFox");
  }
 }
}
//get an employee detail
function getEmpDetails(Empurl){
 initXHR();
 req.open("GET",Empurl, true);
 req.onreadystatechange=handleEmpDetailResponse;
 req.send(null);
}

//get employee list
function getEmployeeList(listurl){
 initXHR();
 req.open("GET", listurl, true);
 req.onreadystatechange=handleEmpListResponse;
 req.send(null);
}
function handleEmpDetailResponse(){
 //if Response is complete
 if(req.readyState==4){
  //response is OK
  if(req.status==200){
   var str="";
   var response=req.responseXML;
   var root=response.documentElement;
   for(i=0; i <root.childNodes.length; i++){
    if(root.childNodes[i].nodeType != 1) continue;
    var name=root.childNodes[i].nodeName;
    var value=root.childNodes[i].firstChild.nodeValue;
    str=str+name+"--->"+value+" <br>";
   }
   document.getElementById("emp-div").style.display="";
   document.getElementById("emp-detail-div").innerHTML=str;
  }else{
   document.getElementById("messageDiv").innerHTML=" <SPAN style='color:#FF0000;
   font-size:12pt; text-decoration:none; ' <Invalid URL or PartId </SPAN>";
  }
  req.abort();
 }
}

function handleEmpListResponse(){
 //if Response is complete

 if(req.readyState==4){
  //response is OK
  if(req.status==200){
   var pstr="";
   var response=req.responseXML;
   var root=response.documentElement;
   for(i=0; i <root.childNodes.length; i++){
    if(root.childNodes[i].nodeType != 1) continue;
    var id=root.childNodes[i].getAttribute("id");
    var href=root.childNodes[i].getAttribute("href");
    pstr=pstr+"EmpId"+"--->"+id+" <input type='button' value='
GetEmpDetails' onclick="+'"'+"getEmpDetails('"+href+"')"+'"'+">"+" <br>";
   }
   document.getElementById("emp-list-div").style.display="";
   document.getElementById("emp-list").innerHTML=pstr;
  }else{
   document.getElementById("messageDiv").innerHTML=" <SPAN style='color:#FF0000;
   font-size:12pt; text-decoration:none; '>Invalid Employee ID. </SPAN>";
  }
 }
}
</SCRIPT>
<center>
<input type="button" value="getEmployee-List" onclick="getEmployeeList
'http://localhost:9080/AJAX_REST_Demo/RESTDemoServlet/employee-list')"> <br> <br>
<div id="messageDiv"> </div>
<div id="emp-list-div" style='color:#FF0000; font-size:12pt; text-decoration:none;
display:none; '>Employee List : </div> <br>
<div id="emp-list"> </div> <br> <br>
<div id="emp-div" style='color:#FF0000; font-size:12pt; text-decoration:none;
display:none; '>Selected Employee Detail : </div> <br>
<div id="emp-detail-div"> </div>
</center>

   在清單 4 中,當使用者單擊 getEmployee-List 按鈕時,會向伺服器發送一個 XML HTTP 要求。為 XML HTTP 要求指定使用處理常式函數 handleEmpListResponse 來處理 readyState 更改。當伺服器完成了響應(readyState = 4)並且該響應為 OK 時,您可以解析 XML 並將其添加到頁面的文件物件模型(Document Object Model,DOM)後面,以顯示僱員列表。類似地,當使用者單擊 GetEmpDetails 按鈕時,處理常式函數 handleEmpDetailResponse 將處理來自伺服器的 XML 響應,並修改頁面的 DOM 以顯示特定僱員的詳細資料。

  結束語

  在本文中,您瞭解了如何使用 Servlet 和基於 Ajax 的用戶端來編寫基於 REST 的 Web 服務。希望您能夠發現,可以很容易地理解和實現基於 REST 的 Web 服務。請查看下面的參考資料部分中所提供的有價值的連結。 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.