Filter实现登录后自动跳转目标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社区:防盗版实名手机尾号: 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,之后大家可以模仿各种情况测试本个项目,比如先点击运行login.jsp或先点击运行secret.jsp。