Filter實現(xiàn)登錄后自動跳轉目標url


馬克-to-win:下面我們將利用Filter技術完成一個稍微實用一點的需求。需求的內容如下:一言以蔽之,我們就想保護internal目錄下的所有資源,(其他地方不保護)。具體有這么幾點:如果用戶非法訪問internal目錄下的資源,就將他導向internal目錄下的login.jsp。如果在login.jsp當中,他輸入了正確的用戶名和密碼,就讓他自動跳轉到他原來想訪問的那個jsp。但如果在一開始,用戶直接就想訪問 login.jsp,即使他輸入了正確的用戶名和密碼,也只把他導向回根目錄的首頁index.jsp。這里需求有兩個難點。一是自動跳轉到他原來想訪問的那個jsp,這需要把他原來想要訪問的目標給存在Session當中。想得到他想訪問的目標,就用 (HttpServletRequest)hsr.getRequestURI()。馬克-to-win:這還不算難。第二個難點就更難。我怎么能知道用戶一開始的目的就是想訪問login.jsp,還是用戶一開始想訪問internal目錄里其他的資源而被導到login.jsp的呢?因為 login.jsp也在internal目錄里,所以到達login.jsp之前,無論如何要經過Filter。問題好像很困難。這里,我是這樣完成這個需求的:當用戶想非法訪問internal目錄下的任何資源前一瞬間(除了login.jsp自己,這一點你要加判斷,desURL.endsWith ("login.jsp"),否則邏輯上會出問題,不信你試試),我在request范圍里加上一個標志:illegal。馬克-to-win:只有這種情況,我才加這個標志。這樣在login.jsp的正常程序前,我再加一個判斷,看是否有這個標志?如果有,就證明用戶想非法訪問internal目錄下的某個資源。如果沒有這個標志,就說明用戶一開始就想訪問login.jsp。
馬克- to-win:馬克 java社區(qū):防盜版實名手機尾號: 73203。



例 1.2.5


index.jsp

<%@ page contentType="text/html; charset=GBK" %>
<html>
<body>
<A HREF="/ServletHello/internal/secret.jsp">secret.jsp</A>
<A HREF="/ServletHello/internal/secret2.jsp">secret2.jsp</A>
<A HREF="/ServletHello/internal/login.jsp">login.jsp</A>
<A HREF="/ServletHello/home.jsp">home.jsp</A>
</body>
</html>



secret.jsp

<%@ page contentType="text/html; charset=GBK" %>
這里秘密地方,來到這,說明你已經登錄了




secret2.jsp

<%@ page contentType="text/html; charset=GBK" %>
這里秘密地方2,來到這,說明你已經登錄了



home.jsp

<%@ page contentType="text/html; charset=GBK" %>
<br>這是在home.jsp<br>


login.jsp


<%@ page contentType="text/html; charset=GBK" %><html>
<body>
<center><h3>登錄:馬克-to-win</h3></center>
<%=request.getRequestURI() %>
<%System.out.println(request.getRequestURI()); %>
<%
String reqRetu=(String)request.getAttribute("illegal");
if(reqRetu==null)
{
   System.out.println("直接來的,未經過filter的setAttribute處理");
/*只要直接訪問login.jsp,就不再記錄過去想去哪兒了。*/  
   session.removeAttribute("destinURL");
} else {
   System.out.println("你要去 "+session.getAttribute("destinURL"));
}
%>       
<form action="../MarkToWinServlet" method="post">
姓名<INPUT TYPE="TEXT" NAME="name">
密碼<INPUT TYPE="TEXT" NAME="pass">
<input type="submit" name="Submit" value="提交">
</form>
</body>
</html>





package com;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;

public class MarkToWinFilter implements Filter {
    public void destroy() {
    }
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hsr = (HttpServletRequest) request;
        HttpServletResponse hsres = (HttpServletResponse) response;
        HttpSession hs = hsr.getSession();
        String desURL = hsr.getRequestURI();
        System.out.println("in filter 你要去" + desURL);
        /* 下面這句話正確,即使null,也能強轉 */
        String isLogin = (String) hs.getAttribute("isLogin");
        System.out.println(" isLogin in Filter is " + isLogin);
        if (isLogin != null || desURL.endsWith("login.jsp")) {
            System.out.println("Filter 放行");
            chain.doFilter(request, response);
        } else {
            hs.setAttribute("destinURL", hsr.getRequestURI());
            hsr.setAttribute("illegal", "true");
            hsr.getRequestDispatcher("/internal/login.jsp").forward(hsr, hsres);
        }
    }
    public void init(FilterConfig fConfig) throws ServletException {
    }
}



package com;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;

public class ServletHello1 extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("GBK");
        HttpSession hs = request.getSession();
        String name = request.getParameter("name");
        String pass = request.getParameter("pass");
        String desUR;
        String contextpath = request.getContextPath();
        String machineName = request.getScheme() + "://"
                + request.getServerName() + ":" + request.getServerPort();
        String webApplicationPath = machineName + contextpath + "/";
        System.out.println("come in" + webApplicationPath);
        if (name.equals("馬克-to-win") && pass.equals("123")) {
            System.out.println("come in if");
            hs.setAttribute("isLogin", "true");
            desUR = (String) hs.getAttribute("destinURL");
            if (desUR == null) {/*有人上來就訪問login.jsp*/
                response.sendRedirect(webApplicationPath + "index.jsp");
            } else {/*有人上來就訪問secret.jsp*/
                hs.removeAttribute("destinURL");/*成功到了目的地后,目的地值就不保存了*/
                System.out.println("machineName+desUR in ServletHello1 is "
                        + machineName + desUR);
                response.sendRedirect(machineName + desUR);
            }
        } else {
            response.sendRedirect(webApplicationPath + "internal/login.jsp");
        }
    }
}





在web.xml當中,加入以下的片段:

    <filter>
        <filter-name>MarkToWinFilter</filter-name>
        <filter-class>com.MarkToWinFilter</filter-class>
    </filter>
  <filter-mapping>
      <filter-name>MarkToWinFilter</filter-name>
      <url-pattern>/internal/*</url-pattern>
  </filter-mapping>



注意和上個例子一樣,本個例子我們還是得在火狐下運行,因為它涉及到Filter當中有Session。項目的啟動一定是運行index.jsp,之后大家可以模仿各種情況測試本個項目,比如先點擊運行l(wèi)ogin.jsp或先點擊運行secret.jsp。