过滤器(过滤器、过滤器的API、处理中文乱码、权限控制、敏感词汇过滤)

一、过滤器

过滤器是对客户端访问的资源的限制,符合条件Servlet可以执行。

1、Servlet的实现步骤

(1)实现Filter接口,实现接口对应的方法:

package pers.zhb.fliter;
import javax.servlet.*;
import java.io.IOException;
public class FilterDemo implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
     System.out.println("过滤器运行了");
  }

  @Override
  public void destroy() {

  }
}

(2)配置web.xml文件:

<filter>
    <filter-name>FilterDemo</filter-name>
    <filter-class>pers.zhb.fliter.FilterDemo</filter-class>
</filter>
   <filter-mapping>
       <filter-name>FilterDemo</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>

(3)创建Servlet,并对Servlet进行配置:

public class FilterServlet 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("Servlet运行了");
    }
}
    <servlet>
        <servlet-name>FilterServlet</servlet-name>
        <servlet-class>pers.zhb.servlet.FilterServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FilterServlet</servlet-name>
        <url-pattern>/filter</url-pattern>
    </servlet-mapping>

  通过Servlet的地址对Servlet进行访问后,Servlet并没有执行,被过滤器过滤掉了。

2、过滤器的放行

public class FilterDemo implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    filterChain.doFilter(servletRequest,servletResponse);
    System.out.println("过滤器运行了");
  }

  @Override
  public void destroy() {

  }
}

 添加filterChain.doFilter(servletRequest,servletResponse);方法后Servlet可以正常被访问了。

二、过滤器的API

1、API

a、生命周期(和servletcontext相似):

(1)创建:服务器启动的时候创建(执行init方法)。

(2)销毁:服务器关闭的时候销毁(执行destory方法)。

b、filterConfig.getFilterName():读取配置文件中的名字。

 getInitParameter():读取配置文件中的初始化配置参数。
public class FilterDemo implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String s1=filterConfig.getFilterName();
        String s2=filterConfig.getInitParameter("zhai");
        System.out.println(s1);
        System.out.println(s2);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    }

    @Override
    public void destroy() {

    }

 配置文件:

<filter>
    <filter-name>FilterDemo</filter-name>
    <filter-class>pers.zhb.filter.FilterDemo</filter-class>
    <init-param>
        <param-name>zhai</param-name>
        <param-value>1997</param-value>
    </init-param>
</filter>
    <filter-mapping>
        <filter-name>FilterDemo</filter-name>
        <url-pattern>/filter</url-pattern>
    </filter-mapping>

2、配置文件:

(1)全名匹配:

<filter>
    <filter-name>FilterDemo</filter-name>
    <filter-class>pers.zhb.filter.FilterDemo</filter-class>
</filter>
    <filter-mapping>
        <filter-name>FilterDemo</filter-name>
        <url-pattern>/servlet1</url-pattern>
    </filter-mapping>

即访问的虚拟路径名必须为servlet1,匹配的是全部的名字。

(2)目录匹配:

<filter>
    <filter-name>FilterDemo</filter-name>
    <filter-class>pers.zhb.filter.FilterDemo</filter-class>
</filter>
    <filter-mapping>
        <filter-name>FilterDemo</filter-name>
        <url-pattern>/abc/*</url-pattern>
    </filter-mapping>

即必须为abc目录下的资源。

(3)后缀名匹配:

<filter>
    <filter-name>FilterDemo</filter-name>
    <filter-class>pers.zhb.filter.FilterDemo</filter-class>
</filter>
    <filter-mapping>
        <filter-name>FilterDemo</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>

 3、dispatcher:访问的方式

(1)REQUEST:默认值,代表直接访问某个资源时执行此filter。

         在不对REQUEST参数进行配置的时候:

创建两个Servlet,由servlet1请求转发到servlet2:

Servlet1:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Servlet1运行了");
        request.getRequestDispatcher("servlet2").forward(request,response);
    }

Servlet2:

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

过滤器:

 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("过滤器运行了");
    }

当在配置文件中添加了dispatcher属性后:

    <filter>
        <filter-name>FilterDemo</filter-name>
        <filter-class>pers.zhb.filter.FilterDemo</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FilterDemo</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

只有访问Servlet1的时候有过滤器,因为请求转发的时候,只有第一次的时候是直接访问,请求转发到Servlet2的时候不是直接访问。

当把Servlet1改为重定向到Servlet2的时候,Servlet1和Servlet2触发过滤器:

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Servlet1运行了");
        response.sendRedirect(request.getContextPath()+"/servlet2");
    }

因为重定向是对服务器的重新访问(两次不同的请求),而请求转发发生在服务器内部。

 (2)FORWARD:

 <filter>
        <filter-name>FilterDemo</filter-name>
        <filter-class>pers.zhb.filter.FilterDemo</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FilterDemo</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

只有转发的时候才能触发过滤器:

重定向:

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Servlet1运行了");
        response.sendRedirect(request.getContextPath()+"/servlet2");
    }
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("Servlet2运行了");
    }  

请求转发:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Servlet1运行了");
       request.getRequestDispatcher("/servlet2").forward(request,response);
    }
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Servlet2运行了");
    }

 

 (3)INCLUDE:包含其他资源的时候触发过滤器。

 (4)ERROR:发生错误的时候触发过滤器。

三、过滤器的应用——处理中文乱码

1、提交数据中文乱码:

(1)书写一个表单向servlet提数据:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
  <head>
    <title>user</title>
  </head>
  <body>
    <form action="${pageContext.request.contextPath}/userservlet" method="post">
      <input type="text" name="name">
      <input type="submit" value="提交">
    </form>
  </body>
</html>

(2)servlet接收到表单的数据并响应给客户端:

public class UserServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name=request.getParameter("name");
        response.getWriter().write(name);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);
    }

}
<?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>UserServlet</servlet-name>
        <servlet-class>pers.zhb.web.UserServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/userservlet</url-pattern>
    </servlet-mapping>
</web-app>

(3)测试:

 

 

 

2、添加过滤器处理中文乱码问题

(1)书写过滤器代码:创建一个过滤器类,实现Filter接口:

public class EncodingFilter implements Filter {

    public EncodingFilter() {
        // TODO Auto-generated constructor stub
    }

    public void destroy() {
        // TODO Auto-generated method stub
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        chain.doFilter(request, response);
    }

    public void init(FilterConfig fConfig) throws ServletException {

    }

}

(2)在配置文件中添加过滤器的配置文件:

<?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">

    <filter>
        <filter-name>Encoding</filter-name>
        <filter-class>pers.zhb.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>pers.zhb.web.UserServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/userservlet</url-pattern>
    </servlet-mapping>

</web-app>

(3)测试:

四、权限控制

1、过滤器

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req=(HttpServletRequest)request;
        HttpServletResponse res=(HttpServletResponse)response;
        HttpSession session =req.getSession();
        if(session.getAttribute("user")==null) {
             req.getRequestDispatcher("/login.jsp").forward(req,res);
        }
        chain.doFilter(request, response);
    }

查看session中是否有user数据,没有的话就请求转发到登录页面

2、登录页面

try{
    conn =  C3P0Utils.getConnection();
    String username=request.getParameter("username");
    String password=request.getParameter("password");
    String identity=request.getParameter("identity");
    String selectSql = "select * from login where account=? and password=? and identity=?";
     ps = conn.prepareStatement(selectSql);// 获取预处理对象
     ps.setString(1, username);
     ps.setString(2, password);
     ps.setString(3, identity);
     rs = ps.executeQuery();
     if(rs.next()){
         out.print("登录成功!!");
         request.getSession().setAttribute("user", rs);
     }
    
}

登录成功的话就往session中存储数据,这样的话过滤器就会检测通过,否则会请求转发到此页面,提醒用户登录

五、敏感词汇过滤

(1)书写一个表单,用于收集用户数据:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<h2>过滤器应用示例---敏感词过滤</h2>
     <form action="NoteServlet" method="post">
        用户名:<input type="text" name="name" /><br/><br/>
        <fieldset>
            <legend>留言板</legend>
            <textarea name="note" rows="10" cols="20"></textarea>
        </fieldset>
        <input type="submit" value="留言" />     
     </form>
</body>
</html>

(2)书写一个Servlet,获取到用户名和用户的留言信息,在将页面返回之前是要进行过滤的:

public class NoteServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("不支持GET方式留言");
        out.close();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");

        String name = request.getParameter("name");
        if(name==null || name.trim().length()<=0){
            out.println("名字不能为空!!!");
        }else{
            String words = request.getParameter("note");
            out.println("<br/>"+name+"的留言是:<br/>"+ words);
        }
        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }

}

(3)过滤器配置:

过滤器:

public class WordFilter implements Filter{

    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");

        //在过滤器中用装饰模式把 原装request的功能增强了
        //---拦截后台调用的getParamter()方法
        MyRequest req = new MyRequest((HttpServletRequest)request);

        chain.doFilter(req, response);//放行
    }

    public void destroy() {
    }
}

MyRequest:

public class MyRequest extends HttpServletRequestWrapper {
    public MyRequest(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        String str = super.getParameter(name);
        List<String> list = WordsUtils.getWords();
        for(String word : list){
            str = str.replaceAll(word, "*");
        }
        return str;
    }
}

对敏感词汇进行替换处理

工具类:

public class WordsUtils {
    private static List<String> list = new ArrayList<String>();
    static{
        //这里应该从数据库中导入敏感词的,我在这里就直接用词来模拟了
        list.add("zhanghua");
        list.add("脏话");
    }
    public static List<String> getWords(){
        return list;
    }
    public static void reBuild(){
        //把list中的内容存储到数据库---每一段时间存储一次
    }
}

存储需要过滤的词语

4、其他

配置文件:

<?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">
    <filter>
        <filter-name>WordFilter</filter-name>
        <filter-class>pers.zhb.filter.WordFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>WordFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>NoteServlet</servlet-name>
        <servlet-class>pers.zhb.web.NoteServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>NoteServlet</servlet-name>
        <url-pattern>/NoteServlet</url-pattern>
    </servlet-mapping>
</web-app>

项目结构:

 测试:

 

原文地址:https://www.cnblogs.com/zhai1997/p/11665422.html