01.Servlet學習筆記

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>");
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章