Servlet處理原生Ajax請求

萌新小白人生中的第一篇博客,不免會有差錯,還望各位大佬多多包涵。javascript

1. Ajax技術簡介 css

    Ajax(Asynchronous JavaScript and XML,異步JavaScript和XML)時一種建立交互式網頁應用的網頁開發技術,它並非一項新的技術,其產生的目的是用於實現頁面的局部刷新。經過Ajax技術可使以前的應用程序在每次提交時不用進行頁面的總體刷新,從而提高操做的性能。html

2. Servlet概念java

    Servlet(服務器端小程序)是使用java編寫的服務器端小程序,能夠像JSP同樣,生成動態的Web頁。不過,Servlet側重於邏輯控制,JSP側重於視圖展現。Servlet主要運行在服務器端,並由服務器調用執行,是一種按照Servlet標準開發的類。Servlet最大的好處就是能夠處理客戶傳來的HTTP請求,並返回一個響應。
web

3. 同步和異步ajax

    同步:客戶端發送請求給服務端,在等待服務端響應請求的這段時間,客戶端不能作其餘事情,只能等待。服務器端作完了才返回給客戶端,這時客戶端就能夠作其餘事情了。用戶使用起來可能不太友好,可是有時咱們必須拿到服務端的數據才能進行下一步操做。好比我給你打電話,你必須接通電話我才能夠和你通話。編程

    異步:客戶端發送請求給服務端,在等待服務端響應請求的這段時間,客戶端能夠作其餘事情,不用等待。節約了時間。提升了效率。好比發短信。一條短信發完後,無論你看沒看,回覆沒回復,我能夠再發下一條短信。不過,也有可能形成短信干擾。因此要慎重。固然,打電話和發短信的前提是必須有手機,手機必須有話費。(說一句廢話)。json

4. Servlet處理原生Ajax請求(不發送數據/發送key/value數據/發送json格式數據)小程序

開發環境:eclipse+tomcat+jsp+javascript+ajax+servlet數組

 

4.1 Servlet處理原生Ajax請求(不攜帶數據,返回普通文本)

    (1) 搭建環境:

    在eclipse中新建Java web項目(會自動導入JRE System Library包),好比我把項目名字寫爲AjaxDemo,並將項目部署到tomcat服務器上,下面是eclipse中項目的目錄結構:

    

咱們先無論lib中的jar包,下面我會進行分析,一步一步來。下面咱們進行開發。

   (2)編寫inedex.jsp頁面

     在WebContent根目錄下新建index.jsp文件,文件內容以下:

      

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2  3 <%-- <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> --%>  4 <%  5 String path = request.getContextPath();  6 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()  7 + path + "/";  8 %>  9 <!DOCTYPE html> 10 <html> 11 <head> 12 <base href="<%=basePath%>"> 13 <title>I LOVE YOU</title> 14 <link rel="stylesheet" type="text/css" href=""> 15 <script type="text/javascript" src="index.js"></script> 16 17 </head> 18 <body> 19 20 <button id="mybutton" value="異步請求服務器" onclick="fun1()" >發送數據格式爲key/value的原生ajax請求</button> 21 <spand id="show" /> 22 23 <br/> 24 25 <hr/> 26 27 <button id="mybutton1" value="異步請求服務器" onclick="fun2()" >發送數據格式爲json的原生ajax請求</button> 28 <spand id="show1" /> 29 30 31 <br/> 32 <hr/> 33 34 <button id="mybutton2" value="異步請求服務器" onclick="fun3()" >不發送數據</button> 35 <spand id="show2" /> 36 37 </body>

 

這個頁面咱們編寫了三個按鈕,而且都註冊了事件,能夠調用js文件中對應的函數來響應按鈕。這裏咱們看id="mybutton2"這個按鈕(第三個),不發送數據這個按鈕。<span>標籤的做用主要是爲了顯示返回的內容。咱們注意到這個jsp文件引用了javascript文件。下面咱們編寫js文件。

(3)編寫inedex.js文件

   

 1 /**  2  *  3 */  4 //原生ajax提交key/value數據  5 function fun1(){  6  7 var value="username=wly&password=1314520"; //key/value類型  8 var x=new XMLHttpRequest(); //建立ajax對象  9 x.onreadystatechange=function(){ //對ajax對象進行監聽  10 if(x.readyState==4){ //4表示解析完畢  11 if(x.status==200){ //200爲正常返回 12 var data=x.responseText; //返回的文本內容 13 document.getElementById("show").innerHTML=data; 14 console.log(data); //web控制檯打印 15  } 16  } 17  } 18 19 //(1)發送方式 20 //(2)發送地址 21 //(3)是否異步,true爲異步,false爲同步  22 x.open("POST","AjaxServlet",true); 23 x.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 24 x.send(value); //發送  25 } 26 27 28 //原生ajax提交json數據 29 function fun2(){ 30 var user={ 31 "username":"wly", 32 "password":"1314521" 33  }; 34 var x=new XMLHttpRequest(); //建立ajax對象 35 x.onreadystatechange=function(){ //對ajax對象進行監聽  36 if(x.readyState==4){ //4表示解析完畢  37 if(x.status==200){ //200爲正常返回 38 var data=JSON.parse(x.responseText); //把json字符串解析爲javascript對象 39 document.getElementById("show1").innerHTML=data.message+" "+data.user.username+" "+data.user.password; 40  console.log(data); 41  console.log(data.meaasage); 42  console.log(data.user); 43  } 44  } 45  } 46 47 //(1)發送方式 48 //(2)發送地址 49 //(3)是否異步,true爲異步,false爲同步  50 x.open("POST","AjaxServlet1",true); 51 x.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 52 53 //把javascript對象轉化爲json字符串 54  x.send(JSON.stringify(user)); 55 } 56 57 58 //原生ajax請求(不發送數據) 59 function fun3(){ 60 61 62 var x=new XMLHttpRequest(); //建立ajax對象 63 x.onreadystatechange=function(){ //對ajax對象進行監聽  64 if(x.readyState==4){ //4表示解析完畢  65 if(x.status==200){ //200爲正常返回 66 var data=x.responseText; //返回的文本內容 67 document.getElementById("show2").innerHTML=data;//將內容顯示在span標籤中 68 console.log(data); //web控制檯打印 69  } 70  } 71  } 72 73 //(1)發送方式 74 //(2)發送地址 75 //(3)是否異步,true爲異步,false爲同步  76 x.open("POST","AjaxServlet2",true); 77 //設置請求頭信息 78 x.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 79 x.send(null); //發送 ,不發送數據,使用null 80 }

 

咱們來看fun3()這個函數,這裏咱們使用原生ajax提交請求,這裏咱們不發送數據,因此send中的參數爲null。代碼裏面都有註釋,這裏不作過多解釋。

既然提交了請求,那麼咱們必須編寫服務器端代碼來處理ajax請求。接下來servlet就登場了。

(4)編寫Servlet文件

   

 1 package com.servlet;  2  3 import java.io.IOException;  4  5 import javax.servlet.ServletException;  6 import javax.servlet.http.HttpServlet;  7 import javax.servlet.http.HttpServletRequest;  8 import javax.servlet.http.HttpServletResponse;  9 10 public class AjaxServlet2 extends HttpServlet { 11 12 protected void doGet(HttpServletRequest request, HttpServletResponse response) 13 throws ServletException, IOException { 14 15 // 設置發送到客戶端的響應的內容類型爲html,編碼方式爲UTF-8 16 response.setContentType("text/html;charset=UTF-8"); 17 // 返回內容 18 response.getWriter().write("我想你了!");// 返回一個普通字符串 19  } 20 21 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 22 this.doGet(req, resp); 23  } 24 }

此時servlet處理Ajax請求很是簡單,由於不須要接受數據,因此只返回普通文本就好了。注意response.getWriter()返回的是PrintWriter,這是一個打印輸出流。調用其write方法輸出文本內容。接下來咱們再web.xml配置servlet。

 

(5)web.xml配置Servlet

   爲何要在web.xml中配置Servlet呢?由於當咱們在瀏覽器輸入url地址時,發送請求給tomcat容器,tomcat必需要加載相對應servlet,並調用Servlet去處理請求,因此必需要在web.xml中配置servlet。若是不配置的話,就會找不到相應的Servlet來處理。

   

 1 <?xml version="1.0" encoding="UTF-8"?>  2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" 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">  3 <display-name>AjaxDemo</display-name>  4 <welcome-file-list>  5 <welcome-file>index.html</welcome-file>  6 <welcome-file>index.htm</welcome-file>  7 <welcome-file>index.jsp</welcome-file>  8 <welcome-file>default.html</welcome-file>  9 <welcome-file>default.htm</welcome-file> 10 <welcome-file>default.jsp</welcome-file> 11 </welcome-file-list> 12 13 14 <servlet> 15 <servlet-name>AjaxServlet</servlet-name> 16 17 <servlet-class>com.servlet.AjaxServlet</servlet-class> 18 </servlet> 19 20 <servlet> 21 <servlet-name>AjaxServlet1</servlet-name> 22 23 <servlet-class>com.servlet.AjaxServlet1</servlet-class> 24 </servlet> 25 26 27 <servlet> 28 <servlet-name>AjaxServlet2</servlet-name> 29 30 <servlet-class>com.servlet.AjaxServlet2</servlet-class> 31 </servlet> 32 33 34 35 36 37 38 <servlet-mapping> 39 40 <servlet-name>AjaxServlet</servlet-name> 41 <url-pattern>/AjaxServlet</url-pattern> 42 43 </servlet-mapping> 44 45 46 <servlet-mapping> 47 48 <servlet-name>AjaxServlet1</servlet-name> 49 <url-pattern>/AjaxServlet1</url-pattern> 50 51 </servlet-mapping> 52 53 54 <servlet-mapping> 55 56 <servlet-name>AjaxServlet2</servlet-name> 57 <url-pattern>/AjaxServlet2</url-pattern> 58 59 </servlet-mapping> 60 61 </web-app>

 

咱們看到AjaxServlet2配置好了。說明一下。配置servlet有2個標籤。第一個是<servlet></servlet>這裏面咱們配置的是servlet名稱和全類路徑。第二個

<servlet-mapping></servlet-mapping>配置的是servlet名稱(和第一個標籤的servlet名稱保持一致)和映射路徑。這裏我使用斜槓/加上本身的路徑。

咱們注意到<welcome-file-list>標籤配置有一個index.jsp文件,至關因而一個歡迎頁面。到時咱們寫url請求地址時就不用寫文件名字了。(方便)

下來咱們跑一下程序。

 

(5)運行程序

   啓動tomcat,在谷歌瀏覽器地址欄上輸入請求地址url:localhost/AjaxDemo/ 

   好了,ok。點擊按鈕(不發送數據)運行就好了。效果展現圖:

   

注意:通常請求地址爲localhost:端口號/項目名/jsp文件名。localhost意爲本地主機,就是這臺計算機。tomcat的默認端口號爲8080,我把tomcat的端口號改成了80,而80端口號是HTTP協議的默認端口號。因此我能夠省略掉80端口號。其實在你輸入網站的時候其實瀏覽器(非IE)已經幫你輸入協議了。後面的jsp文件名我也省了,由於得益於上面標籤<welcme-file-list>的配置。哈哈。方便了好多。同理。咱們能夠實現其餘實例。

 

4.2 Servlet處理原生Ajax請求(發送key/value數據,返回普通文本)

(1)編寫jsp文件

   上面有index.jsp代碼,看第一個按鈕就好了。同理。

(2)編寫js文件

   上面有index文件,看第一個函數fun1()就好了。註釋都有。注意key/value的格式爲data="username=wly&password=1314520"。多個鍵值對能夠用&來鏈接,而後再使用send(data)方法進行發送數據。

 (3)編寫Servlet文件

   

 1 package com.servlet;  2  3 import java.io.IOException;  4  5 import javax.servlet.ServletException;  6 import javax.servlet.http.HttpServlet;  7 import javax.servlet.http.HttpServletRequest;  8 import javax.servlet.http.HttpServletResponse;  9 10 public class AjaxServlet extends HttpServlet { 11 12 protected void doGet(HttpServletRequest request, HttpServletResponse response) 13 throws ServletException, IOException { 14 15 response.setContentType("text/html;charset=UTF-8"); 16 String username = request.getParameter("username"); //獲取username的內容 17 String password = request.getParameter("password"); //獲取password的內容 18 System.out.println(username + " " + password); 19 response.getWriter().write("haha " + "username: " + username + " password: " + password); //鏈接一個普通字符串返回 20 21  } 22 23 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 24 this.doGet(req, resp); 25  } 26 }

此時servlet要作的事情,接受前臺傳來的數據和返回內容。獲取前臺傳來的內容,使用request.getParameter(String paramString)方法。能夠根據參數的名稱獲取相應的內容。這個方法很是重要。獲取到了之後,咱們只返回一個普通文本字符串便可。

(4)web.xml配置servlet

   同理。上面web.xml已經配置好了。配置的是AjaxServlet。這裏不作過多解釋。

(5)運行程序

   啓動tomcat,在谷歌瀏覽器地址欄上輸入請求地址url:localhost/AjaxDemo/ 

   好了,ok。點擊第一個按鈕運行就好了。效果展現圖:

   

 

4.3 Servlet處理原生Ajax請求(發送json數據,返回json數據)

(1)Json

      JSON(JavaScript Object Notation, JS 對象簡譜) 是一種輕量級的數據交換格式。對於Ajax應用程序來講,json比xml更快更易使用。人類易於閱讀和書寫。機器很容易解析和生成。它基於JavaScript編程語言(標準ECMA-262第三版-1999年12月)的子集。JSON是一種文本格式,它徹底獨立於語言。這些屬性使JSON成爲理想的數據交換語言。項目中經常使用的Json類庫:Gson(谷歌公司研發),FastJson(阿里巴巴研發),Jackson(簡單易用,依賴包少),Json-lib(使用普遍,依賴包較多)。

(2)導入jar包

      由於涉及到json數據格式的處理,因此咱們必須導入json相關的包以及依賴包進行處理。咱們使用應用比較普遍的Json-lib類庫。上面項目結構裏面有7個jar包(lib下面)。能夠發現上面json-lib庫的核心jar包是json-lib-2.4-jdk15.jar,其餘幾個都是依賴包。Json-lib是一個Java類庫,用於將bean,集合,java數組和XML轉換爲JSON,而後再次轉換爲bean和DynaBeans(動態bean)。

(3)新建實體類(User)

   由於涉及到將json對象轉化爲java對象,將java對象轉化爲json對象。因此要創建User對象,有2個屬性,username和password。並提供setter和getter方法,還有toString()方法。

   

package com.entity; public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User [username=" + username + ", password=" + password + "]"; } }

 

(4)編寫jsp文件

   同理。看第二個按鈕便可。

(5)編寫js文件

   同理。上面index.js文件中的fun2()函數。這裏作一下解釋。注意json的數據格式var user={"username":"wly", "password":1314521}。這裏咱們把數據value值直接寫了。(爲了方便)。實際開發中咱們應該獲取頁面的username的value值。password的value值。可使用 document.getElementById("id").value來獲取頁面數據。還要注意有2個方法。觀察fun2()。咱們發現發送的時候,作了一下處理,使用的是JSON.stringify(user)。這個函數的做用主要是將javascript對象轉化爲json字符串,由於定義的user是一個var類型,它是一個javascript對象,只是內容定義的是符合json數解析爲javascript對象據規範的格式。因此才能夠轉化。轉化爲json字符串才能夠發送。在把參數傳入send()方法裏面進行發送。同理。還有一個方法JSON.parse(返回的json字符串),它的做用是將返回的json字符解析爲javascript對象,而後再進行前臺頁面數據的顯示。

(6)編寫servlet文件

   第一步,先編寫一個json的工具類,用來接受前臺傳來的json字符串,並把json字符串轉化爲json對象。

   

 1 package com.util;  2  3 import java.io.BufferedReader;  4 import java.io.IOException;  5 import java.io.InputStreamReader;  6 import java.io.UnsupportedEncodingException;  7  8 import javax.servlet.http.HttpServletRequest;  9 10 import net.sf.json.JSONObject; 11 12 public class JsonReader { 13 14 public static JSONObject receivePost(HttpServletRequest request) throws UnsupportedEncodingException, IOException { 15 16 // 讀取請求內容 17 BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8")); 18 19 String line = null; 20 StringBuilder sb = new StringBuilder(); 21 22 while ((line = br.readLine()) != null) { 23  sb.append(line); 24  } 25 26 // 將json字符串轉化爲json對象 27 JSONObject json = JSONObject.fromObject(sb.toString()); 28 return json; 29  } 30 31 }

第二步,編寫servlet類。

 

 1 package com.servlet;  2  3 import java.io.IOException;  4  5 import javax.servlet.ServletException;  6 import javax.servlet.http.HttpServlet;  7 import javax.servlet.http.HttpServletRequest;  8 import javax.servlet.http.HttpServletResponse;  9 10 import com.entity.User; 11 import com.util.JsonReader; 12 13 import net.sf.json.JSONObject; 14 15 public class AjaxServlet1 extends HttpServlet { 16 17 protected void doGet(HttpServletRequest request, HttpServletResponse response) 18 throws ServletException, IOException { 19 20 // response.setContentType("text/html;charset=UTF-8"); 21 22 response.setContentType("application/json;charset=UTF-8"); //設置響應的內容類型和編碼 23 JSONObject json = JsonReader.receivePost(request); 24  System.out.println(json); 25 26 // 將json對象轉化爲java對象 27 User user = (User) JSONObject.toBean(json, User.class); 28 29 JSONObject result = new JSONObject(); 30 31 // 將user對象轉化爲json對象,保存user 32 result.put("user", JSONObject.fromObject(user)); 33 result.put("message", "返回成功"); 34  response.getWriter().print(result); 35  } 36 37 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 38 this.doGet(req, resp); 39  } 40 }

 

BufferedReader能夠用來讀取文件或者接收來自鍵盤(控制檯)的信息。它比Scanner更加快捷,可以大幅度縮短程序運行時間。它下面的readline()方法能夠一次性讀取一行文字(String),很是方便。須要注意的是,使用BufferedReader對象的readLine()方法必須處理java.io.IOException異常(Exception)。以及,在使用完BufferredReader之後,須要用close()方法關閉流。上面咱們用BufferedReader對象來接受請求內容。並使用StringBuilder對象進行存儲StringBuilder是一個字符串變量,單線程下效率比較高。JSONObject類是json-lib核心庫中的一個比較重要的類,這裏咱們使用其中的2個方法就行。其餘的本身看源碼。

一個是public static JSONObject fromObject(Object object),這是JSONObject類的一個靜態方法,將Object類型數據(或者是java對象)轉化爲JSONObject對象返回。另外一個是public static Object toBean(JSONObject jsonObject, Class beanClass)方法,它的做用主要用於將json對象轉化爲Object類型(或者說java對象)。注意上面PrintWritter的print()方法,其實底層仍是調用了write方法。其實最終返回的仍是json字符串。本身感興趣的話能夠本身研究一下源碼。

(7)web.xml配置servlet

  同理。上面已經配置。配置的是AjaxServlet1。

(8)運行程序

   同理。輸入url地址。點擊第二個按鈕就好了。效果圖以下:

   

 

5. 總結

   (1)注意jsp文件引入js文件的路徑問題,這裏咱們能夠把2個文件都放在WebContent根目錄下。

   (2)注意ajax提交的地址找不到時,要檢查web.xml是否配置正確,也可使用${pageContext.request.contextPath}/配置的映射地址。至關因而全路徑。

   (3)Ajax傳給後臺json數據時,須要使用JSON.stringify(data)將javascript對象轉化爲json字符串。與之相對應的方法是JSON.parse(data)。

   (4)Ajax使用JSONObject類處理json數據時,注意json-lib的jar包以及依賴包必定要導全。

   (5)json-lib類庫性能分析:json-lib最開始的也是應用最普遍的json解析工具,json-lib 很差的地方確實是依賴於不少第三方包,對於複雜類型的轉換,json-lib對於json轉換成bean還有缺陷, 好比一個類裏面會出現另外一個類的list或者map集合,json-lib從json到bean的轉換就會出現問題。json-lib在功能和性能上面都不能知足如今互聯網化的需求。

    本篇博客源碼連接:https://pan.baidu.com/s/1fTR0mpfmj9-D7tPrONOu8g         提取碼:swsa 

相關文章
相關標籤/搜索