礎知識,servlet是什么?
官方解釋:Servlet 是運行在 Web 服務器或應用服務器上的程序,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務器上的數據庫或應用程序之間的中間層
簡單來說,servlet是運行在web服務器如tomcat,jetty這樣應用服務器上的一段程序,他可以響應http協議的請求,并且實現用戶自己的邏輯,最終將結果返回到用戶的客戶端(瀏覽器)
Java Servlet 通常情況下與使用 CGI(Common Gateway Interface,公共網關接口)實現的程序可以達到異曲同工的效果。但是相比于 CGI,Servlet 有以下幾點優勢:
1、性能明顯更好。
2、Servlet 在 Web 服務器的地址空間內執行。這樣它就沒有必要再創建一個單獨的進程來處理每個客戶端請求。
3、Servlet 是獨立于平臺的,因為它們是用 Java 編寫的。
4、服務器上的 Java 安全管理器執行了一系列限制,以保護服務器計算機上的資源。因此,Servlet 是可信的。
5、Java 類庫的全部功能對 Servlet 來說都是可用的。它可以通過 sockets 和 RMI 機制與 applets、數據庫或其他軟件進行交互。
Servlet的生命周期
Servlet 生命周期可被定義為從創建直到毀滅的整個過程。以下是 Servlet 遵循的過程:
1、Servlet 通過調用 init () 方法進行初始化。
2、Servlet 調用 service() 方法來處理客戶端的請求。
3、Servlet 通過調用 destroy() 方法終止(結束)。
4、最后,Servlet 是由 JVM 的垃圾回收器進行垃圾回收的
init() 方法
init 方法被設計成只調用一次。它在第一次創建 Servlet 時被調用,在后續每次用戶請求時不再調用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一樣。
Servlet 創建于用戶第一次調用對應于該 Servlet 的 URL 時,但是您也可以指定 Servlet 在服務器第一次啟動時被加載。
service() 方法
service() 方法是執行實際任務的主要方法。Servlet 容器(即 Web 服務器)調用 service() 方法來處理來自客戶端(瀏覽器)的請求,并把格式化的響應寫回給客戶端。
每次服務器接收到一個 Servlet 請求時,服務器會產生一個新的線程并調用服務。service() 方法檢查 HTTP 請求類型(GET、POST、PUT、DELETE 等),并在適當的時候調用 doGet、doPost、doPut,doDelete 等方法。
destroy() 方法
destroy() 方法只會被調用一次,在 Servlet 生命周期結束時被調用。destroy() 方法可以讓您的 Servlet 關閉數據庫連接、停止后臺線程、把 Cookie 列表或點擊計數器寫入到磁盤,并執行其他類似的清理活動。
在調用 destroy() 方法之后,servlet 對象被標記為垃圾回收。
JSP是什么?
JSP全稱Java Server Pages,是一種動態網頁開發技術。它使用JSP標簽在HTML網頁中插入Java代碼。標簽通常以<%開頭以%>結束。
JSP是一種Java servlet,主要用于實現Java web應用程序的用戶界面部分。網頁開發者們通過結合HTML代碼、XHTML代碼、XML元素以及嵌入JSP操作和命令來編寫JSP。
JSP通過網頁表單獲取用戶輸入數據、訪問數據庫及其他數據源,然后動態地創建網頁。
JSP標簽有多種功能,比如訪問數據庫、記錄用戶選擇信息、訪問JavaBeans組件等,還可以在不同的網頁中傳遞控制信息和共享信息。
servlet和jsp的區別
1、Servlet在Java代碼中可以通過HttpServletResponse對象動態輸出HTML內容。
2、JSP是在靜態HTML內容中嵌入Java代碼,然后Java代碼在被動態執行后生成HTML內容。
servlet和jsp各自的特點
1、Servlet雖然能夠很好地組織業務邏輯代碼,但是在Java源文件中,因為是通過字符串拼接的方式生成動態HTML內容,這樣就容易導致代碼維護困難、可讀性差。
2、JSP雖然規避了Servlet在生成HTML內容方面的劣勢,但是在HTML中混入大量、復雜的業務邏輯。
MVC的誕生
JSP和Servlet都有自身的適用環境,那么有沒有什么辦法能夠讓它們發揮各自的優勢呢?答案是肯有的,MVC模式就能夠完美解決這一問題。
MVC模式,是Model-View-Controller的簡稱,是軟件工程中的一種軟件架構模式,分為三個基本部分,分別是:模型(Model)、視圖(View)和控制器(Controller):
Controller——負責轉發請求,對請求進行處理
View——負責界面顯示
Model——業務功能編寫(例如算法實現)、數據庫設計以及數據存取操作實現
在JSP/Servlet開發的軟件系統中,這三個部分的描述如下所示:
MVC模型
1、Web瀏覽器發送HTTP請求到服務端,然后被Controller(Servlet)獲取并進行處理(例如參數解析、請求轉發)
2、Controller(Servlet)調用核心業務邏輯——Model部分,獲得結果
3、Controller(Servlet)將邏輯處理結果交給View(JSP),動態輸出HTML內容
4、動態生成的HTML內容返回到瀏覽器顯示
MVC模式在Web開發中有很大的優勢,它完美規避了JSP與Servlet各自的缺點,讓Servlet只負責業務邏輯部分,而不會生成HTML代碼;同時JSP中也不會充斥著大量的業務代碼,這樣大大提高了代碼的可讀性和可維護性。
相關面試題
如何讀取Servlet的初始化參數?
ServletConfig中定義了如下的方法用來讀取初始化參數的信息:
public String getInitParameter(String name)
參數:初始化參數的名稱。
返回:初始化參數的值,如果沒有配置,返回null。
init(ServletConfig)方法執行次數
在Servlet的生命周期中,該方法執行一次。
service()方法的職責
service()方法為Servlet的核心方法,客戶端的業務邏輯應該在該方法內執行,典型的服務方法的開發流程為:
解析客戶端請求-〉執行業務邏輯-〉輸出響應頁面到客戶端
get方式和post方式有何區別
數據攜帶上:
GET方式:在URL地址后附帶的參數是有限制的,其數據容量通常不能超過1K。
POST方式:可以在請求的實體內容中向服務器發送數據,傳送的數據量無限制。
請求參數的位置上:
GET方式:請求參數放在URL地址后面,以?的方式來進行拼接
POST方式:請求參數放在HTTP請求包中
用途上:
GET方式一般用來獲取數據
POST方式一般用來提交數據
原因:
首先是因為GET方式攜帶的數據量比較小,無法帶過去很大的數量
POST方式提交的參數后臺更加容易解析(使用POST方式提交的中文數據,后臺也更加容易解決)
GET方式比POST方式要快
Servlet相關 API
HttpServletRequest:封裝了與請求相關的信息
HttpServletResponse:封裝了與響應相關的信息
獲取頁面的元素的值有幾種方式,分別說一下
request.getParameter() 返回客戶端的請求參數的值
request.getParameterNames() 返回所有可用屬性名的枚舉
request.getParameterValues() 返回包含參數的所有值的數組
request.getAttribute()和request.getParameter()區別
用途上:
request.getAttribute(), 一般用于獲取request域對象的數據(在跳轉之前把數據使用setAttribute來放到request對象上)
request.getParameter(), 一般用于獲取客戶端提交的參數
存儲數據上:
request.getAttribute()可以獲取Objcet對象
request.getParameter()只能獲取字符串(這也是為什么它一般用于獲取客戶端提交的參數)
forward和redirect的區別
實際發生位置不同,地址欄不同
轉發是發生在服務器的
轉發是由服務器進行跳轉的,細心的朋友會發現,在轉發的時候,瀏覽器的地址欄是沒有發生變化的,在我訪問Servlet111的時候,即使跳轉到了Servlet222的頁面,瀏覽器的地址還是Servlet111的。也就是說瀏覽器是不知道該跳轉的動作,轉發是對瀏覽器透明的。通過上面的轉發時序圖我們也可以發現,實現轉發只是一次的http請求,一次轉發中request和response對象都是同一個。這也解釋了,為什么可以使用request作為域對象進行Servlet之間的通訊。
重定向是發生在瀏覽器的
重定向是由瀏覽器進行跳轉的,進行重定向跳轉的時候,瀏覽器的地址會發生變化的。曾經介紹過:實現重定向的原理是由response的狀態碼和Location頭組合而實現的。這是由瀏覽器進行的頁面跳轉實現重定向會發出兩個http請求,**request域對象是無效的,因為它不是同一個request對象
用法不同:
很多人都搞不清楚轉發和重定向的時候,資源地址究竟怎么寫。有的時候要把應用名寫上,有的時候不用把應用名寫上。很容易把人搞暈。記住一個原則: 給服務器用的直接從資源名開始寫,給瀏覽器用的要把應用名寫上
request.getRequestDispatcher("/資源名 URI").forward(request,response)
轉發時"/"代表的是本應用程序的根目錄【zhongfucheng】
response.send("/web應用/資源名 URI");
重定向時"/"代表的是webapps目錄
能夠去往的URL的范圍不一樣:
轉發是服務器跳轉只能去往當前web應用的資源
重定向是服務器跳轉,可以去往任何的資源
傳遞數據的類型不同
轉發的request對象可以傳遞各種類型的數據,包括對象
重定向只能傳遞字符串
跳轉的時間不同
轉發時:執行到跳轉語句時就會立刻跳轉
重定向:整個頁面執行完之后才執行跳轉
典型的應用場景:
轉發: 訪問 Servlet 處理業務邏輯,然后 forward 到 jsp 顯示處理結果,瀏覽器里 URL 不變
重定向: 提交表單,處理成功后 redirect 到另一個 jsp,防止表單重復提交,瀏覽器里 URL 變了
精品長文創作季#
JSP,全稱是Java Server Pages,中文含義是Java服務端頁面,它是一種用于動態網頁開發的技術,本質上就是Servlet程序,只不過JSP是將Servlet中和HTML、CSS、JavaScript等界面相關的代碼單獨抽取出來,從而形成了JSP,下面就介紹一下JSP程序。
JSP是專門用于前端界面顯示的一個文件,為什么會出現JSP呢???首先我們來看下,JSP沒有出來之前,如果我們要使用Servlet程序編寫一個HTML界面,此時你會寫出下面的代碼:
package com.gitcode.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @version 1.0.0
* @Date: 2024/2/10 20:20
* @Author ZhuYouBin
* @Description:
*/
public class HtmlResponseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 響應HTML內容
response.setContentType("text/html;charset=UTF-8");
// 獲取輸出流
PrintWriter writer=response.getWriter();
// 輸出HTML內容
writer.println("<!DOCTYPE html>");
writer.println("<html lang=\"en\">");
writer.println("<head>");
writer.println(" <meta charset=\"UTF-8\">");
writer.println(" <title>響應HTML內容</title>");
writer.println("</head>");
writer.println("<body>");
writer.println(" <h3>Hello World!你好,世界!</h3>");
writer.println("</body>");
writer.println("</html>");
// 關閉流
writer.close();
}
}
從上面代碼中,可以看出來,開發一個HTML界面,需要使用writer輸出流,將HTML代碼拼接起來,通過HttpServletResponse響應對象,返回給客戶端。
可想而知,這是多么復雜的事情,這還只是一個HTML界面,一個Web工程中有著幾十、幾百個HTML,那么通過這種編碼方式,一方面開發效率非常低,另一方面后期維護起來的時候,也是非常困難。
所以,為了解決這個問題,Sun公司就提出了一種新的動態網頁開發技術,也就是我們這里所學的JSP程序。
JSP是如何解決輸出HTML問題的呢???
我們這樣想一下,在上面的代碼中,大部分代碼都是使用writer.println()方法輸出HTML標簽內容,那么我們能不能將這一部分代碼單獨抽取出來,然后在程序運行的時候,再把這些代碼嵌入到對應的位置,最終拼接成一個完整的HTML返回給客戶端。
Sun公司就是采用了這種思想,將這些和HTML相關的代碼都單獨抽取了出來,將其單獨保存到一個以【.jsp】為后綴的文件里面,這個.jsp文件就叫做JSP程序。Sun公司開發了一個JSP引擎程序,在程序運行過程中,通過JSP引擎將對應的jsp文件渲染成Servlet程序,最終將渲染的結果響應給客戶端,這樣就實現了簡化Servlet的開發。
所以說,JSP程序本質上就是Servlet程序,這是因為JSP引擎會將我們訪問的JSP文件,渲染成Servlet程序,然后再執行這個Servlet程序,從而完成客戶端的響應處理。
創建JSP程序非常簡單,我們只需要創建一個以【.jsp】為后綴的文件,接著編寫相關的代碼即可。在IDEA中的web目錄下,創建一個HelloWorld.jsp文件,如下:
這樣就創建成功啦!!!啟動Tomcat容器,瀏覽器訪問http://localhost:8080/servlet/HelloWorld.jsp地址,看到下面內容,那么第一個JSP程序就算完成啦。
PS:一般情況下,我們會將jsp文件保存在WEB-INF目錄下面,因為這個目錄下的文件是受保護的,瀏覽器不能直接訪問。
今天就到這里,未完待續~~
SP全稱是Java Server Pages
它和servle技術一樣,都是SUN公司定義的一種用于開發動態web資源的技術
JSP實際上就是Servlet
jsp運行原理
瀏覽器訪問服務器上jsp頁面
服務器中jsp-->翻譯成.java文件-->編譯成.class文件
jsp和servlet最佳使用方式
servlet:獲取參數 處理邏輯 請求轉發
jsp:html界面 數據回顯
jsp的基本語法
jsp注釋<%--注釋內容--> 特點:安全,省流量
網頁注釋:<!-- 網頁注釋 --> 特點:不安全,費流量
小腳本 <% java代碼 %>
聲明成員變量和方法 <%! %>
顯示數據 <%=%>相當于out.print()
3個指令
(1)page
<%@page ...%>
session開關 默認開啟
pageEncoding 設置本頁面的編碼格式
contextType: 等同于response.setContextType("text/html;charset=utf-8");
errorPage: 如果頁面中有錯誤,則跳轉到指定的資源。
isErrorPage:默認是關閉的 開啟后可以使用exception對象來獲取異常信息
(2)include
靜態包含:把其它資源包含到當前頁面中。
在翻譯時就把兩個文件合并
<%@ include file="/include/1.jsp" %>
動態包含:不會合并文件,當代碼執行到include時,才包含另一個文件的內容。
<jsp:include page="/include/1.jsp"></jsp:include>
(3)taglib
作用:在JSP頁面中導入JSTL標簽庫。替換jsp中的java代碼片段。
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
6個動作
<jsp:include > 動態包含
<jsp:forward> 請求轉發
<jsp:param> 設置請求參數
<jsp:forward page="/7.jsp">
<jsp:param value="wanglong" name="username"/>
<jsp:param value="123" name="password"/>
</jsp:forward>
<jsp:useBean> 創建一個對象
<!-- 使用userbean標簽創建一個對象
id表示創建對象的名字
class表示使用哪個類創建該對象
-->
<jsp:setProperty> 給指定的對象屬性賦值
<jsp:getProperty> 取出指定對象的屬性值
//name表示要賦值那個對象
jsp的9個內置對象
request
response
session
application
exception 獲取異常信息 默認是關上的
page 當前servlet實例 this
config
out
pageContext(利用pageContext對象 往各個域中存值)
參數3表示向哪個域里存值
pageContext.setAttribute("www", "request",PageContext.REQUEST_SCOPE);
全域查找 域從小到大進行查找
<%=pageContext.findAttribute("www") %>
EL表達式
一個書寫規范,提供了java代碼在jsp頁面的簡便書寫方式
功能
1.獲取存在4個作用域中的數據
${u} 相當于 pageContext.findAttribute("u");
EL獲取對于null這樣的數據,在頁面中表現為空字符串
判斷空值的方法
關鍵詞 empty
${empty u}
支持三目判斷
${empty str3?"我是前面的":"我是后面的" }
獲取對象的屬性值 javaBean導航(對象導航)
內部就相當于調用了getUsername()方法
用點能獲取的 用[]都能獲取
用[]獲取的 點獲取不了
使用隱式對象 指定域找對應的值
${pageScope.xx}
${requestScope.xx }
${sessionScope.xx }
${applicationScope.xx }
獲取表單提交的數據
${param.username }
${param.password }
${paramValues.hobby[0] }
*請認真填寫需求信息,我們會在24小時內與您取得聯系。