java ee 第三週做業

1、session是什麼?有什麼做用?在servlet中怎麼管理session?java

  Http是無狀態的協議,客戶端只須要簡單地向服務器請求,但客戶端或者服務器都沒有紀錄彼此過去的行爲,每一次請求之間都是獨立的。由此在Java Servlet API中引入Session機制來跟蹤客戶的狀態。Session指的是在一段時間內,單個客戶與Web服務器的一連串相關的交互過程。在一個Session中,客戶可能會屢次請求訪問同一個網頁,也有可能請求訪問各類不一樣的服務器資源共享源。
例如在電子郵件應用中,從一個客戶登陸到電子郵件系統開始,通過收信,寫信和發信等一系列操做,直至最後退出郵件系統,整個過程爲一個Session。編程

  對於Session來講,Session是一個容器,能夠存放會話過程當中的任何對象。同時,Session是(request對象)產生的,同一個會話中多個request共享了一Session對象,能夠直接從請求中獲取到Session對象。瀏覽器

  Servlet的會話管理機制:服務器

  HTTP是一種無狀態的協議。它意味着Web應用並不瞭解有關同一用戶之前請求的信息。維持會話狀態信息的方法之一是使用Servlet或者JSP容器提供的會話跟蹤功能。Servlet API規範定義了一個簡單的HttpSession接口,經過它咱們能夠方便地實現會話跟蹤。HttpSession接口提供了存儲和返回標準會話屬性的方法。標準會話屬性如會話標識符、應用數據等,都以「名字-值」對的形式保存。簡而言之,HttpSession接口提供了一種把對象保存到內存、在同一用戶的後繼請求中提取這些對象的標準辦法。在會話中保存數據的方法是setAttribute(String s, Object o),從會話提取原來所保存對象的方法是getAttribute(String s)。每當新用戶請求一個使用了HttpSession對象的JSP頁面,JSP容器除了發回應答頁面以外,它還要向瀏覽器發送一個特殊的數字。這個特殊的數字稱爲「會話標識符」,它是一個惟一的用戶標識符。此後,HttpSession對象就駐留在內存之中,等待同一用戶返回時再次調用它的方法。在客戶端,瀏覽器保存會話標識符,並在每個後繼請求中把這個會話標識符發送給服務器。會話標識符告訴JSP容器當前請求不是用戶發出的第一個請求,服務器之前已經爲該用戶建立了HttpSession對象。此時,JSP容器再也不爲用戶建立新的HttpSession對象,而是尋找具備相同會話標識符的HttpSession對象,而後創建該HttpSession對象和當前請求的關聯。會話標識符以Cookie的形式在服務器和瀏覽器之間傳送。若是客戶端不支持cookie,運用url改寫機制來保證會話標識符傳回服務器。cookie

 

2、分析書上P132的程序清單網絡

一、long before = System.currentTimeMillis();    ..........     long after = System.currentTimeMillis();   這兩個語句的做用?session

此語句的做用是規定了Filter負責攔截全部的用戶請求的過濾範圍。多線程

2. HttpServletRequest hrequest = (HttpServletRequest) request ;  這個語句的含義?app

將請求強制轉換爲HttpServletRequest型再賦給HttpServletRequest 請求對象hrequest異步

3. System.out.println("Filter 已經攔截到用戶的請求的地址: "  + hrequest.getServletPath());   這句話的含義?

經過getServletPath()函數打印Filter 已經攔截到用戶的請求的地址

 

3、寫一個用Filter進行用戶受權的例子即過濾request?

LoginFilter.java 

複製代碼 代碼以下:
public class LoginFilter implements Filter {  

    private String permitUrls[] = null; 

    private String gotoUrl = null; 

    public void destroy() { 

        // TODO Auto-generated method stub 

        permitUrls = null; 

        gotoUrl = null; 

    } 

    public void doFilter(ServletRequest request, ServletResponse response, 

            FilterChain chain) throws IOException, ServletException { 

        // TODO Auto-generated method stub 

        HttpServletRequest res=(HttpServletRequest) request; 

        HttpServletResponse resp=(HttpServletResponse)response; 

        if(!isPermitUrl(request)){ 

            if(filterCurrUrl(request)){ 

                System.out.println("--->請登陸"); 

                resp.sendRedirect(res.getContextPath()+gotoUrl); 

                return; 

            } 

        } 

        System.out.println("--->容許訪問"); 

        chain.doFilter(request, response); 

    } 

    public boolean filterCurrUrl(ServletRequest request){ 

        boolean filter=false; 

        HttpServletRequest res=(HttpServletRequest) request; 

        User user =(User) res.getSession().getAttribute("user"); 

        if(null==user) 

            filter=true; 

        return filter; 
    }       

    public boolean isPermitUrl(ServletRequest request) { 

        boolean isPermit = false; 

        String currentUrl = currentUrl(request); 

        if (permitUrls != null && permitUrls.length > 0) { 

            for (int i = 0; i < permitUrls.length; i++) { 

                if (permitUrls[i].equals(currentUrl)) { 

                    isPermit = true; 

                    break; 

                } 

            } 

        } 

        return isPermit; 

    }        

    //請求地址 

    public String currentUrl(ServletRequest request) {   

        HttpServletRequest res = (HttpServletRequest) request; 

        String task = request.getParameter("task"); 

        String path = res.getContextPath(); 

        String uri = res.getRequestURI(); 

        if (task != null) {// uri格式 xx/ser 

            uri = uri.substring(path.length(), uri.length()) + "?" + "task="

                    + task; 

        } else { 

            uri = uri.substring(path.length(), uri.length()); 

        } 

        System.out.println("當前請求地址:" + uri); 

        return uri; 

    } 

    public void init(FilterConfig filterConfig) throws ServletException { 

        // TODO Auto-generated method stub 

        String permitUrls = filterConfig.getInitParameter("permitUrls"); 

        String gotoUrl = filterConfig.getInitParameter("gotoUrl"); 

  

        this.gotoUrl = gotoUrl; 

  

        if (permitUrls != null && permitUrls.length() > 0) { 

            this.permitUrls = permitUrls.split(","); 

        } 

    } 

}

Web.xml

複製代碼 代碼以下:
<filter>  

    <filter-name>loginFilter</filter-name> 

    <filter-class>filter.LoginFilter</filter-class> 

  

    <init-param> 

        <param-name>ignore</param-name> 

        <param-value>false</param-value> 

    </init-param> 

    <init-param> 

        <param-name>permitUrls</param-name> 

        <param-value>/,/servlet/Loginservlet?task=login,/public.jsp,/login.jsp</param-value> 

    </init-param> 

    <init-param> 

        <param-name>gotoUrl</param-name> 

        <param-value>/login.jsp</param-value> 

    </init-param> 

</filter> 

<filter-mapping> 

    <filter-name>loginFilter</filter-name> 

    <url-pattern>/*</url-pattern> 

</filter-mapping>

 

4、總結JEETT文檔中兩段代碼的差異,並分析啓動代碼後的效果有啥不一樣?

1.首先介紹一下什麼是異步處理、異步任務

異步處理:異步的概念和同步相對。當一個異步過程調用發出後,調用者不能馬上獲得結果。實際處理這個調用的部件在完成後,經過狀態、通知和回調來通知調用者。以CAsycSocket類爲例(注意,CSocket從CAsyncSocket派生,可是其功能已經由異步轉化爲同步),當一個客戶端經過調用 Connect函數發出一個鏈接請求後,調用者線程馬上能夠朝下運行。當鏈接真正創建起來之後,socket底層會發送一個消息通知該對象。這裏提到執行部件和調用者經過三種途徑返回結果:狀態、通知和回調。可使用哪種依賴於執行部件的實現,除非執行部件提供多種選擇,不然不受調用者控制。若是執行部件用狀態來通知,那麼調用者就須要每隔必定時間檢查一次,效率就很低(有些初學多線程編程的人,總喜歡用一個循環去檢查某個變量的值,這實際上是一種很嚴重的錯誤)。若是是使用通知的方式,效率則很高,由於執行部件幾乎不須要作額外的操做。

AsyncTask: 即asynchronous task,異步任務。AsyncTask其實是圍繞Thread和Handler設計的一個輔助類,在內部是對Thread和Handler的一種封裝。AsyncTask的異步體如今由後臺線程進行運算(訪問網絡等比較耗時的操做),而後將結果發佈到用戶界面上來更新UI,使用AsyncTask使得我不用操做Thread和Handler。

2.異步與同步的區別是什麼?

同步與異步的區別:在於請求的內容是否是馬上返回,同步請求須要等待結果返回後才能繼續執行。單線程的執行的時候,須要順序執行,若是碰到一個計算量很大,很耗時的函數須要執行,該線程就必須在這裏等待結果計算出來之後,才能繼續執行。

異步請求理論上不須要等待請求的結果,將耗時的計算交給另一個線程,在結果計算完成後會通知主線程。實際上,異步請求會馬上獲得一個臨時結果,而後異步請求就能夠繼續執行了,當異步線程返回真正結果後再通知主線程,而後主線程在作出動做。

3.根據上面的基礎知識,可大體得出文檔中代碼的區別爲:

(1)request.startAsync()致使請求被異步處理; 在服務方法結束時,響應不會發送到客戶端。

(2)acontext.start(new Runnable() {…​}) 從容器中獲取新線程。

(3)run()內部類的方法的代碼在新線程中執行。內部類能夠訪問異步上下文以從請求讀取參數並寫入響應。調用complete()異步上下文的 方法將提交響應並將其發送給客戶端。

運行效果不一樣之處:

使用異步處理後的例子在大負載的狀況下響應速度變快,服務器吞吐量變大

相關文章
相關標籤/搜索