JavaWeb过滤器的应用
一:粗粒度权限控制(拦截是否登录、拦截用户名admin权限)
思路:过滤器能够在Web组件被调用之前检查ServletRequest对象,修改请求头或者请求的正文;过滤器能够在被Web组件调用之后检查ServletResponse对象,修改响应头或者响应的内容,所以判断是否进入那个页面 就应该写在Filter
UserFilter
1 public class UserFilter implements Filter { 2 public void destroy() {} 3 public void doFilter(ServletRequest request, ServletResponse response, 4 FilterChain chain) throws IOException, ServletException { 5 /* 6 * 1. 得到session 7 * 2. 判断session域中是否存在admin,如果存在,放行 8 * 3. 判断session域中是否存在username,如果存在,放行,否则打回到login.jsp,并告诉它不要瞎留达 9 */ 10 HttpServletRequest req = (HttpServletRequest) request; 11 String name = (String)req.getSession().getAttribute("admin"); 12 if(name != null) { 13 chain.doFilter(request, response); 14 return; 15 } 16 17 name = (String)req.getSession().getAttribute("username"); 18 if(name != null) { 19 chain.doFilter(request, response); 20 } else { 21 req.setAttribute("msg", "您啥都不是,不要瞎溜达!"); 22 req.getRequestDispatcher("/login.jsp").forward(request, response); 23 } 24 } 25 public void init(FilterConfig fConfig) throws ServletException { } 26 }
AdminFilter.java
1 public class AdminFilter implements Filter { 2 public void destroy() {} 3 public void doFilter(ServletRequest request, ServletResponse response, 4 FilterChain chain) throws IOException, ServletException { 5 /* 6 * 1. 得到session 7 * 2. 判断session域中是否存在admin,如果存在,放行 8 * 3. 判断session域中是否存在username,如果存在,放行,否则打回到login.jsp,并告诉它不要瞎留达 9 */ 10 HttpServletRequest req = (HttpServletRequest) request; 11 String name = (String)req.getSession().getAttribute("admin"); 12 if(name != null) { 13 chain.doFilter(request, response); 14 } else { 15 req.setAttribute("msg", "您可能是个啥,但肯定不是管理员!"); 16 req.getRequestDispatcher("/login.jsp").forward(request, response); 17 } 18 } 19 20 }
LoginServlet
1 public class LoginServlet extends HttpServlet { 2 public void doPost(HttpServletRequest request, HttpServletResponse response) 3 throws ServletException, IOException { 4 request.setCharacterEncoding("utf-8"); 5 response.setContentType("text/html;charset=utf-8"); 6 7 /* 8 * 1. 获取用户名 9 * 2. 判断用户名中是否包含itcast 10 * 3. 如果包含,就是管理员 11 * 4. 如果不包含,就是普通会员 12 * 5. 要把登录的用户名称保存到session中 13 * 6. 转发到index.jsp 14 */ 15 String username = request.getParameter("username"); 16 if(username.contains("itcast")) { 17 request.getSession().setAttribute("admin", username); 18 } else { 19 request.getSession().setAttribute("username", username); 20 } 21 request.getRequestDispatcher("/index.jsp").forward(request, response); 22 } 23 }
二: 分ip统计网站的访问次数
统计工作需要在所有资源之前都执行,那么就可以放到Filter中了。
我们这个过滤器不打算做拦截操作!因为我们只是用来做统计的。
用什么东西来装载统计的数据。Map<String,Integer>
整个网站只需要一个Map即可!
Map什么时候创建(使用ServletContextListener,在服务器启动时完成创建,并只在到ServletContext中),Map保存到哪里!(Map保存到ServletContext中!!!)
-
Map需要在Filter中用来保存数据
-
Map需要在页面使用,打印Map中的数据
AListener.java
1 public class AListener implements ServletContextListener { 2 /** 3 * 在服务器启动时创建Map,保存到ServletContext 4 */ 5 public void contextInitialized(ServletContextEvent sce) { 6 // 创建Map 7 Map<String,Integer> map = new LinkedHashMap<String,Integer>(); 8 // 得到ServletContext 9 ServletContext application = sce.getServletContext(); 10 // 把map保存到application中 11 application.setAttribute("map", map); 12 } 13 14 15 public void contextDestroyed(ServletContextEvent sce) { 16 } 17 }
AFilter.java
1 public class AFilter implements Filter { 2 private FilterConfig config; 3 public void destroy() { 4 } 5 public void doFilter(ServletRequest request, ServletResponse response, 6 FilterChain chain) throws IOException, ServletException { 7 /* 8 * 1. 得到application中的map 9 * 2. 从request中获取当前客户端的ip地址 10 * 3. 查看map中是否存在这个ip对应访问次数,如果存在,把次数+1再保存回去 11 * 4. 如果不存在这个ip,那么说明是第一次访问本站,设置访问次数为1 12 */ 13 /* 14 * 1. 得到appliction 15 */ 16 ServletContext app = config.getServletContext(); 17 Map<String,Integer> map = (Map<String, Integer>) app.getAttribute("map"); 18 /* 19 * 2. 获取客户端的ip地址 20 */ 21 String ip = request.getRemoteAddr(); 22 /* 23 * 3. 进行判断 24 */ 25 if(map.containsKey(ip)) {//这个ip在map中存在,说明不是第一次访问 26 int cnt = map.get(ip); 27 map.put(ip, cnt+1); 28 } else {//这个ip在map中不存在,说明是第一次访问 29 map.put(ip, 1); 30 } 31 app.setAttribute("map", map);//把map再放回到app中 32 33 chain.doFilter(request, response);//肯定放行 34 } 35 36 37 /** 38 * 在服务器启动时就会执行本方法,而且本方法只执行一次! 39 */ 40 public void init(FilterConfig fConfig) throws ServletException { 41 this.config = fConfig; 42 } 43 }
show.jsp
1 <table align="center" border="1" width="50%"> 2 <tr><td>ip</td><td>次数</td></tr> 3 <c:forEach items="${applicationScope.map}" var="entry"> 4 <tr> 5 <td>${entry.key }</td> 6 <td>${entry.value }</td> 7 </tr> 8 </c:forEach> 9 </table>
三:解决全站字符乱码(POST和GET中文编码问题)
RequestFilter
1 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 2 request.setCharacterEncoding("utf-8"); 3 4 HttpServletRequest req = (HttpServletRequest)request; 5 if(req.getMethod().equals("GET")){ 6 EncodingRequest er = new EncodingRequest(req); 7 chain.doFilter(er, response); 8 }else if(req.getMethod().equals("POST")){ 9 chain.doFilter(request, response); 10 } 11 12 }
EncodingServlet
1 public void doPost(HttpServletRequest request, HttpServletResponse response) 2 throws ServletException, IOException { 3 response.setContentType("text/html;charset=utf-8"); 4 String username= request.getParameter("username"); 5 response.getWriter().print(username); 6 } 7
EncodingRequest
1 public class EncodingRequest extends HttpServletRequestWrapper{ 2 private HttpServletRequest req; 3 public EncodingRequest(HttpServletRequest request) { 4 super(request); 5 // TODO Auto-generated constructor stub 6 this.req=request; 7 } 8 public String getParameter(String name){ 9 String value = req.getParameter(name); 10 try { 11 value =new String(value.getBytes("iso-8859-1"),"utf-8"); 12 13 } catch (UnsupportedEncodingException e) { 14 // TODO Auto-generated catch block 15 e.printStackTrace(); 16 } 17 return value; 18 } 19 }
效果图: