【左京淳的JAVA WEB学习笔记】第五章 过滤器与监听器

过滤器可以用来做权限校验或是编码转换等功能。
多个过滤器可以串联在一起,做多重过滤。
自定义的过滤器需实现javax.servlet.Filter介面。

编码转换案例:

设定过滤範围及encoding方式
@WebFilter(urlPatterns = "/*",  initParams = {@WebInitParam(name = "encoding",value = "utf-8")})public class CharacterEncodingFilter implements Filter {…}urlPatterns = "/*" //过滤目标为此网站下所有网页initParams = {@WebInitParam(name = "encoding",value = "utf-8")} //将encoding方式设为utf-8(或其他编码)
在init方法中读取参数
  public void init(FilterConfig fConfig) throws ServletException {    this.encoding = fConfig.getInitParameter("encoding");  }
在doFilter中过滤请求
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {    if(encoding != null) {      request.setCharacterEncoding(encoding);    }    HttpServletRequest r = (HttpServletRequest)request;    if(r.getMethod().equalsIgnoreCase("get")) { //只针对GET请求进行过滤,POST方法通常不会乱码。      Enumeration<?>names = request.getParameterNames();      while(names.hasMoreElements()) {        String[] values = request.getParameterValues(names.nextElement().toString());        for(int i = 0;i < values.length; ++i) {          values[i] = new String(values[i].getBytes("ISO-8859-1"),encoding);        }      }    }    chain.doFilter(request, response); //过滤器处理完后丢给下一个过滤器或引导至资源网页。  }

权限校验案例:

用户登入成功后,将用户保存至session中。
将之前写的LoginSvl稍作修正,原本把用户名保存在request,这次保存到session里面
@WebServlet("/LoginSvl")public class LoginSvl extends HttpServlet {  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    String uname = request.getParameter("uname");    request.getSession().setAttribute("uname", uname);    String pwd = request.getParameter("pwd");    //request.setAttribute("uname", uname);    request.getRequestDispatcher("/main/hello.jsp").forward(request, response);  }}
定义用户权限过滤器
@WebFilter(filterName = "/UserFilter", urlPatterns = "/user/*")public class UserFilter implements Filter {  (前略…)  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {    HttpServletRequest req = (HttpServletRequest)request;    Object object = req.getSession().getAttribute("uname");    if(object != null) { //这边因为是範例,所以没有从资料库拿使用者名单,只是简单的从session里确认是否有uname被储存了。      chain.doFilter(request, response);    }else {      request.setAttribute("msg", "请先登录");      req.getRequestDispatcher("/main/login.jsp").forward(request, response);    }  }}
製作jsp页面
新增user/UserInfo.jsp页面,随意添加一行内容。
Hi,${uname}

跑看看过滤器是否起作用吧。

监听器的种类繁多,用来监听各种不同对象。不像Filter一样只有一种。例如:

ServletContextListener

当伺服器启动时会创建ServletContext物件,此时利用监听器即可加载一些初始化资讯。

@WebListenerpublic class MyContextListener implements ServletContextListener {}    public void contextDestroyed(ServletContextEvent sce)  {         }    public void contextInitialized(ServletContextEvent sce)  {          System.out.println("Tomcat启动,ServletContext被创建");    }

HttpSessionListener

一个Session代表一个在线上的用户,因此可以用监听器追蹤或管理用户状态。
注:统计用户对象时,如果用户主动登出,Web应用程式会自动创建另一个会话对象,因此线上人数不会变更。只有用户超时未操作时,线上人数才会减少。

聊天室管理

利用监听器也可以踢掉不当发言的使用者,流程如下:

在自订的HttpSessionListener里新增一个Map来管理所有session在LoginSvl里面也新增一个Map,把所有登入后的使用者放进去。如果有想踢掉的使用者,先从LoginSvl的Map找出使用者的sessionid,然后用此id找到在监听器map里相对应的session,使其失效即可。
@WebListenerpublic class OnlineUserListerner implements HttpSessionListener {  public static Map<String,HttpSession> allUser;  static {    allUser = new ConcurrentHashMap<>();  }      public void sessionCreated(HttpSessionEvent se)  {          HttpSession session = se.getSession();         allUser.put(session.getId(), session);    }    public void sessionDestroyed(HttpSessionEvent se)  {         HttpSession session = se.getSession();        allUser.remove(session.getId(), session);    }}
@WebServlet("/LoginSvl")public class LoginSvl extends HttpServlet {  private Map<String,String> loginedUsers = new ConcurrentHashMap<>();  (中略…)  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    String uname = request.getParameter("uname");    String pwd = request.getParameter("pwd");    LoginBiz biz = new LoginBiz();    User user = biz.login(uname,pwd);    request.getSession().setAttribute("user", uname);    loginedUsers.put(uname, request.getSession().getId());    request.getRequestDispatcher("/main/main.jsp").forward(request, response);  }}

踢除某用户的方法

String sessionid = loginedUsers.get(uname);HttpSession session = OnlineUserListerner.allUser.get(sessionid);session.invalidate();

ServletRequestListener

监听每一次用户访问纪录,可用于统计网站被访问次数,例如:

@WebListenerpublic class PageViewListener implements ServletRequestListener {  AtomicInteger pv;    public PageViewListener() {        System.out.println("PageViewListener被建立");        pv = new AtomicInteger(0);    }    public void requestDestroyed(ServletRequestEvent sre)  {     }    public void requestInitialized(ServletRequestEvent sre)  {       System.out.println(pv.incrementAndGet());    }

此监听器在Tomcat启动时被建立
使用AtomicInteger pv当作计数器。
每次收到客户端的request就会触发一次requestInitialized()。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章