过滤器

过滤器如何编写?

1.写一个类实现Filter接口
2.在web.xml中进行配置

Filter接口:

 public void init(FilterConfig filterConfig)
 	创建之后,马上执行;Filter会在服务器启动时就创建!
 public void destroy():
 	销毁之前执行!在服务器关闭时销毁
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
  	每次过滤时都会执行

Filter是单例的

web.xml配置

<filter>
<filter-name>xxx</fi1ter-name>T
<filter-class>cn.itcast.web.filter.AFitler</fitler-class>
</servlet>
<fitler-mapping>
<filter-name>xxx</filter-name>
只要碰到AServlet就拦截
<url-pattern>/Aservlet</url-pattern>
</filter-mapping>

举例:
web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>AServlet</servlet-name>
        <servlet-class>cn.itcast.web.servlet.AServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>AServlet</servlet-name>
        <url-pattern>/AServlet</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>AServlet</filter-name>
        <filter-class>cn.itcast.web.filter.AFilite</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AServlet</filter-name>
        <url-pattern>/AServlet</url-pattern>
    </filter-mapping>
</web-app>

AServlet:

public class AServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("AServlet......");
    }
}

AFilter:

public class AFilite implements Filter {
    /**
     *
     * @param filterConfig
     * @throws ServletException
     *
     * 创建之后马上执行,用来做初始化
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化");
    }

    /**
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     *
     * 每次过滤时都会执行
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截你");
    }

    /**
     * 销毁之前,用来做对非内存资源进行释放
     */
    @Override
    public void destroy() {
        System.out.println("过滤器销毁");
    }
}

这个过滤器屏蔽了AServlet路径访问

多个过滤器

AServlet:

public class AServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("AServlet......");
    }
}

AFilter:

public class AFilite implements Filter {
    /**
     *
     * @param filterConfig
     * @throws ServletException
     *
     * 创建之后马上执行,用来做初始化
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("AFilite过滤器初始化");
    }

    /**
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     *
     * 每次过滤时都会执行
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("AFilter拦截你");
        filterChain.doFilter(servletRequest,servletResponse);//放行,不再拦截
        System.out.println("AFilite回来了");
    }

    /**
     * 销毁之前,用来做对非内存资源进行释放
     */
    @Override
    public void destroy() {
        System.out.println("过滤器销毁");
    }
}

BFilter:

public class BFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("BFilter拦截你");
        chain.doFilter(req,resp);//放行
        System.out.println("BFilter回来了");
    }

    public void init(FilterConfig config) throws ServletException {
        System.out.println("BFilter过滤器初始化");
    }

}

web.xml:

    <servlet>
        <servlet-name>AServlet</servlet-name>
        <servlet-class>cn.itcast.web.servlet.AServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>AServlet</servlet-name>
        <url-pattern>/AServlet</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>AServlet</filter-name>
        <filter-class>cn.itcast.web.filter.AFilite</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AServlet</filter-name>
        <url-pattern>/AServlet</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>BServlet</filter-name>
        <filter-class>cn.itcast.web.filter.BFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>BServlet</filter-name>
        <url-pattern>/AServlet</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

结果:

AFilter拦截你
BFilter拦截你
AServlet......
BFilter回来了
AFilite回来了

区别

FilterConfig与ServletConfig相似:

*获取初始化参数:getInitParameter():
*获得过滤器名称:getFilterName():
*获取application:getServletContext():

FilterChain

*doFilter(ServletRequest,ServletResponse):放行!
就相当于调用了目标servlet的service()方法!
用来放行拦截器

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截你");
        filterChain.doFilter(servletRequest,servletResponse);//放行,不再拦截
        System.out.println("回来了");
    }

结果:

拦截你
AServlet......
回来了

四种拦截方式

请求	DISPATCHER
转发	FORWARD
包含	INCLUDE
错误	ERROR

<filter-mapping>中进行配置

 <dispatcher>REQUEST</dispatcher>默认的
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>

FilterConfig接口

MyFilter03:

public class MyFilter03 implements Filter {
    private String characterEncoding;
    FilterConfig fc;
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //输出参数信息
        characterEncoding=fc.getInitParameter("encoding");
        System.out.println("encoding初始化参数的值为:"+characterEncoding);
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        //获取FilterConfig对象
        this.fc=config;
    }

}

web.xml:

 <filter>
        <filter-name>MyFilter03</filter-name>
        <filter-class>cn.itcast.web.filter.MyFilter03</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>GBK</param-value>
        </init-param>
    </filter>
   <filter-mapping>
       <filter-name>MyFilter03</filter-name>
       <url-pattern>/AServlet</url-pattern>
   </filter-mapping>

结果:

AFilter拦截你
BFilter拦截你
encoding初始化参数的值为:GBK
AServlet......
BFilter回来了  
AFilite回来了

过滤器的优点

• 过滤器是可插拔的。
• 一个过滤器不依赖于另一个资源。
• 维护少,比较容易维护。
• 能够过滤访问web资源的所有的请求,包括图片,样式等。(每个请求都触发一次过滤事件)

过滤器的编写原则:

a 尽量不要过滤全部 * (降低所有请求的访问效率,且容易出错)
b 在过滤器中,优先使用转发,谨慎使用重定向,因为重定向有可能再次进入过滤器,导致死循环。

过滤器的优点

要创建一个过滤器,必须要实现Filter接口。
Filter接口为过滤器提供了生命周期方法。
在这里插入图片描述

FilterChain接口

在这里插入图片描述

注解配置过滤器

注解配置时,顺序按过滤器类的类名,按字符串的排序规则。

过滤器的过滤顺序

  • 如果是用web.xml配置的话,和url-pattern有关,谁在前面谁就先过滤
  • 如果使用注解配置的话,只和过滤器的类名有关,顺序按过滤器类的类名,按字符串的排序规则。
  • 如果既有web.xml和注解配置的话,web.xml配置的先过滤

案例

a 统一中文编码处理

@WebFilter("/*")
public class CFilter implements Filter {

    /**
     * Default constructor. 
     */
    public CFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		chain.doFilter(request, response);

	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

注册名检查过滤器

@WebFilter("/RegServlet")
public class RegFilter implements Filter {

    /**
     * Default constructor. 
     */
    public RegFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	private static List<String> badNames=new ArrayList<>();
	static {
		badNames.add("他妈的");
		badNames.add("fuck");
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//1 获取请求参数
		String username=((HttpServletRequest)request).getParameter("username");
		if(badNames.contains(username)) {
			response.getWriter().println(username+"非法,注册失败");
			response.getWriter().flush();
			response.getWriter().close();
			return;
		}
		chain.doFilter(request, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

ip过滤器

@WebFilter("/*")
public class IPFilter implements Filter {

    /**
     * Default constructor. 
     */
    public IPFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//获取请求方ip
		String ip=request.getRemoteAddr();
		if(ip.startsWith("192.168")) {
			response.getWriter().println("禁止192.168开头的IP访问本站");
			response.getWriter().flush();
			response.getWriter().close();
			return;
		}
		chain.doFilter(request, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

内页访问登录校验过滤器

LoginCheckFilter:


/**
 * Servlet Filter implementation class LoginCheckFilter
 */
@WebFilter("/*")
public class LoginCheckFilter implements Filter {

    /**
     * Default constructor. 
     */
    public LoginCheckFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//让两个uri白名单放行。//login.jsp,LoginServlet
		HttpServletRequest req=(HttpServletRequest) request;
		if(req.getRequestURI().indexOf("login.jsp")>=0
				||req.getRequestURI().indexOf("LoginServlet")>=0
				||!req.getSession().isNew()) {
			chain.doFilter(request, response);
			return;
		}
		request.setAttribute("msg", "请先登录");
		//在过滤器中转发,不会再进入过滤器
		request.getRequestDispatcher("login.jsp").forward(request, response);
		
//		req.getSession().setAttribute("msg", "请先登录");
//		((HttpServletResponse)response).sendRedirect("login.jsp");
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

login.jsp:

	
	<c:if test="${not empty msg }">
		${msg}<br/>
		
	</c:if>
	<!-- 让session失效 -->
	<%session.invalidate(); %>
	 
	<!-- <img  src="img/1.png" width="100px" height="200px"> -->
	
	<form action="LoginServlet" method="post">
		<input name="username" placeholder="username" /> <br/>
			<input name="password" type="password" placeholder="password" /> <br /> 
			<input type="submit" value="登录" />
	</form>

篡改响应报文

CharResponseWrapper.java:

import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

//工具类,对请求、响应流的封装,可以获取响应的报文
class CharResponseWrapper
extends HttpServletResponseWrapper
{
	protected CharArrayWriter charWriter;//将响应缓存在这个写入器中
	protected PrintWriter writer;
	protected boolean getOutputStreamCalled;
	protected boolean getWriterCalled;
	public CharResponseWrapper(HttpServletResponse response)
	{
	super(response);
	// Create the writer
	charWriter = new CharArrayWriter();
	}
	public ServletOutputStream getOutputStream()
	throws IOException
	{
	// Can't call getOutputStream if getWriter
	// has already been called
	if (getWriterCalled)
	{
	    throw new IllegalStateException(
	            "getWriter already called");
	}
	getOutputStreamCalled = true;
	return super.getOutputStream();
	}
	public PrintWriter getWriter()
	throws IOException
	{
	if (writer != null)
	{
	    return writer;
	}
	// Can't call getWriter if getOutputStream
	// has already been called
	if (getOutputStreamCalled)
	{
	    throw new IllegalStateException(
	            "getOutputStream already called");
	}
		getWriterCalled = true;
		writer = new PrintWriter(charWriter);
		return writer;
	}
	
	public String toString()//将响应数据用字符串返回
	{
	String s = null;
	// Only return a String if the writer was
	// used.
	if (writer != null)
	{
	    s = charWriter.toString();
	}
	return s;
}
}

GetMsgServlet.java:

@WebServlet("/GetMsgServlet")
public class GetMsgServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public GetMsgServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().println("今天晚上警察巡逻,保护大家安全");
		response.getWriter().flush();
		response.getWriter().close();
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

BadResponseFilter.java:

@WebFilter("/GetMsgServlet")
public class BadResponseFilter implements Filter {

    /**
     * Default constructor. 
     */
    public BadResponseFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//使用新的响应流对象,代替原来的response的对象
		CharResponseWrapper crw=new CharResponseWrapper((HttpServletResponse)response);
		
		chain.doFilter(request, crw);
		String newHtml=crw.toString().replace("警察", "jc");
		response.getWriter().println(newHtml);
		response.getWriter().flush();
		response.getWriter().close();
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java后端指南

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值