zoukankan      html  css  js  c++  java
  • 第七部分_深度剖析Filter

    使用Servlet过滤器

    • 了解Servlet过滤器的概念:Servlet过滤器本身并不生成请求和响应对象,他只提供过滤作用,能够对Servlet容器的请求和响应对象进行检查和修改。能够在Servlet被调用之前检查Request对象,修改Request Header和Request内容;能够在Servlet被调用之后检查Response对象,修改Response Header和Response内容。Servlet过滤器负责过滤的Web组件可以使Servlet、JSP或者HTML文件。
    • 了解Servlet过滤器的工作过程
    • 掌握创建Servlet过滤器的方法:所有的Serlvet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法:init()、doFilter()、destroy()
    • 掌握发布Servlet过滤器的方法

    过滤器的例子:下面创建一个NoteFilter过滤器,它可以拒绝列在黑名单上的客户访问留言簿

     首先是过滤器类NoteFilter:

    package com.test.filter;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    public class NoteFilter implements Filter
    {
    	private FilterConfig config = null;
    
    	private String blackList = null;
    
    	public void init(FilterConfig config) throws ServletException
    	{
    		this.config = config; // 保存为成员变量是为了在这个类的其他方法中使用,如doFilter方法
    		blackList = config.getInitParameter("blacklist");
    	}
    
    	public void destroy()
    	{
    		config = null;
    	}
    
    	public void doFilter(ServletRequest request, ServletResponse response,
    			FilterChain chain) throws IOException, ServletException
    	{
    
    		String username = ((HttpServletRequest) request)
    				.getParameter("username");
    		if (username != null)
    			username = new String(username.getBytes("ISO-8859-1"), "GB2312"); // 编码转换
    		if (username != null && username.indexOf(blackList) != -1)
    		{
    			response.setContentType("text/html;charset=GB2312");
    			PrintWriter out = response.getWriter();
    			out.println("<html><head></head><body>");
    			out.println("<h1>对不起," + username + ",你没有权限留言 </h1>");
    			out.println("</body></html>");
    			out.flush();
    			return; // 直接返回
    		}
    
    		long before = System.currentTimeMillis();
    		config.getServletContext().log(
    				"NoteFilter:before call chain.doFilter()");
    		
    		chain.doFilter(request, response);
    		
    		
    		config.getServletContext()
    				.log("NoteFilter:after call chain.doFilter()");
    		long after = System.currentTimeMillis();
    		String name = "";
    		if (request instanceof HttpServletRequest)
    		{
    			name = ((HttpServletRequest) request).getRequestURI();
    		}
    		config.getServletContext().log(
    				"NoteFilter:" + name + ": " + (after - before) + "ms");
    	}
    }
    
    /*
    	当NoteFilter初始化时,它调用config.getInitParameter("blacklist")方法,从web.xml文件中读取初始化参数blacklist,这个参数表示被禁止访问留言簿的客户黑名单。
    	如果客户不在黑名单中,NoteFilter的doFilter方法就会调用chain.doFilter()方法,这个方法用于调用过滤器链中后续过滤器的doFilter()方法。假如没用后续过滤器,那么就把客户请求传给相应的Web组件。
    	在本例中,在调用chain.doFilter()方法前后记录了调用的时间,从而计算出Web组件响应客户所花的时间。
    */
    

    接下来是NoteServlet:

    package com.test.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class NoteServlet extends HttpServlet
    {
    	private static final String CONTENT_TYPE = "text/html; charset=GB2312";
    
    	public void service(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException
    	{
    		response.setContentType(CONTENT_TYPE);
    		PrintWriter out = response.getWriter();
    		out.println("<html>");
    		out.println("<head><title>留言薄</title></head>");
    		out.println("<body>");
    
    		String username = request.getParameter("username");
    		String content = request.getParameter("content");
    		if (username != null)
    			username = new String(username.getBytes("ISO-8859-1"), "GB2312");
    		if (content != null)
    			content = new String(content.getBytes("ISO-8859-1"), "GB2312");
    
    		if (content != null && !content.equals(""))
    			out.println("<p>" + username + "的留言为:" + content + "</P>");
    
    		out.println(" <FORM  action=" + request.getContextPath()
    				+ "/NoteServlet method=POST>");
    
    		out.println("<b>姓名:</b>");
    		out.println("<input type=text size=10 name=username ><br>");
    		out.println("<b>留言:</b><br>");
    		out
    				.println("<textarea name=content rows=5 cols=20  wrap></textarea><br>");
    		out.println("<BR>");
    		out.println("<input type=submit  value=提交>");
    		out.println("</form>");
    		out.println("</body></html>");
    	}
    
    	public void destroy()
    	{
    	}
    }
    

    最后再web.xml中进行相关的配置(注意:在web.xml文件中,必须先配置Servlet过滤器,再配置Servlet):

    <filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.test.filter.NoteFilter</filter-class>
    <init-param>
    <param-name>blacklist</param-name>
    <param-value>hello</param-value>
    </init-param>
    </filter>
    
    <filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/NoteServlet</url-pattern> <!-- 准备过滤的地址模式 --> 
    </filter-mapping>

    输入姓名为hello或者hello123等等:

    小练习

    练习题1:在Servlet过滤器中能否访问application范围内的共享数据?

    答案:可以的,先调用FilterConfig的getServletContext()方法获得ServletContext,再调用ServletContext的getAttribute()方法来获得application范围内的共享数据。

    练习题2:Servlet过滤器只能对Servlet进行过滤,这句话是否正确?

    答案:不正确。Servlet过滤器可以对Servlet、JSP和HTML文件过滤。

    如:

    <filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/NoteServlet</url-pattern> <!-- 准备过滤的地址模式 --> 
    </filter-mapping>
    

    更改为:

    <filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern> <!-- 准备过滤的地址模式 --> 
    </filter-mapping>
    

    表示过滤整个web应用下所有的内容。

    最后,我们举一个例子说明过滤器在实际开发中的作用:

    假设用户访问我们的web应用,首先需要登录,然后在登录之后用户可以通过地址栏的方式访问这个web应用下的其他页面,如果未登录用户通过地址栏访问这个页面需要跳转到登录页面,这样的话我们在每个页面中都需要写一个判断用户登录状态的逻辑,使得整个开发繁琐,此时,过滤器就派上了用场,我们只需要在过滤器中写一次判断,然后过滤应用下的所有页面即可。

  • 相关阅读:
    adb pull / push
    June 25,2014---->Binder(IPC),Dalvik ,DEX/ODEX
    adb 读写模式 挂载文件系统
    INSTALL_FAILED_UID_CHANGED
    Logcat不显示Application的解决办法
    Android终端管理器删除文件夹
    ADB
    StringBuffer
    扑克牌排序
    windows内存管理方式以及优缺点
  • 原文地址:https://www.cnblogs.com/Code-Rush/p/4638965.html
Copyright © 2011-2022 走看看