Servlet三種配置方式
方式一: 精確配置
必須以精確的路徑,最後加上/SOS才能訪問
如:http://localhost:8080/ServletProject/SOS
<url-pattern>/SOS</url-pattern>
方式二: 模糊配置
只要是以.do爲結尾就可以訪問
如:http://localhost:8080/ServletProject/a.do
如:http://localhost:8080/ServletProject/b.do
都可以,後綴也不是非要.do, ,.p .o .k 都可以
<url-pattern>*.do</url-pattern>
方式三: 攔截所有請求
不管輸入什麼都可以訪問本Servlet
如:http://localhost:8080/ServletProject (後面什麼都沒有)
如:http://localhost:8080/ServletProject/alvin is great (或者後面亂寫)
<url-pattern>/*</url-pattern>
一個Servlet可以配置多個url-pattern
不同的Servlet不允許配置相同的url-pattern,如果配置了在服務器啓動的時候會報錯
服務器啓動的時候會將部署的項目中的web.xml文件加載內存
服務器中Servlet創建是單例的
服務器在接收到瀏覽器請求後,會開闢一個線程來處理此次請求,在線程中調用對應的Servlet進行處理。
服務器調用Servlet處理請求,但是一個Servlet服務器只會創建一個實例化對象,該對象是線程共享的。
Servlet的生命週期
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("servlet被執行了");
}
//init會一開始就被調用,但前後只會被調用一次,後續只會運行service
@Override
public void init() throws ServletException {
System.out.println("我被初始化");
}
//服務器被關閉之後執行的方法,類似C++的析構函數
@Override
public void destroy() {
System.out.println("我被銷燬了");
}
Servlet生命週期:
結論:
從第一次被調用到服務器關閉
驗證:
init方法: servlet被初始化創建的時候調用
service方法: 處理請求的時候
destory方法: servlet被銷燬的時候,當服務器關閉的時候銷燬servlet,觸發destory方法執行
配置servlet服務器啓動完成加載和初始化創建
<load-on-startup>1</load-on-startup>
我們可以在web.xml中配置 load-on-startup 來設置servlet的加載時機爲服務器啓動。
生命週期就變爲從服務器開啓到服務器關閉
doget,dopost 和 service 之間的區別
創建登陸頁面
<html>
<head>
<title>登陸頁面</title>
</head>
<body>
<form action="http://localhost:8080/ServletProject/SOS" method="get">
登錄:<input type="text" id="username" name="username"/><br/>
密碼:<input type="password" id="pwd" name="pwd"/><br/>
<input type="submit" value="登錄"/>
</form>
</body>
</html>
當method = get時, 由 doget處理
當method = post時,由 dopost處理
如果method 的 請求方式 和 doget或dopost不符將會報405錯誤
servlet沒有生命service時,會根據要求選擇,如果service 和 doget 或 dopost同時存在時, 優先處理service
Servlet常見異常總結
404錯誤: 資源未找到
原因一: 在請求地址中的servlet的別名書寫錯誤。
原因二: 虛擬項目名稱拼寫錯誤
500錯誤: 內部服務器錯誤
錯誤一:
ClassNotFoundException
解決:
在web.xml中效驗servlet類全限路徑是否拼寫錯誤。
錯誤二:
因爲service方法體的代碼執行錯誤導致
解決:
根據錯誤提示對service方法體中的代碼進行錯誤更改。
405錯誤:請求方式不支持
原因:
請求方式和servlet中的方法不匹配所造成的。
解決:
儘量使用service方法進行請求處理,並且不要再service方法中調用父類的service。
HTTPServletRequest的介紹和特點
request對象
服務器在接收到請求後,會給此次請求創建一個request對象,此對象中封存了此次請求相關的數據
作用: 存儲請求數據
注意:每次請求都會創建新的request對象存儲請求數據
特點:
request對象由服務器創建
一次請求創建一個request對象
生命週期爲一次請求內,請求結束即銷燬此次request對象
request獲取請求行數據和根據鍵名獲取請求頭數據
//獲取請求信息
//獲取請求行信息
//獲取請求方式
String method = req.getMethod();
System.out.println("請求方式:"+method);
//獲取請求URL信息
StringBuffer requestURL = req.getRequestURL();
System.out.println("請求URL:"+requestURL.toString());
//獲取請求URI信息
String requestURI = req.getRequestURI();
System.out.println("請求URI:"+requestURI);
//獲取get請求URL中的請求數據
String queryString = req.getQueryString();
System.out.println("獲取get請求URL中的數據:"+queryString);
//獲取協議
String scheme = req.getScheme();
System.out.println("獲取請求協議:"+scheme);
//獲取請求頭信息
//根據鍵名獲取請求頭信息
String header = req.getHeader("User-Agent2");
System.out.println("獲取瀏覽器版本信息:"+header);
//獲取請求頭中鍵名的枚舉
Enumeration headerNames = req.getHeaderNames();
while(headerNames.hasMoreElements()){
//獲取請求頭鍵名
String name=(String) headerNames.nextElement();
//獲取請求頭的鍵名對應的值
String value=req.getHeader(name);
System.out.println(name+":"+value);
}
//獲取請求實體數據(用戶數據)
//根據鍵名獲取數據
String uname = req.getParameter("uname2");
String pwd=req.getParameter("pwd");
System.out.println("請求實體數據:"+uname+":"+pwd);
//獲取同名不同值的實體數據
String[] favs = req.getParameterValues("fav");
if(favs!=null){
for(String s:favs){
System.out.println("fav的值爲:"+s);
}
}
//獲取請求實體中鍵名的枚舉
Enumeration names = req.getParameterNames();
while(names.hasMoreElements()){
//獲取鍵名
String name=(String) names.nextElement();
//判斷
if("fav".equals(name)){
String[] favs2=req.getParameterValues(name);
if(favs!=null){
for(String s:favs2){
System.out.println(name+":"+s);
}
}
}else{
//獲取值
String value=req.getParameter(name);
System.out.println(name+":"+value);
}
}
//請求相關的網絡數據
//獲取客戶端信息
String remoteAddr = req.getRemoteAddr();
System.out.println("獲取客戶端的IP:"+remoteAddr);
//獲取客戶端的端口號(瀏覽器)
int remotePort = req.getRemotePort();
System.out.println("獲取客戶端的端口號:"+remotePort);
//獲取服務器主機ip
String localAddr = req.getLocalAddr();
System.out.println("獲取服務器ip:"+localAddr);
//獲取服務器的端口號
int localPort=req.getLocalPort();
System.out.println("獲取服務器端口號:"+localPort);
//處理請求信息
//響應處理結果
}
request對象學習之獲取請求數據
請求數據:
請求行:請求方式 請求URL 協議
getMethod(); 返回請求方式
getRequestUrl(); 返回請求url
getRequestUri(); 返回請求uri
getQueryString(); 返回get請求中的URL中的用戶數據 注意: post請求中沒有此方法。
getSchema(); 返回協議
請求頭
getHeader(String name) 根據鍵名獲取請求頭信息
注意: 如果獲取的請求頭信息不存在返回null
getHeaderNames() 返回存儲了請求頭鍵名枚舉集合
請求實體
getParameter(String name) 根據鍵名獲取數據
注意:
鍵名其實就是前端頁面中的表單標籤的name屬性的值或者前端頁面其他提交數據的鍵的名字
如果請求中沒有對應的請求數據,則返回Null
getParameterValues(String name) 根據鍵名獲取同名不同的值,返回數組
注意: 如果沒有對應的鍵名,則返回null
getParameterNames() 返回實體數據中鍵名的枚舉
請求網絡相關數據
getRemoteAddr() 獲取客戶端的IP地址
getRemotePort() 獲取客戶端端口號
getLocalAddr() 獲取服務器端ip
getLocalPort() 獲取服務器端的端口號
設置響應行和設置響應頭
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//獲取請求數據
//處理請求數據
//響應處理結果
//設置響應行
//自定義響應404異常
//resp.sendError(404);
//設置響應頭
//添加響應頭信息
resp.addHeader("mouse","thinkpad");
resp.addHeader("mouse","thinkpad2");
//設置響應頭
//resp.setHeader("mouse", "two fly birds");
//resp.setHeader("mouse", "two fly birds2");
//設置響應實體
resp.getWriter().write("resp object");
resp.getWriter().write("resp object");
resp.getWriter().write("resp object");
resp.getWriter().write("resp object");
}
response對象之處理響應學習:
設置響應行: 協議 狀態碼 狀態消息
response.sendError(int status);
作用: 可以自主的響應狀態給瀏覽器
設置響應頭
addHeader(String name,String value) 添加響應頭信息,同名數據不會覆蓋 setHeader(String nanme,String value) 設置響應頭信息,會覆蓋原有信息。如果沒有此響應頭則添加該信息。
設置響應實體(處理結果)
resp.getWriter().write(“實體內容”);
注意:
實體內容可以分開進行響應。
注意:
一旦使用resp對象作出了請求響應,則意味着此次請求處理完畢。服務器在響應後會將此次請求相關的req對象和resp對象銷燬。
亂碼解決問題
post請求方式亂碼:
req.setCharacterEncoding(“utf-8”);
get請求方式亂碼解決:
方式一:每個數據都要單獨的進行轉換
String uname=req.getParameter(“uname”);
String uname2=new String(uname.getBytes(“iso-8859-1”), “utf-8”);
方式二:
req.setCharacterEncoding(“utf-8”);
在tomcat的server.xml文件中的Connector標籤中增加屬性: useBodyEncodingForURI=“true”
響應亂碼問題:瀏覽器中顯示的服務器響應數據亂碼
resp.setContentType(“text/html;charset=utf-8”);
Servlet代碼編寫流程
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//設置請求編碼格式
req.setCharacterEncoding("utf-8");
//設置響應編碼格式
//resp.setHeader("content-type", "text/html;charset=utf-8");
resp.setContentType("text/html;charset=utf-8");
//獲取請求數據
String uname=req.getParameter("uname");
//String uname2=new String(uname.getBytes("iso-8859-1"), "utf-8");
//處理請求數據
System.out.println(uname);
//響應處理結果
resp.getWriter().write("請求處理完畢.");
}
請求轉發介紹
登陸模擬
<html>
<head>
<meta charset="UTF-8">
<script src="js/jquery-3.4.1.min.js"></script>
</head>
<body>
<script type="text/javascript" charset="UTF-8">
alert("hello");
</script>
<form action="http://localhost:8080/ServletProject/SOS" method="get">
<p>請輸入管理員賬號密碼!</p><br/>
登錄:<input type="text" id="username" name="username"/><br/>
密碼:<input type="password" id="pwd" name="pwd"/><br/>
<input type="submit" value="登錄"/>
</form>
</body>
</html>
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//設置請求編碼格式
request.setCharacterEncoding("utf-8");
//設置響應編碼格式
response.setContentType("text/html;charset=utf-8");
//獲取請求信息
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
//接收數據庫信息
Student stu = SqlService.Login(username,pwd);
//處理請求信息
if(stu != null && stu.getClassname().equals("管理員")){
response.getWriter().write("登陸成功!歡迎您: " + stu.getRealname());
}else{
response.getWriter().write("您不是管理員!");
}
}
重定向的作用和特點
1.用戶如何實現跳轉(客戶端控制的跳轉方式)
方式1:點擊超鏈接
方式2:提交表單
最終地址的變化都會體現在地址欄中
兩種方式都是向服務器端發起的一個新的請求
2.程序如何實現跳轉(服務器端控制的跳轉方式)
方式1: 轉發
方式2: 重定向
方式3: 包含include(可以忽略)
3.轉發和重定向的共同點
服務器端控制的跳轉方式,都實現了跳轉
4.轉發和重定向的不同點
1)語句不同
轉發: request.getRequestDispatcher("/login/login.jsp").forward(request, response);
重定向:response.sendRedirect("/myservlet2/login/success.jsp");
2)跳轉後地址欄的路徑不同
轉發:跳轉之前的地址
重定向:跳轉之後的地址 /login/success.jsp
3)是否可以獲取保存在request中的數據
轉發:可以獲取
重定向:無法獲取
4)原理不同!!!
5)效率不同
轉發效率高
重定向效率低
6)跳轉的範圍不同
轉發:僅限當前項目跳轉(最大也就是當前服務器)
重定向:可以跳轉到互聯網的任意位置
跳轉的路徑不同
絕對路徑
轉發:不支持(只能在當前項目跳轉 http://www.alvin.com)
重定向:支持
根路徑/
轉發:不需要寫上下文路徑 /login/login.jsp(只能在當前項目跳轉)
重定向:需要些上下文路徑 /myservlet/login/success.jsp
/代表當前服務器
相對路徑
只有相對路徑1(當前文件自身) 沒有相對路徑2(基準路徑)
路徑的選擇
1.重定向到其他服務器,只能使用絕對路徑
2.跳轉到當前服務器的其他項目或者當前項目,建議使用根路徑
3.不建議使用相對路徑
8)根路徑的/含義不同
轉發: /代表當前項目
重定向: /代表當前服務器
9)刷新是否導致表單重複提交
重定向:不會
轉發:會
10)是否經過過濾器
轉發: 不經過
重定向: 經過
到底是使用轉發還是重定向?
某些情況下,無可選擇
希望前後兩個組件共享request數據,使用轉發
跳轉到同一個應用的WEB-INF目錄下只能用轉發
跳轉到不同的應用只能使用重定向
使用Cookie存儲數據需要使用重定向
跳轉到同一應用,哪種方式更好?
使用轉發效率高,儘量使用轉發
使用轉發需要解決重複提交問題,尤其是添加操作
註銷之後一般用重定向
連續表單頁面之間建議使用重定向,避免屬性衝突
Cookie的介紹和特點和作用
特點:
瀏覽器端的數據存儲技術
哪些數據需要被存儲在服務器端
行聲明:
以響應的方式告訴瀏覽器進行存儲,不適合大量數據的存儲
作用:
解決了不同請求之間請求數據共享的問題
創建Cookie數據
Cookie cookie = new Cookie("b",b);
Cookie構造方法源碼
public Cookie(String name, String value) {
validation.validate(name);
this.name = name;
this.value = value;
}
設置Cookie信息
//設置三天有效期
cookie.setMaxAge(3600 * 24 * 3);
Session
A
//設置請求編碼格式
request.setCharacterEncoding("utf-8");
//設置響應 編碼格式
response.setContentType("text/html;charset=utf-8");
//獲取請求信息
String uname=request.getParameter("username");
//處理請求數據
System.out.println("ServletA.service():"+uname);
//創建Session對象
HttpSession session = request.getSession();
//存儲數據到session對象中
session.setAttribute("uname", uname);
System.out.println("ServletA.service():"+session.getId());
//響應處理結果
B
//設置請求編碼格式
request.setCharacterEncoding("utf-8");
//設置響應 編碼格式
response.setContentType("text/html;charset=utf-8");
//獲取請求信息
//獲取Session對象
HttpSession session = request.getSession();
//獲取A的處理結果數據
String uname=(String) session.getAttribute("username");
//處理請求數據
//打印A流轉的數據
System.out.println("ServletB.service():"+uname);
問題:
用戶不同的請求在處理的時候需要使用其他請求中的數據該怎麼辦
解決:
session技術
使用:
創建session對象
HttpSession session = request.getSession();
存儲數據到session中
session.setAttribute(String name,Object value);
獲取session對象
HttpSession session = request.getSession();
獲取session中的數據
session,getAttribute(String uname); //注意,返回的object類型,需要強制轉換
刪除session中的數據
session.removeAttribute(String name); 注意,如果有數據則刪除,沒有則什麼都不做。
流程:
瀏覽器發起請求到Servlet1,在Servlet1中使用request.getSession()獲取Session對象,如果此次請求中沒有 SessionID則創建一個新的Session對象,如果有SessionID則將其對應的Session對象返回(前提是該session對 象沒有到對象到期銷燬了,就算有sessionID也會重新創建一個Session)
效驗session是否失效,存儲數據到session對象中或者獲取session中的數據或者刪除session中的數據特點: session解決了同一個用戶不同請求的數據共享問題。
特點:
session解決了同一個用戶不同請求的數據共享問題。
優化登錄案例
login
//設置請求編碼格式
req.setCharacterEncoding("utf-8");
//設置響應編碼格式
resp.setContentType("text/html;charset=utf-8");
//獲取Session中的數據
HttpSession session = req.getSession();
String str=(session.getAttribute("flag")==null?"":"用戶名或密碼錯誤");
//銷燬session
session.invalidate();
//獲取請求信息
//處理請求信息
//響應處理結果
//直接響應
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<form action='user' method='get'>");
resp.getWriter().write("<font color='red'>"+str+"</font>");
resp.getWriter().write(" 用戶名:<input type='text' name='uname' value=''/><br />");
resp.getWriter().write(" 密碼:<input type='password' name='pwd' value=''/><br />");
resp.getWriter().write("<input type='submit' value='登錄'/><br />");
resp.getWriter().write("</form>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
user
//設置請求編碼格式
req.setCharacterEncoding("utf-8");
//設置響應編碼格式
resp.setContentType("text/html;charset=utf-8");
//獲取請求信息
String uname=req.getParameter("uname");
String pwd=req.getParameter("pwd");
//處理請求信息
//校驗用戶信息
if("張三".equals(uname) && "123".equals(pwd)){
//登錄成功
//響應處理結果
}else{
//登錄失敗
//創建Session並增加登錄失敗標記
HttpSession session = req.getSession();
session.setAttribute("flag","loginFalse");
//響應處理結果(重定向到登錄頁面)
resp.sendRedirect("login");
}
ServletContext對象介紹和獲取
問題:
Request解決了一次請求內的數據共享問題,session解決了用戶不同請求的數據共享問題,那麼不同的用戶的數據共享該怎麼辦呢?
解決:
使用ServletContext對象
作用:
解決了不同用戶的數據共享問題
原理:
ServletContext對象由服務器進行創建,一個項目只有一個對象。不管在項目的任意位置進行獲取得到的都是同一對象,那麼不同用戶發起的請求獲取到的也就是同一對象了,該對象由用戶共同擁有。
特點:
服務器進行創建
用戶共享
一個項目只有一個
生命週期:
服務器啓動到服務器關閉
作用域:
項目內
使用:
獲取ServletContext對象
使用作用域進行共享數據流轉
獲取web.xml中的全局配置
獲取webroot下項目資源流對象
獲取webroot下資源絕對路徑
ServletContext對象的獲取
//設置請求編碼格式
req.setCharacterEncoding("utf-8");
//設置響應編碼格式
resp.setContentType("text/html;charset=utf-8");
//獲取請求信息
//處理請求信息
String str = "我是用戶共享數據";
//獲取ServletContext對象
ServletContext servletContext = this.getServletContext();
ServletContext servletContex2 = this.getServletConfig().getServletContext();
ServletContext servletContex3 = req.getSession().getServletContext();
System.out.println(servletContext == servletContex2); //true
System.out.println(servletContext == servletContex3); //true
ServletContext對象存儲和獲取共享數據
servletA
//設置請求編碼格式
req.setCharacterEncoding("utf-8");
//設置響應編碼格式
resp.setContentType("text/html;charset=utf-8");
//獲取請求信息
//處理請求信息
String str = "我是用戶共享數據";
//獲取ServletContext對象
ServletContext servletContext = this.getServletContext();
ServletContext servletContex2 = this.getServletConfig().getServletContext();
ServletContext servletContex3 = req.getSession().getServletContext();
System.out.println(servletContext == servletContex2); //true
System.out.println(servletContext == servletContex3); //true
//存儲共享用戶到ServletContext中
servletContext.setAttribute("str",str);
//直接響應
resp.getWriter().write("數據已經在ServletContext存儲完畢!");
servletB
//設置請求編碼格式
req.setCharacterEncoding("utf-8");
//設置響應編碼格式
resp.setContentType("text/html;charset=utf-8");
//獲取請求信息
//獲取ServletContext對象
ServletContext sc = this.getServletContext();
//獲取共享數據
String s=(String) sc.getAttribute("str");
//處理請求信息
System.out.println("TestServletContextB.service()"+s);
獲取web配置文件全局屬性
//設置請求編碼格式
req.setCharacterEncoding("utf-8");
//設置響應編碼格式
resp.setContentType("text/html;charset=utf-8");
//獲取請求信息
//處理請求信息
String str="我是用戶共享數據";
//獲取ServletContext對象
ServletContext sc1 = this.getServletContext();
ServletContext sc2 =this.getServletConfig().getServletContext();
ServletContext sc3=req.getSession().getServletContext();
System.out.println(sc1==sc2);
System.out.println(sc2==sc3);
//存儲用戶共享數據到ServletContext中
sc1.setAttribute("str", str);
//獲取web.xml中的全局配置屬性
String f=sc1.getInitParameter("flag");
if("false".equals(f)){
System.out.println("TestServlectContextA.service(關閉***資源)");
}else{
System.out.println("TestServlectContextA.service(打開***資源)");
}
//獲取webRoot下資源的流對象
//File f2=new File("D:\\apache-tomcat-7.0.56\\webapps\\sc\\image");
InputStream resourceAsStream = sc1.getResourceAsStream("image/s.png");
//獲取WebRoot下資源的絕對路徑
String path=sc1.getRealPath("image/s.png");
System.out.println(path);
//響應處理結果
//直接響應
resp.getWriter().write("數據已經在ServletContext中存儲完畢");
web配置
<?xml version="1.0" encoding="UTF-8"?>
-<web-app version="2.5" id="WebApp_ID" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- 配置全局配置屬性 -->
-<context-param>
<param-name>flag</param-name>
<param-value>true</param-value>
</context-param>
<display-name>ServletContext</display-name>
-<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>TestServlectContextA</servlet-name>
<servlet-class>com.alvin.servlet.TestServlectContextA</servlet-class>
</servlet>
-<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>TestServletContextB</servlet-name>
<servlet-class>com.alvin.servlet.TestServletContextB</servlet-class>
</servlet>
-<servlet-mapping>
<servlet-name>TestServlectContextA</servlet-name>
<url-pattern>/sa</url-pattern>
</servlet-mapping>
-<servlet-mapping>
<servlet-name>TestServletContextB</servlet-name>
<url-pattern>/sb</url-pattern>
</servlet-mapping>
-<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
ServletContext對象實現網頁訪問計數次數
UserServlet
//設置請求編碼格式
req.setCharacterEncoding("utf-8");
//設置響應編碼格式
resp.setContentType("text/html;charset=utf-8");
//獲取請求信息
String uname=req.getParameter("uname");
String pwd=req.getParameter("pwd");
//處理請求信息
//校驗用戶信息
if("張三".equals(uname) && "123".equals(pwd)){
//登錄成功
//獲取ServletContext對象
ServletContext sc=this.getServletContext();
//獲取計數器
Object obj=sc.getAttribute("nums");
//判斷
if(obj!=null){
//計數器數據自增
int nums=(int) obj;
nums=nums+1;
//存儲計數器數據到ServletContext對象
sc.setAttribute("nums", nums);
}else{
sc.setAttribute("nums",1);
}
//創建Session對象
HttpSession hs=req.getSession();
//存儲數據
hs.setAttribute("uname",uname);
//響應處理結果(重定向到登錄成功的Servlet)
resp.sendRedirect("main");
}else{
//登錄失敗
//創建Session並增加登錄失敗標記
HttpSession session = req.getSession();
session.setAttribute("flag","loginFalse");
//響應處理結果(重定向到登錄頁面)
resp.sendRedirect("login");
}
}
LoginServlet
//設置請求編碼格式
req.setCharacterEncoding("utf-8");
//設置響應編碼格式
resp.setContentType("text/html;charset=utf-8");
//獲取Session中的數據
HttpSession session = req.getSession();
String str=(session.getAttribute("flag")==null?"":"用戶名或密碼錯誤");
//銷燬session
session.invalidate();
//獲取請求信息
//處理請求信息
//響應處理結果
//直接響應
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<form action='user' method='get'>");
resp.getWriter().write("<font color='red'>"+str+"</font>");
resp.getWriter().write(" 用戶名:<input type='text' name='uname' value=''/><br />");
resp.getWriter().write(" 密碼:<input type='password' name='pwd' value=''/><br />");
resp.getWriter().write("<input type='submit' value='登錄'/><br />");
resp.getWriter().write("</form>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}