阿里技術專家深刻講解,一文把Servlet整的明明白白

System.out.println("統一資源定位符:" + request.getRequestURL());html

System.out.println("協議和版本:" + request.getProtocol());

    System.out.println("當前項目地址:" + request.getContextPath());



    // 獲得一個請求頭

    System.out.println("獲得host的請求頭值:" + request.getHeader("host"));

}

}java

複製代碼git

3.三、請求參數亂碼問題(POST)

------------------



### 3.3.一、請求參數產生亂碼的緣由



? 在瀏覽器發送數據給服務器的時候,**使用 utf-8 編碼**,但服務器解碼默認使用 ISO-8859-1 解碼:歐洲碼,不支持漢字的。



? **若是是 GET 請求且 Tomcat 版本大於8.0.5,則不須要考慮亂碼問題,不然 GET 請求也須要考慮亂碼問題。**



### 3.3.二、POST方式亂碼解決方案



1.  解決方法:**request.setCharacterEncoding("utf-8") 設置請求參數的編碼爲UTF-8。**

2.  代碼位置:設置請求的編碼這句話必定放在獲取請求參數以前。

3.  頁面的編碼:這個編碼必定要與頁面的編碼相同。若是頁面使用的是 GBK,則這裏也要用GBK。



4、響應對象

======



4.一、HttpServletResponse對象概述

---------------------------



? HttpServletResponse 是一個接口,該接口的實現類對象稱爲響應對象,**用於響應數據(響應行,響應頭,響應體)給瀏覽器**。HttpServletResponse 接口包含了大量的方法。由 Tomcat 去實現這個對象,而且在 servlet 啓動的時候調用 service() 將請求對象和響應對象傳遞進來了。咱們在 service 方法中直接使用便可。



4.二、響應數據相關方法

------------



| 響應體相關的方法 | 功能描述 |

| --- | --- |

| OutputStream getOutputStream() | 若是服務器端返回的是二進制數據  

則使用這個方法,好比圖片 |

| PrintWriter getWriter() | 若是服務器端返回的是字符的文本數據,使用這個方法 |

@WebServlet(urlPatterns = "/response")web

public class ResponseServlet extends HttpServlet {面試

@Override

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // 得到字符打印流對象

    PrintWriter out = response.getWriter();

    // 響應數據給瀏覽器顯示

    out.print("<h1 style='color:red'>hello browser<h1>");

}

}跨域

複製代碼數組

4.三、響應內容中文亂碼問題

--------------



### 4.3.一、亂碼緣由



? 由於 Tomcat 中響應體默認的是歐洲碼錶,ISO-8859-1 不支持中文。



### 4.3.二、解決辦法



4.3.二、方法一



? **在得到打印流對象以前,經過下面方法設置打印流的編碼爲utf-8**



| response方法 | 說明 |

| --- | --- |

| response.setCharacterEncoding("字符集") | 用於設置響應體的字符集  

設置打印流使用的碼錶 |

@WebServlet(urlPatterns = "/response")瀏覽器

public class ResponseServlet extends HttpServlet {服務器

@Override

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // 設置打印流編碼

    response.setCharacterEncoding("utf-8");

    // 得到字符打印流對象

    PrintWriter out = response.getWriter();

    // 響應數據給瀏覽器顯示

    out.print("<h1 style='color:red'>你好 browser<h1>");

}

}session

複製代碼

4.3.三、方法二



? **經過下面方法告訴瀏覽器返回數據類型和編碼**



| 響應對象的方法 | 功能描述 |

| --- | --- |

| void setContentType(String type) | 1\. 告訴瀏覽器返回內容類型  

2\. 設置打印流編碼  

**注意: 必須在獲取流以前設置,不然無效** |

@WebServlet(urlPatterns = "/response")

public class ResponseServlet extends HttpServlet {

@Override

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // 設置打印流編碼

    // response.setCharacterEncoding("utf-8");



    // 告訴瀏覽器返回內容類型並設置打印流編碼

    response.setContentType("text/html;charset=utf-8");

    // 得到字符打印流對象

    PrintWriter out = response.getWriter();

    // 響應數據給瀏覽器顯示

    out.print("<h1 style='color:red'>你好 browser<h1>");

}

}

複製代碼

5、JSP

=====



5.一、JSP的做用

----------



? JSP——Java Server Page運行在服務器端的 Java 頁面,之前學習的 HTML 運行在瀏覽器端。JSP 是運行在服務器上,最終仍是解析成靜態的HTML,運行在瀏覽器。咱們在瀏覽器上看到的HTML頁面,實際上是 JSP 在服務器上運行的結果。



? **JSP 的主要做用是代替 Servlet 程序回傳 html 頁面的數據。由於 Servlet 程序回傳 html 頁面數據是一件很是繁鎖的事情。開發成本和維護成本都極高。**



![image-20200514095259063](https://img-blog.csdnimg.cn/img_convert/55a0c415785f7fdf55b35fa2e8e9630d.png)



5.二、JSP的優點

----------



| 技術 | 特色 |

| --- | --- |

| HTML | 靜態頁面 優勢:方便頁面美化操做,寫JS腳本和CSS代碼都比較方便。  

缺點:不能寫動態的內容。 |

| Servlet | 運行在服務器上小 Java 程序  

優勢:製做動態內容  

缺點:不方便寫 HTML 以及 CSS 和 JS 代碼 |

| JSP | JSP = HTML + Servlet  

特色:既有 HTML 的優勢:方便美化和編寫 JS 代碼。  

又有 Servlet 優勢:能夠在頁面寫 Java 代碼,能夠製做動態內容(不建議)。 |



5.三、JSP的原理

----------



? \*\*JSP頁面本質上是一個 Servlet 程序。\*\*當咱們第一次訪問 jsp 頁面的時候。Tomcat 服務器會幫咱們把 jsp 頁面翻譯成爲一個 java 源文件。而且對它進行編譯成爲.class 字節碼程序。咱們打開 java 源文件不難發現其裏面的內容是:



![image-20210116212753515](https://img-blog.csdnimg.cn/img_convert/34736f701195e36b8036b4c2269b3366.png)



? 咱們跟蹤原代碼發現,HttpJspBase 類。它直接地繼承了 HttpServlet 類。也就是說。jsp 翻譯出來的 java 類,它間接了繼承了 HttpServlet 類。也就是說,翻譯出來的是一個 Servlet 程序。



? ![image-20210116212815402](https://img-blog.csdnimg.cn/img_convert/e7cfc50dae1fb00afca7e225bc646fdc.png)



? 翻譯出來的 Servlet 程序的源代碼,不難發現。其底層實現,也是經過輸出流。把 html 頁面數據回傳



給客戶端。

out.write("\r\n");

out.write("\r\n");

out.write("<html>\r\n");

out.write("<head>\r\n");

out.write("

<title>Title</title>\r\n");

out.write("</head>\r\n");

out.write("<body>\r\n");

out.write("

a.jsp 頁面\r\n");

out.write("</body>\r\n");

out.write("</html>\r\n");

複製代碼

5.四、JSP運行過程

-----------



? JspServlet 首先會將 jsp 文件代碼翻譯成 Servlet 的 Java 代碼,而後再編譯成字節碼文件執行,其底層就是一個 Servlet。



![image-20200424093408316](https://img-blog.csdnimg.cn/img_convert/c9d2725fa5d1d4a7d35155e839460bdb.png)



1.  瀏覽器請求 JSP 頁面,Tomcat 中的 JspServlet 會先 JSP 文件翻譯成 Servlet 文件:xxx\_jsp.java。

2.  將 xxx\_jsp.java 文件編譯產生字節碼文件:xxx\_jsp.class。

3.  加載字節碼文件 xxx\_jsp.class 並建立 xxx\_jsp 對象。

4.  調用 xxx\_jsp 的 service 方法處理請求並響應數據。



? **瀏覽器第一次訪問 JSP 的時候,由 Tomcat 將 JSP 翻譯成了 Servlet,而且編譯成字節碼文件,只生成1次。若是這期間修改了JSP內容,就會從新翻譯。**



6、轉發和重定向

========



6.一、轉發和重定向的做用

-------------



? 用於 web 組件的跳轉,從A 組件跳到另外一個組件B。



6.二、轉發

------



![image-20210116214138803](https://img-blog.csdnimg.cn/img_convert/2aaf0d0a627d45459061fe0ec3461923.png)



### 6.2.一、跳轉位置



? 請求轉發是指,服務器收到請求後,從一次資源跳轉到另外一個資源的操做叫請求轉發。在服務器端進行的組件(資源)的跳轉。



![image-20200424101847738](https://img-blog.csdnimg.cn/img_convert/63813ac9cbcd835797fbfa2da12b4cf5.png)



### 6.2.二、轉發的方法

request.getRequestDispatcher("/要跳轉到的地址").forward(request, response);

複製代碼

6.三、重定向

-------



![image-20210116220209299](https://img-blog.csdnimg.cn/img_convert/578a593e1720e9e811703c2ef2d189d3.png)



### 6.3.一、跳轉的位置



? 在瀏覽器端進行的頁面(組件/資源)跳轉。



![image-20200424102524457](https://img-blog.csdnimg.cn/img_convert/f61cd1965e7bf5829ab8bdbf4815618d.png)



### 6.3.二、重定向的方法

response.sendRedirect("要跳轉的地址")

複製代碼

6.四、轉發和重定向的區別

-------------



| 區別 | 轉發 forward | 重定向 redirect |

| --- | --- | --- |

| 目錄 | 能夠訪問WEB-INF目錄下的資源 | 不能夠訪問WEB-INF目錄下的資源 |

| 地址欄 | 地址欄不會發生變化,仍是上一個地址 | 會變化,顯示新的地址 |

| 跳轉位置 | 在服務端進行跳轉 | 在瀏覽器端跳轉 |

| 請求對象(域) | 請求域數據不會丟失,由於是同一個請求 | 請求域數據會丟失,由於不是同一個請求 |



6.五、注意

------



1.  不管是重定向仍是轉發,後續代碼都會執行,但通常轉發或重定向後面不會有代碼,沒有執行的意義了,由於不論是轉發仍是重定向瀏覽器最終顯示的都是跳轉後頁面的數據。

2.  若是須要保留請求域中的數據,必須使用轉發。

3.  若是須要跳轉到WEB-INF目錄中的資源,必須使用轉發。

4.  若是須要跨域,必須使用重定向。



7、三大做用域

=======



7.一、什麼是做用域

----------



? 用於 Servlet 之間數據共享的服務器內存區域,做用域結構是一個Map<String, Object>。



![img01](https://img-blog.csdnimg.cn/img_convert/d19fb1cbca96507bcbab180fb307e066.png)



7.二、做用域類型

---------



| 做用域 | 類型 | 做用範圍 |

| --- | --- | --- |

| 請求域 | HttpServletRequest | 只在同一次請求中起做用 |

| 會話域 | HttpSession | 同一個會話中起做用  

瀏覽器第1次訪問服務器直到瀏覽器關閉  

的整個過程稱爲1次會話 |

| 上下文域 | ServletContext | 同一個應用中起做用  

服務器啓動直到服務器關閉的整個過程都起做用 |



7.三、做用域方法

---------



| 與做用域有關的方法 | 做用 |

| --- | --- |

| Object getAttribute("鍵") | 從中獲得一個值 |

| void setAttribute("鍵",Object數據) | 向做用域中存儲鍵值對數據 |

| void removeAttribute("鍵") | 刪除做用域中的鍵值對數據 |



7.四、如何選擇做用域

-----------



? **先考慮做用範圍小的做用域,若是小做用範圍的做用域能知足需求就使用小做用範圍的做用域。**



8、EL表達式

=======



8.一、什麼是EL表達式

------------



? EL 表達式的全稱是:`Expression Language`。是表達式語言。



? EL 表達式主要是代替 jsp 頁面中的表達式腳本在 jsp 頁面中進行數據的輸出。由於 EL 表達式在輸出數據的時候,要比 jsp 的表達式腳本要簡潔不少。



8.二、EL表達式運算

-----------



### 8.2.一、算數運算



| 算術運算符 | 說明 | 舉例 | 結果 |

| --- | --- | --- | --- |

| + | 加法 | ${12+18} | 30 |

| \- | 減法 | ${18-8} | 10 |

| \* | 乘法 | ${12\*12} | 144 |

| /(div) | 除法 | 6/3或{6/3}或6/3或{6 div 3} | 2 |

| %(mod) | 取模 | {10%3} 或{10 mod 3} | 1 |



### 8.2.二、邏輯運算



| 邏輯運算符 | 說明 | 舉例 | 結果 |

| --- | --- | --- | --- |

| && 或 and | 與運算 | { 12 == 12 && 12 < 11 } 或 { 12 == 12 and 12 < 11 } | false |

| | 或 or | 或運算 | 12==12∥∥12<11或{ 12 = = 12 \\|\\| 12<11}或 12==12∥∥12<11或{12= =12 or 12<11} | true |

| ! 或 not | 取反運算 | !true後{!true} 後 !true後{not true} | false |



### 8.2.三、關係運算



| 關係運算 | 說明 | 舉例 | 結果 |

| --- | --- | --- | --- |

| \== 或 eq | 等於 | 5==5或{5 == 5} 或 5==5或{5 eq 5} | true |

| != 或 ne | 不等於 | 5!=5或{5 !=5} 或 5!=5或{5 ne 5} | false |

| < 或 lt | 小於 | 3<5或{3 < 5} 或 3<5或{3 lt 5} | true |

| \> 或 gt | 大於 | 2>10或{2 > 10} 或 2>10或{2 gt 10} | false |

| <= 或 le | 小於等於 | 5<=12或{ 5 <= 12 } 或 5<=12或{ 5 le 12 } | true |

| \>= 或 ge | 大於等於 | 3>=5或{ 3 >= 5 }或 3>=5或{ 3 ge 5 } | false |



### 8.2.四、三元運算



? `表達式 1?表達式 2:表達式 3`



? 若是表達式 1 的值爲真,返回表達式 2 的值,若是表達式 1 的值爲假,返回表達式 3 的值。



![img11](https://img-blog.csdnimg.cn/img_convert/e30e91d36d1838b68abf7a91e5c37355.png)



### 8.2.五、判空運算



? 判空:判斷的是內容是否爲空,不是對象是否爲空。



? ![img12](https://img-blog.csdnimg.cn/img_convert/c1dc13b32960ebb0e6b564843c30adb7.png)



8.三、EL 從四個做用域中取值

----------------



? **EL 獲取數據的方式是從 4 個做用域對象中,從小到大的去獲取**,若是須要指定做用域獲取數據,可以使用如下 EL 的內置對象來指定。



### 8.3.一、PageContext 對象



? JSP 本質是 Servlet,但比 Servlet 多了一個做用域:**頁面域**,在 JSP 中有四大做用域。頁面域是隻在一個JSP頁面中起做用,不一樣的JSP之間不能實現數據的共享,比請求域範圍還要小。



| PageContext 操做有關的方法 | 說明 |

| --- | --- |

| void setAttribute(String key, Object value) | 向頁面域中添加鍵和值 |

| Object getAttribute(String key) | 從頁面域中獲得值 |

| void removeAttribute(String key) | 刪除四個域中同名的鍵 |

| Object findAttribute(String key) | 自動從四個做用域中去查某個鍵,  

從小到大的範圍來查找,若是找到就中止。  

若是沒有找到,返回null |

<%

//向頁面域中添加一個字符串    

pageContext.setAttribute("name","我是頁面域");

%>

複製代碼

### 8.3.二、 EL 指定域獲取數據



| 做用域 | EL的寫法 |

| --- | --- |

| 頁面域 | ${pageScope.鍵名} |

| 請求域 | ${requestScope.鍵名} |

| 會話域 | ${sessionScope.鍵名} |

| 上下文域 | ${applicationScope.鍵名} |

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<title>EL指定域獲取數據</title>
<%

    // 向頁面域中添加一個字符串

    pageContext.setAttribute("name", "頁面域");

    // 請求域

    request.setAttribute("name", "請求域");

    // 會話域

    session.setAttribute("name", "會話域");

    // 上下文域

    application.setAttribute("name", "上下文域");

%>

    

從頁面域獲取:${pageScope.name}

<hr>



從請求域獲取:${requestScope.name}

<hr>



從會話域獲取:${sessionScope.name}

<hr>



從上下文域獲取:${applicationScope.name}

<hr>

	自動查找做用域獲取:${name}

<hr>

複製代碼

9、JSTL 標籤庫

==========



? JSTL 標籤庫 全稱是指 JSP Standard Tag Library JSP 標準標籤庫。是一個不斷完善的開放源代碼的 JSP 標籤庫。EL 表達式主要是爲了替換 jsp 中的表達式腳本,而標籤庫則是爲了替換代碼腳本。這樣使得整個 jsp 頁面變得更佳簡潔。JSTL 由五個不一樣功能的標籤庫組成。



| 功能範圍 | URL | 前綴 |

| --- | --- | --- |

| **核心標籤庫** | [java.sun.com/jsp/jstl/co…](https://gitee.com/vip204888/java-p7) | c |

| 格式化 | [java.sun.com/jsp/jstl/fm…](https://gitee.com/vip204888/java-p7) | fmt |

| 函數 | [java.sun.com/jsp/jstl/fu…](https://gitee.com/vip204888/java-p7) | fn |



9.一、使用步驟

--------



### 9.1.一、導入jar包

taglibs-standard-impl-1.2.1.jar

taglibs-standard-spec-1.2.1.jar

複製代碼

### 9.1.二、引入標籤庫

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

複製代碼

### 9.1.三、使用標籤



9.二、核心標籤庫經常使用標籤

-------------



### 9.2.一、<c:if />



? 用於頁面上單條件判斷。



| 屬性名 | 是否支持EL | 屬性類型 | 屬 性 描 述 |

| --- | --- | --- | --- |

| test | 支持,必須是 EL | boolean值 | EL 中條件爲真則執行標籤體內容  

注意:沒有對應 else 標籤 |

<%--

ii.<c:if />

if 標籤用來作 if 判斷。

test 屬性表示判斷的條件(使用 EL 表達式輸出)

--%>

<c:if test="${ a == b }">

若是a等於b

</c:if>

<c:if test="${ a != b }">

若是a不等於b

</c:if>

複製代碼

### 9.2.二、<c:choose>



? 用於多分支判斷(多條件判斷),相似於跟 switch ... case .... default 。



| 標籤名 | 做用 |

| --- | --- |

| choose | 相似於 java 中swtich, choose只是一個容器,包含下面兩個元素 |

| when | 能夠出現多個,用於每一個判斷條件,相似於 switch 中 case。有一個 test 屬性,與 if 功能相同 |

| otherwise | 若是上面全部的條件都不知足,執行 otherwise 內容。相似於 switch 中 default |



### 9.2.三、<c:forEach>



? 用於遍歷集合或數組(最爲經常使用)。



| 屬性名 | 是否支持EL | 屬性類型 | 屬性描述 |

| --- | --- | --- | --- |

| items | true | 數組或集合 | 使用 EL 表達式,表明集合或數組 |

| var | false | String | var 的變量名錶明集合中的每個元素 |

| varStatus | false | String | 表明每一個元素的狀態對象,  

一共有4個屬性,屬性的含義見下表 |



? varStatus屬性表:



| 屬性 | 數據類型 | 含義 |

| --- | --- | --- |

| index | int | 當前遍歷到的這個元素索引號,從 0 開始 |

| **count** | int | 遍歷到當前爲止,一共遍歷了多少個元素,從1 開始 |

| first | boolean | 若是當前遍歷的是第1個元素,則返回true |

| last | boolean | 若是當前遍歷的是最後1個元素,則返回true |

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<title>學生信息表</title>

<style>

    tr {

        text-align: center;

    }

</style>
<caption>學生信息列表</caption>

<tr>

    <th>序號</th>

    <th>學號</th>

    <th>姓名</th>

    <th>性別</th>

    <th>成績</th>

</tr>



<%--

    forEach標籤:用於JSP頁面遍歷集合和數組

        items屬性:設置要遍歷的集合或數組:通常從做用域中獲取

        var屬性:設置一個變量名:用來接收遍歷到的每個元素



        varStatus屬性:設置一個變量名:記錄當前遍歷元素的狀態(狀態對象)

            index 屬性:當前遍歷元素的在集合中的索引值:從0開始

            count 屬性:遍歷到當前元素爲止已經遍歷了多少個元素,從 1 開始

--%>

<c:forEach items="${stus}" var="stu" varStatus="status">

    <!-- 給偶數行設置背景顏色 -->

    <tr style="background-color:${status.count % 2 == 0 ? 'gray;' : ''}">

        <td>${status.count}</td>

        <td>${stu.id}</td>

        <td>${stu.name}</td>

        <td>${stu.gender? "男":"女"}</td>

        <td>${stu.score}</td>

    </tr>

</c:forEach>

複製代碼

9.三、格式化標籤庫經常使用標籤



# 最後

針對最近不少人都在面試,我這邊也整理了至關多的面試專題資料,也有其餘大廠的面經。但願能夠幫助到你們。

![image](https://upload-images.jianshu.io/upload_images/24613101-bd5471b3c4055df2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



> 上述的面試題答案都整理成文檔筆記。 也還整理了一些面試資料&最新2021收集的一些大廠的面試真題(都整理成文檔,小部分截圖)
>
> **資料領取方式:[點擊這裏免費獲取](https://gitee.com/vip204888/java-p7)**

![image](https://upload-images.jianshu.io/upload_images/24613101-037ac3b223a0b02e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)




以上就是本文的所有內容,但願對你們的學習有所幫助,也但願你們多多支持。
相關文章
相關標籤/搜索