文章目錄
通過servlet實現登錄功能
來自於how2java
步驟一:創建login.html
- ctrl+n 新建 html
- 添加form元素:
- action=“login” 標題會提交到login路徑,login路徑在後續步驟會映射到LoginServlet
- method=“post” post方式表示提交的密碼信息在瀏覽器地址欄看不到
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登錄頁面</title>
</head>
<body>
<form action="login" method="post">
賬號: <input type="text" name="name"> <br>
密碼: <input type="password" name="password"> <br>
<input type="submit" value="登錄">
</form>
</body>
</html>
步驟二:創建LoginServlet
- 因爲瀏覽器中的form的method是post,所以LoginServlet需要提供一個doPost方法
- 在doPost方法中,通過request.getParameter 根據name取出對應的賬號和密碼
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println("name:" + name);
System.out.println("password:" + password);
}
}
步驟四:映射loginservlet到路徑login
- 即爲了當訪問login.html 點擊form action時候,對應的login 映射到servlet,
- 在web.xml中新增映射
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
步驟五:提交數據
- 重啓tomcat
- 訪問
http://localhost/login
步驟六:返回html響應
根據瀏覽器提交的賬號密碼返回登錄成功或者失敗
這一步本來應該通過訪問數據庫來實現,這裏簡化一下,直接在內存中進行校驗
如果賬號是 admin,密碼是123, 就返回登錄成功,否則返回登錄失敗
- 判斷賬號密碼是否爲 admin 123,如果是就打印
success 否則就打印 fail - 根據賬號密碼,創建對應的html字符串。
- 然後通過response.getWriter().println() 發送到瀏覽器。
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
String password = request.getParameter("password");
String html = null;
if ("admin".equals(name) && "123".equals(password))
html = "<div style='color:green'>success</div>";
else
html = "<div style='color:red'>fail</div>";
PrintWriter pw = response.getWriter();
pw.println(html);
}
}
注:在response中寫html只是爲了自己練習
總結:servlet流程梳理
- 流程圖:
- login.html: 首先訪問
http://127.0.0.1/login.html
:打開一個靜態html,這個頁面可以通過form,以post的方式提交數據 - /login路徑: 在上一步的login.html中,用form,把賬號和密碼,提交到/login這個路徑,並且附帶method=“post”
- 找到對應的Servlet: tomcat接到一個請求
http://localhost/login
,路徑是/login
,就去web.xml
中進行匹配,根據標籤<servlet-mapping>
會匹配到LoginServlet
,接下來根據這個servlet進行 - 實例化servlet對象: tomcat定位到
LoginServlet
,發現沒有實例存在,於是就調用LoginServlet的構造方法實例化一個對象。 - 調用doGet或者doPost: Tomcat拿到LoginServlet後,就根據頁面login.html提交的信息
method="post"
去調用對應的doPost方法;<form action="login" method="post">
表示這個form會提交到action login - request獲取參數: doPost方法中
protected void doPost(HttpServletRequest request, HttpServletResponse response){ ... }
其中通過參數request,取出頁面提交的信息:
String name = request.getParameter("name"); String password = request.getParameter("password");
- **response響應:**把html字符串通過如下方式,設置在了response對象上。
PrintWriter pw = response.getWriter(); pw.println(html);
- tomcat把html傳遞給瀏覽器::在Servlet完成工作之後,tomcat拿到被Servlet修改過的response,根據這個response生成html 字符串,然後再通過HTTP協議,這個html字符串,回發給瀏覽器,瀏覽器再根據HTTP協議獲取這個html字符串,並渲染在界面上。
這樣在效果上,瀏覽器就可以看到Servlet中生成的字符串了
doService
-
doGet(): 當瀏覽器使用get方式提交數據的時候,servlet需要提供doGet()方法
- form默認的提交方式
- 如果通過一個超鏈訪問某個地址
- 如果在地址欄直接輸入某個地址
- ajax指定使用get方式的時候
-
doPost(): 當瀏覽器使用post方式提交數據的時候,servlet需要提供doPost()方法
- 在form上顯示設置 method="post"的時候
- ajax指定post方式的時候
-
service(): LoginServlet繼承了HttpServlet,同時也繼承了一個方法:
service(HttpServletRequest , HttpServletResponse )
- 實際上,在執行doGet()或者doPost()之前,都會先執行service(),由service()方法進行判斷,到底該調用doGet()還是doPost()
- service(), doGet(), doPost() 三種方式的參數列表都是一樣的。
- 所以,有時候也會直接重寫service()方法,在其中提供相應的服務,就不用區分到底是get還是post了。
- 比如把前面的登錄的LoginServlet,改爲提供service方法,也可以達到相同的效果:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
String password = request.getParameter("password");
String html = null;
if ("admin".equals(name) && "123".equals(password))
html = "<div style='color:green'>success</div>";
else
html = "<div style='color:red'>fail</div>";
PrintWriter pw = response.getWriter();
pw.println(html);
}
}
獲取中文參數
login.html
中加上<meta http-equiv="Content-Type" content="text/html;charset="UTF-8">
這句話的目的是告訴瀏覽器,等下發消息給服務器的時候,使用UTF-8編碼- 在servlet進行編碼解碼:
- 當servlet不編碼解碼直接拿string:
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //request.setCharacterEncoding("UTF-8"); String name = request.getParameter("name"); /*byte[] bytes = name.getBytes("ISO-8859-1"); name = new String(bytes, "UTF-8");*/ String password = request.getParameter("password"); System.out.println("name:" + name); }```
-
當添加
byte[] bytes = name.getBytes("ISO-8859-1");
name = new String(bytes, "UTF-8");
先根據ISO-8859-1解碼,然後用UTF-8編碼
這樣就可以得到正確的中文參數了 -
這樣需要對每一個提交的數據都進行編碼和解碼處理,如果覺得麻煩,也可以使用一句話代替:
request.setCharacterEncoding("UTF-8");
不過這句話要在request.getParameter("name");
之前,因爲如果不setCharactoerEncoding()
,servlet會默認使用iso8859-1
進行編碼,這也是我們上面byte[] bytes = name.getBytes("ISO-8859-1");
name = new String(bytes, "UTF-8");
的原理。 -
返回中文響應:同理,在servlet中加上
response.setContentType("text/html; charset=UTF-8");
所以這段代碼:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String password = request.getParameter("password");
//System.out.println("name:" + name);
String html = null;
if ("admin".equals(name) && "123".equals(password))
html = "<div style='color:green'>登錄成功</div>";
else
html = "<div style='color:red'>登錄失敗</div>";
response.setContentType("text/html; charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.println(html);
}
}
生命週期
- 一個Servlet的生命週期由 實例化,初始化,提供服務,銷燬,被回收 幾個步驟組成
- 實例化:當用戶通過瀏覽器輸入一個路徑,這個路徑對應的servlet被調用的時候,該Servlet就會被實例化
- 無論訪問了多少次LoginServlet,LoginServlet構造方法 只會執行一次,所以Servlet是單實例的
public LoginServlet(){ System.out.println("LoginServlet 構造方法 被調用"); }
- 初始化:LoginServlet 繼承了HttpServlet,同時也繼承了init(ServletConfig) 方法
- init 方法是一個實例方法,所以會在構造方法執行後執行。
- 無論訪問了多少次LoginSerlvet,init初始化 只會執行一次
public void init(ServletConfig config) { System.out.println("init(ServletConfig)"); }
- do service :在service()中就會編寫我們的業務代碼,在本例中就是判斷用戶輸入的賬號和密碼是否正確
- 銷燬 :接着是銷燬destroy(),在如下幾種情況下,會調用destroy()
- 該Servlet所在的web應用重新啓動,在server.xml中配置該web應用的時候用到了
<Context path="/" docBase="e:\\project\\j2ee\\web" debug="0" reloadable="false" />
- 如果把
reloadable="false"
改爲reloadable="true"
就表示有任何類發生的更新,web應用會自動重啓,當web應用自動重啓的時候,destroy()方法就會被調用
- 關閉tomcat的時候 destroy()方法會被調用,但是這個一般都發生的很快,不易被發現。
public void destroy() { System.out.println("destroy()"); }
- 該Servlet所在的web應用重新啓動,在server.xml中配置該web應用的時候用到了
- 回收: 當servlet被銷燬,就滿足垃圾回收條件;當下次GC來的時候,就可能被回收
- 下面我們通過一個實例觀察生命週期:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
public LoginServlet(){
System.out.println("LoginServlet 構造方法 被調用");
}
public void init(ServletConfig config) {
System.out.println("init(ServletConfig)");
}
public void destroy() {
System.out.println("destroy()!");
}
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println("name:" + name);
String html = null;
if ("admin".equals(name) && "123".equals(password))
html = "<div style='color:green'>登錄成功</div>";
else
html = "<div style='color:red'>登錄失敗</div>";
response.setContentType("text/html; charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.println(html);
}
}