Servlet程式
一、Servlet 技術
1、什么是 Servlet
① Servlet 是 JavaEE 規范之一,規范就是介面
② Servlet 就 JavaWeb 三大組件之一,三大組件分別是:Servlet 程式、Filter 過濾器、Listener 監聽器,
③ Servlet 是運行在服務器上的一個 java 小程式,它可以接收客戶端發送過來的請求,并回應資料給客戶端,
2、手動實作 Servlet 程式
① 撰寫一個類去實作Servlet介面:


② 重寫service()方法,處理請求,并回應資料:
package com.zixue.servlet; import javax.servlet.*; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-10 10:57 */ public class HelloServlet implements Servlet { @Override public void init(ServletConfig config) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("HelloServlet被訪問了"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
③ 到web.xml中去配置Servlet程式的訪問地址:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- servlet標簽給Tomcat服務器配置Servlet程式--> <servlet> <!-- servlet-name標簽給Servlet程式起一個別名(一般是類名)--> <servlet-name>HelloServlet</servlet-name> <!-- servlet-class標簽是Servlet程式的全類名--> <servlet-class>com.zixue.servlet.HelloServlet</servlet-class> </servlet> <!-- servlet-mapping標簽給Servlet程式配置訪問地址--> <servlet-mapping> <!-- servlet-name標簽是配置的訪問地址給哪個Servlet程式使用的--> <servlet-name>HelloServlet</servlet-name> <!-- url-pattern標簽配置訪問地址 / : 在服務器決議的時候,表示的路徑為:http://ip:port/工程路徑 (映射到web目錄) /helloServlet : 表示這個Servlet程式的訪問地址為:http://ip:port/工程路徑/helloServlet --> <url-pattern>/helloServlet</url-pattern> </servlet-mapping> </web-app>
3、url 地址到 Servlet 程式的訪問

4、Servlet 的生命周期
① 執行Servlet構造器方法;
② 執行init初始化方法;
③ 執行service方法;
④ 執行destroy銷毀方法,
注:
① 和②是在第一次訪問創建Servlet程式的時候呼叫;
③ 每次訪問都會呼叫;
④ 在整個web工程停止的時候呼叫,
package com.zixue.servlet; import com.sun.media.sound.SoftTuning; import javax.servlet.*; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-10 10:57 */ public class HelloServlet implements Servlet { public HelloServlet() { System.out.println("1.構造器方法執行"); } @Override public void init(ServletConfig config) throws ServletException { System.out.println("2.init初始化方法執行"); } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("3.HelloServlet被訪問了"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { System.out.println("4.執行destroy銷毀方法"); } }
瀏覽器地址欄第一次訪問:


繼續訪問:

當停止整個web工程的時候:


5、GET 和 POST 請求的分發處理
我們在service方法中做請求的分發處理,service方法的形參位置有一個ServletRequest介面,它有一個子介面HttpServletRequest,其內部有一個方法getMethod(),這個方法可以實作請求的分發處理,

在web下創建一個form.html檔案,提供請求的方式GET/POST:

form.html檔案:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>請求的分發</title> </head> <body> <form action="http://localhost:8080/06_servlet/helloServlet1" method="get"> <input type="submit" /> </form> </body> </html>
要訪問的Servlet程式:HelloServlet1.java
package com.zixue.servlet; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-10 11:26 */ public class HelloServlet1 implements Servlet { @Override public void init(ServletConfig config) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { //1.型別轉換:ServletRequest -- httpServletRequest(它有getMethod()) HttpServletRequest httpServletRequest = (HttpServletRequest) req; //2.獲取請求的方式 String method = httpServletRequest.getMethod(); if ("GET".equals(method)){ doGet(); }else if ("POST".equals(method)){ doPost(); } } /** * 做GET請求的操作 */ public void doGet(){ System.out.println("GET請求"); System.out.println("GET請求"); } /** * 做POST請求的操作 */ public void doPost(){ System.out.println("POST請求"); System.out.println("POST請求"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
瀏覽器地址欄訪問form.html檔案:


結果如下:

修改form.html檔案中的請求方式為post:

再次訪問效果如下:

6、通過繼承 HttpServlet 實作 Servlet 程式
一般在實際專案開發中,都是使用繼承 HttpServlet 類的方式去實作 Servlet 程式,具體實作步驟:
① 撰寫一個類去繼承HttpServlet類:
② 根據業務需要重寫doGet()或doPost()方法:
③ 到web.xml中配置Servlet程式的訪問地址;
HelloServlet2.java:
package com.zixue.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-10 11:53 */ public class HelloServlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("HelloServlet2的doGet方法"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("HelloServlet2的doPost方法"); } }
web.xml:

7、使用 IDEA 創建 Servlet 程式

配置Servlet的資訊:

web.xml中配置訪問地址:

8、Servlet 類的繼承體系

二、ServletConfig 類
ServletConfig 類從類名上來看,就知道是 Servlet 程式的配置資訊類, Servlet 程式和 ServletConfig 物件都是由 Tomcat 負責創建,我們負責使用, Servlet 程式默認是第一次訪問的時候創建,ServletConfig 是每個 Servlet 程式創建時,就創建一個對應的 ServletConfig 物件,1、ServletConfig 類的三大作用
① 獲取Servlet程式的別名servlet-name的值;
② 獲取初始化引數init-param的值;
③ 獲取ServletContext物件,
web.xml中的配置:

Servlet中的代碼:

效果如下:

注意點:

三、ServletContext 類
1、什么是 ServletContext?
① ServletContext 是一個介面,它表示 Servlet 背景關系物件;
② 一個 web 工程,只有一個 ServletContext 物件實體;
③ ServletContext 物件是一個域物件;
④ ServletContext 是在 web 工程部署啟動的時候創建,在 web 工程停止的時候銷毀,
什么是域物件? 域物件,是可以像 Map 一樣存取資料的物件,叫域物件, 這里的域指的是存取資料的操作范圍,整個 web 工程,
2、ServletContext 類的四個作用
① 獲取 web.xml 中配置的背景關系引數 context-param;
② 獲取當前的工程路徑,格式: /工程路徑;
③ 獲取工程部署后在服務器硬碟上的絕對路徑;
④ 像 Map 一樣存取資料,
web.xml 中的配置:
演示ServletContext作用的代碼:
package com.zixue.servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-10 13:41 */ public class Servlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.獲取web.xml中配置的背景關系引數 ServletContext context = getServletContext(); String username = context.getInitParameter("username"); System.out.println("背景關系引數username = " + username); String password = context.getInitParameter("password"); System.out.println("背景關系引數password = " + password); //2.獲取當前的工程路徑 格式:/工程路徑 System.out.println("當前工程路徑:" + context.getContextPath()); //3.獲取工程部署后在服務器磁盤上的絕對路徑 System.out.println("工程部署的路徑是:" + context.getRealPath("/")); } }
效果如下:

當前的工程就在服務器磁盤的如下位置:

ServletContext像Map一樣存取資料:
ContextServlet1代碼:
package com.zixue.servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-10 13:57 */ public class ContextServlet1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = getServletContext(); System.out.println("保存之前,ContextServlet1獲取key的值是:" + context.getAttribute("key")); context.setAttribute("key", "value"); System.out.println("保存之后,ContextServlet1獲取key的值是:" + context.getAttribute("key")); } }
ContextServlet2代碼:
package com.zixue.servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-10 13:59 */ public class ContextServlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = getServletContext(); System.out.println("ContextServlet2中獲取的key值為:" + context.getAttribute("key")); } }
注:ServletContext物件在整個web工程只有一份,域資料未保存之前是無法獲取到的,當域資料保存之后,無論在哪個Servlet程式中都可以進行訪問,
四、HTTP 協議
1、什么是 HTTP 協議
什么是協議? 協議是指雙方,或多方,相互約定好,大家都需要遵守的規則,叫協議, 所謂 HTTP 協議,就是指,客戶端和服務器之間通信時,發送的資料,需要遵守的規則,叫 HTTP 協議, HTTP 協議中的資料又叫報文,2、請求的 HTTP 協議格式




3、哪些是 GET 請求,哪些是 POST 請求
GET請求:
① form標簽中的method=get
② a標簽
③ link標簽引入css
④ script標簽引入js
⑤ img標簽引入圖片
⑥ iframe引入html頁面
⑦ 瀏覽器地址欄輸入地址敲回車
POST請求:
form標簽中的method=post
4、回應的 HTTP 協議格式


5、常用的回應碼說明
200 --- 請求成功
302 --- 請求重定向
404 --- 瀏覽器地址欄地址找不到
500 --- 服務器代碼錯誤
五、HttpServletRequest 類
1、HttpServletRequest 類有什么作用
每次只要有請求進入 Tomcat 服務器,Tomcat 服務器就會把請求過來的 HTTP 協議資訊決議好封裝到 Request 物件中,然后傳遞到 service 方法(doGet 和 doPost)中給我們使用,我們可以通過 HttpServletRequest 物件,獲取到所有請求的資訊,2、HttpServletRequest 類的常用方法

RequestAPIServlet.java:
package com.zixue.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author Mr Guo * @create 2020-11-10 14:51 */ public class RequestAPIServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.獲取請求的資源路徑 System.out.println("URI = " + req.getRequestURI()); //2.獲取請求的統一資源定位符 System.out.println("URL = " + req.getRequestURL()); //3.獲取客戶端的ip地址 System.out.println("客戶端ip地址為:" + req.getRemoteHost()); //4.獲取請求頭 System.out.println("請求頭User-Agent的值為:" + req.getHeader("User-Agent")); //5.獲取請求引數 System.out.println("請求引數username = " + req.getParameter("username")); System.out.println("請求引數password = " + req.getParameter("password")); //6.獲取請求的方式 System.out.println("請求方式為:" + req.getMethod()); } }
瀏覽器地址欄訪問:

效果如下:

3、POST 請求的中文亂碼解決

4、請求的轉發
什么是請求的轉發? 請求轉發是指,服務器收到請求后,從一個資源跳轉到另一個資源的操作叫請求轉發,
Servlet1代碼:
public class Servlet1 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //請求的轉發 //1.獲取請求的引數 String username = request.getParameter("username"); System.out.println("Servlet1中的請求引數username = " + username); //2.向request域中保存資料 request.setAttribute("key","value"); //3.獲取請求轉發的物件 /* 請求轉發必須要以斜杠打頭,/ 斜杠表示地址為:http://ip:port/工程名/ , 映射到 IDEA 代碼的 web 目錄 */ RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet2"); //4.前往Servlet2 requestDispatcher.forward(request,response); } }
Servlet2代碼:
public class Servlet2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.獲取請求的引數 String username = request.getParameter("username"); System.out.println("Servlet2中的請求引數username = " + username); //2.獲取request域中保存的資料 System.out.println(request.getAttribute("key")); //3.處理自己的業務 System.out.println("Servlet2自己的業務"); } }
瀏覽器地址欄訪問:

效果如下:

5、base 標簽的作用
在web目錄下有一個index.html頁面,內容如下:

在web/a/b目錄下有一個c.html頁面,內容如下:

目錄結構如下:

啟動當前工程,默認會訪問當前工程的index.html頁面:

點擊超鏈接a標簽會跳轉到c.html頁面:

它們之間的跳轉是沒有任何問題的(可以來回跳轉),解釋如下:
所有的相對路徑在跳轉的時候都會相對于瀏覽器地址欄中的地址進行跳轉,在index.html頁面,瀏覽器地址欄中的地址是:http://localhost:8080/06_servlet/index.html,映射到當前工程的web目錄下,點擊超鏈接,超鏈接的地址為:a/b/c.html,此時的跳轉沒有任何問題,在c.html頁面,瀏覽器地址欄的地址為:http://localhost:8080/06_servlet/a/b/c.html,點擊超鏈接,超鏈接地址為:../../index.html,父親的父親剛好映射到web目錄,此時的跳轉也沒有問題,
使用請求轉發進行跳轉:
Servlet程式ForwardC.java如下:

工程啟動后,默認訪問index.html頁面,此時,我們訪問ForwardC這個Servlet程式:http://localhost:8080/06_servlet/forwardC,會轉發到c.html頁面:

此時,點擊超鏈接,超鏈接地址為:../../index.html,瀏覽器地址欄地址為:http://localhost:8080/06_servlet/forwardC,這時已經無法訪問到index.html頁面了,
那么,如何解決這個問題呢?
使用base標簽:

6、Web 中的相對路徑和絕對路徑

7、web 中 / 斜杠的不同意義

六、HttpServletResponse 類
1、HttpServletResponse 類的作用
HttpServletResponse 類和 HttpServletRequest 類一樣,每次請求進來,Tomcat 服務器都會創建一個 Response 物件傳遞給 Servlet 程式去使用,HttpServletRequest 表示請求過來的資訊,HttpServletResponse 表示所有回應的資訊,我們如果需要設定回傳給客戶端的資訊,都可以通過 HttpServletResponse 物件來進行設定2、兩個輸出流的說明

兩個流同時只能使用一個, 使用了位元組流,就不能再使用字符流,反之亦然,否則就會報錯,
3、如何往客戶端回傳資料
public class ResponseIOServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter writer = response.getWriter(); writer.write("response's content"); } }
效果如下:

4、回應的亂碼解決
當我們試圖向客戶端回傳帶有中文的資料時:

會出現如下的亂碼問題:

怎么解決呢?

效果如下:

5、請求重定向
請求重定向,是指客戶端給服務器發請求,然后服務器告訴客戶端說,我給你一些地址,你去新地址訪問,叫請求重定向(因為之前的地址可能已經被廢棄),
Response1代碼:

Response2代碼:

效果如下:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/209839.html
標籤:Java
上一篇:Java變數型別Java變數型別
下一篇:Java常用類:Arrays類
