13、过滤器的常见应用
过滤器小Demo:
整体思路:
-
前端:
- 一个表单获取到username,传到Servlet(通过form的action定位到已经注册的servlet的url)
- 一个success界面,提供注销按钮(注销之后直接跳转index界面)
- 一个error界面,提供返回登录按钮(点击跳转index界面)
-
Servlet:
- LoginServlet:获取到username进行判断,然后进行重定向index
- LogoutServlet:实现removeAttribute(),然后重定向index
-
Filter:
将ServletRequest强转成HTTPServletRequest,获取到Session判断是否为空,进行重定向index
自己理解一遍之后完全重写花了将近2小时,呜呜呜呜!
理一遍思路:
-
创建login.jsp页面,前端获取到username传到/servlet/login
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>登录</h1> <form action="/servlet/login" method="post"> <input type="text" name="username"> <input type="submit"> </form> </body> </html>
-
创建LoginServlet,处理获取的username,判断转发success.jsp或者error页面!
public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); //判断登录,并重定向到对应jsp页面 if (username.equals("tom")){ //这里是我整个Demo的一个大问题,深刻理解了Session中保存键值对, //创建了一个Constant类静态定义一个键USER_SESSION,用来存放Session的ID req.getSession().setAttribute(Constant.USER_SESSION,req.getSession().getId()); resp.sendRedirect("/sys/success.jsp"); }else { resp.sendRedirect("/error.jsp"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
实现页面跳转之后分成两部分
- success部分
- 显示成功
- 一个注销的超链接,传到/servlet/logout,然后创建LogoutServlet来注销Session
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>Success!</h1> <p><a href="/servlet/logout">注销</a></p> </body> </html>
public class LogoutServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //通过静态的键获取存的值(Session的ID) if (req.getSession().getAttribute(Constant.USER_SESSION)!=null){ req.getSession().removeAttribute(Constant.USER_SESSION); resp.sendRedirect("/login.jsp"); }else{ resp.sendRedirect("/login.jsp"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
error部分
- 就是单纯的重新登录:超链接到login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>Error!</h1> <p><a href="login.jsp">返回重新登录</a></p> </body> </html>
注意:a标签,既可以用“/sevlet/logout”的形式,请求到注册的Servlet,通过Servlet里面实现跳转,也可以直接”login.jsp“直接跳转到jsp页面
- success部分
-
添加过滤器
到这里就已经实现登录注销重新登录的操作了,但是还有一个BUG,就是我在地址栏输入success.jsp还是能够直接访问,可是我明明点击过注销了,理论上应该是会调用到注销Session的方法的,(自己在remove后面打印了ID,显示为NULL那么session肯定已经被注销了)但就是能访问,希望大佬能帮我分析分析原因。
不过这不是重点,瞄准大方向,在success界面添加一个过滤器,用来过滤没有session之后访问success界面自动跳转到error界面
public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)servletRequest; HttpServletResponse resp = (HttpServletResponse)servletResponse; if (req.getSession().getAttribute(Constant.USER_SESSION)==null){ resp.sendRedirect("/error.jsp"); } //自己测试的时候,这句话没有加,确实容易犯错 filterChain.doFilter(servletRequest, servletResponse); } public void destroy() { }
到此整个Demo结束,说实话整个Demo看狂神做的时候一步一步挺简单的,但是自己实际动手从0开始写,确实有难度的,自己通过这种先整体看一遍在自己实现一遍的方法确实收获很多,但是有点费时间,除了BUG自己不太能直接筛查出来,还是基础不够牢固,继续加油!