Filter案例——请求编码、登录检查、敏感字过滤器

目录

  • 案例1:请求编码过滤器
  • 案例2:登录检查过滤器
  • 案例3:敏感字过滤器

请求编码过滤器

跳转到目录
Filter案例——请求编码、登录检查、敏感字过滤器_第1张图片

  • login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录title>
head>
<body>
    <form action="/filter_listener/loginServlet" method="post">
        账号:<input type="text" name="username"><br>
        密码:<input type="text" name="password"><br>
        <input type="submit" value=" 登录 ">
    form>
body>
html>
  • LoginServlet.java
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 无论什么Servlet往浏览器中输入字符时都要设置编码.
        // 将这两行代码设置到过滤器中
        // request.setCharacterEncoding("utf-8");
        // response.setContentType("text/html;charset=utf-8");
        // ================================================

        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username + "," + password);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
  • CharacterEncodingFilter.java
@WebFilter(value = "/*", initParams = {
        @WebInitParam(name = "encoding", value = "UTF-8")
})
public class CharacterEncodingFilter implements Filter {

    private String encoding;

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        // 设置编码
        //1. 应用中没有编码并且自己设置了编码
        if (hasLength(encoding) && req.getCharacterEncoding() == null) {
            req.setCharacterEncoding(encoding);
        }
        chain.doFilter(req, resp); // 放行
    }

    public void init(FilterConfig config) throws ServletException {
        this.encoding = config.getInitParameter("encoding");
    }

    private boolean hasLength(String str) {
        return str != null && !"".equals(str.trim());
    }

    public void destroy() {
    }
}

登录检查过滤器

跳转到目录
Filter案例——请求编码、登录检查、敏感字过滤器_第2张图片

  • jsp
    在welcome.jsp, function1.jsp, function2.jsp, function3.jsp有重复代码.可以使用过滤器来设置.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录title>
head>
<body>
    <form action="/filter_listener/loginServlet2" method="post">
        账号:<input type="text" name="username" required><br>
        密码:<input type="text" name="password"><br>
        <input type="submit" value=" 登录 ">
    form>
body>
html>


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
${sessionScope.USER_IN_SESSION}

<%--<%--%>
<%--    Object user = session.getAttribute("USER_IN_SESSION");--%>
<%--    // 如果user没有登录--%>
<%--    if (user == null){--%>
<%--        response.sendRedirect(request.getContextPath()+"/checkLogin/login.jsp");--%>
<%--    }--%>
<%--%>--%>

<hr>
<a href="${pageContext.request.contextPath}/checkLogin/function1.jsp">功能1a>
<a href="${pageContext.request.contextPath}/checkLogin/function2.jsp">功能2a>
<a href="${pageContext.request.contextPath}/checkLogin/function3.jsp">功能3a>


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
${sessionScope.USER_IN_SESSION}

<%--<%--%>
<%--    Object user = session.getAttribute("USER_IN_SESSION");--%>
<%--    // 如果user没有登录--%>
<%--    if (user == null){--%>
<%--        response.sendRedirect(request.getContextPath()+"/checkLogin/login.jsp");--%>
<%--    }--%>
<%--%>--%>

这是功能1


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
${sessionScope.USER_IN_SESSION}

<%--<%--%>
<%--    Object user = session.getAttribute("USER_IN_SESSION");--%>
<%--    // 如果user没有登录--%>
<%--    if (user == null){--%>
<%--        response.sendRedirect(request.getContextPath()+"/checkLogin/login.jsp");--%>
<%--    }--%>
<%--%>--%>

这是功能2


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
${sessionScope.USER_IN_SESSION}

<%--<%--%>
<%--    Object user = session.getAttribute("USER_IN_SESSION");--%>
<%--    // 如果user没有登录--%>
<%--    if (user == null){--%>
<%--        response.sendRedirect(request.getContextPath()+"/checkLogin/login.jsp");--%>
<%--    }--%>
<%--%>--%>

这是功能3
  • LoginServlet.java
@WebServlet("/loginServlet2")
public class LoginServlet2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        // 把登录信息存储到session中
        request.getSession().setAttribute("USER_IN_SESSION", username);
        response.sendRedirect(request.getContextPath()+"/checkLogin/welcome.jsp");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
  • CheckLoginFilter
@WebFilter("/*")
public class CheckLoginFilter implements Filter {

    // 不需要检查的资源
    private String[] unCheckUris = {"/filter_listener/checkLogin/login.jsp",
            "/filter_listener/checkLogin/login",
            "/filter_listener/loginServlet2"};

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        // ================================================================================

        // 会产生请求死循环.因为/*,过滤器可以拦截任何请求
        /*
        if (user == null) {// 没有登录
            Object user = request.getSession().getAttribute("USER_IN_SESSION");
            response.sendRedirect(request.getContextPath() + "/checkLogin/login.jsp");
            return;
        }
         */

        // 当前正在过滤的资源
        String requestURI = request.getRequestURI();
        // System.out.println(requestURI);

        //if (!"/filter_listener/checkLogin/login.jsp".equals(requestURI) && !"/filter_listener/checkLogin/login".equals(requestURI)) {
        // 优化写法
        if (!Arrays.asList(unCheckUris).contains(requestURI)) {
            Object user = request.getSession().getAttribute("USER_IN_SESSION");
            //System.out.println(user);
            if (user == null) { // 没有登录
                response.sendRedirect(request.getContextPath() + "/checkLogin/login.jsp");
                return;
            }
        }
        //==========================================================================================

        chain.doFilter(request, response);
    }

    public void init(FilterConfig config) throws ServletException {
    }

    public void destroy() {
    }
}

敏感字过滤器

跳转到目录

案例2_敏感词汇过滤
* 需求:
1. 对day17_case案例录入的数据进行敏感词汇过滤
2. 敏感词汇参考《敏感词汇.txt》
3. 如果是敏感词汇,替换为 ***

* 分析:
	1. 对request对象进行增强。增强获取参数相关方法
	2. 放行。传递代理对象


* 增强对象的功能:
	* 设计模式:一些通用的解决固定问题的方式
	1. 装饰模式
	2. 代理模式
		* 概念:<卖电脑>
			1. 真实对象:被代理的对象(联想公司)  	真实对象被代理对象所代理
			2. 代理对象:卖联想电脑代理商
			3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
	 	* 实现方式:
		 	1. 静态代理:有一个类文件描述代理模式(会有一个代理类文件)
		 	2. 动态代理:在内存中形成代理类(在内存中有代理类)
				* 实现步骤:
					1. 代理对象和真实对象实现相同的接口
					2. 代理对象 = Proxy.newProxyInstance(); // 创建代理对象
					3. 使用代理对象调用方法。
					4. 增强方法

				* 增强方式:
					1. 增强参数列表
					2. 增强返回值类型
					3. 增强方法体执行逻辑

卖联想电脑- 代理设计模式

  • Lenovo.java
/**
 * 真实类
 */
public class Lenovo implements SaleComputer {
    @Override
    public String sale(double money) {
        System.out.println("卖了一台"+money+"元的联想电脑");
        return "联想电脑";
    }

    @Override
    public void show() {
        System.out.println("展示电脑");
    }
}
  • SaleComputer.java
public interface SaleComputer {

    public String sale(double money);

    public void show();
}
  • ProxyTest.java
public class ProxyTest {
   public static void main(String[] args) {
       //1. 创建真实对象
       Lenovo lenovo = new Lenovo();

       //2. 动态代理增强lenovo对象

        /*
           三个参数:
               1. 类加载器:真实对象.getClass().getClassLoader()
               2. 接口数组:真实对象.getClass().getInterfaces()
               3. 处理器:new InvocationHandler()
        */
       SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(),
               lenovo.getClass().getInterfaces(),
               new InvocationHandler() {

                   /**
                    * 代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行.
                    * 参数:
                    *   1. proxy:代理对象
                    *   2. method:代理对象调用的方法,被封装为的对象
                    *   3. args:代理对象调用的方法时,传递的实际参数
                    */
                   @Override
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                   /*System.out.println("该方法执行了....");
                   System.out.println(method.getName());
                   System.out.println(args[0]);*/
                       //判断是否是sale方法
                       if (method.getName().equals("sale")) {
                           //1.增强参数
                           double money = (double) args[0];
                           money = money * 0.85;
                           //2. 增强方法体
                           System.out.println("专车接你....");
                           //使用真实对象调用该方法
                           String obj = (String) method.invoke(lenovo, money);
                           System.out.println("免费送货...");
                           //3.增强返回值
                           return obj + "_鼠标垫";
                       } else {
                           Object obj = method.invoke(lenovo, args);
                           return obj;
                       }
                   }
               });

       //2. 调用出售电脑的方法
       String computer = proxy_lenovo.sale(8000);
       System.out.println(computer);

       // proxy_lenovo.show();
   }
}

敏感字过滤实现:

  • TestSensitiveWordsServlet.java
@WebServlet("/testSensitiveWordsServlet")
public class TestSensitiveWordsServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String msg = request.getParameter("msg");
        System.out.println(username + "," + msg);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
  • SensitiveWordsFilter.java
/**
 * 敏感词汇过滤器
 */
@WebFilter("/*")
public class SensitiveWordsFilter implements Filter {

    // 存储敏感词汇的集合
    private List<String> list = new ArrayList<>();

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //1. 创建代理对象,增强getParameter方法
        ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 增强getParameter方法
                // 判断是否是getParameter方法
                if (method.getName().equals("getParameter")) {
                    // 增强返回值
                    // 获取返回值
                    String value = (String) method.invoke(req, args);
                    if (value != null) {
                        for (String str : list) {
                            if (value.contains(str)){
                                value = value.replaceAll(str, "***");
                            }
                        }
                    }
                    return value;
                }
                return method.invoke(req, args);
            }
        });
        //2. 放行
        chain.doFilter(proxy_req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        try {
            //1. 获取文件真实路径
            ServletContext servletContext = config.getServletContext();
            String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");

            //2. 读取文件
            BufferedReader br = new BufferedReader(new FileReader(realPath));

            //3. 将文件的每一行数据添加到list集合中
            String line = null;
            while ((line = br.readLine()) != null){
                list.add(line);
            }

            br.close();

            System.out.println(list);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void destroy() {
    }
}

你可能感兴趣的:(JavaWeb)