Filter application-permission management and filtering sensitive words

I just made an application about Filter. I took advantage of my brain fever and quickly recorded it. There are two small applications in this article. One is about permission management . *What is permission management? *It means that you can’t do anything when you are not logged in. This operation is very familiar. For example, Tmall’s ordering system can only browse when you are not logged in, and you cannot submit orders and payments. When you submit an order You will be reminded to log in first. Another common example is the login query system of some websites. When you are not logged in, you cannot view any information. This is permission management. The advantage of this is that it is very safe. It filters out some insecure factors. Generally Now as long as it involves logging in, the website basically uses filters to achieve this authority management operation. Another small application is to filter sensitive words . This application is more common. This example can be seen everywhere. For example, in the Canyon of Kings, you are from Zuan, and the opposite is very good, or you are also very good, and the opposite is spraying you. Then you take advantage of the good blood of the Zuan people and start to spray. At this time, you will find "I ** You * **" in the chat box . A lot of me, you, and asterisks. Vocabulary filtering operation, next we focus on implementing the following sensitive word filtering.
Regarding permission management, it is actually very simple to implement. The general idea is to first see whether the resource you want to access is related to login. For example, login.jsp will not be filtered out, and then we can judge whether you have logged in or not. The login is judged by the session. When you log in successfully, you will save a parameter in the session and verify whether the parameter exists in the filter. When you open the browser and have not logged in, the parameter must be Empty, at this time if you want to access other resources will be blocked, the filter code is as follows:

 @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //强制转换
        HttpServletRequest request = (HttpServletRequest) req;

        //获取请求的资源路径 看是否是登录相关的资源
        String uri = request.getRequestURI();

        //判断
        if (uri.contains("/index.jsp") || uri.contains("/UserLoginServlet") ||uri.contains("/JSP/css/") || uri.contains("/JSP/js/")){
            //包含 证明用户就是想登陆 放行
            chain.doFilter(req, resp);
        }else{
            //不包含 验证用户是否已经登录
            if (request.getSession().getAttribute("user") != null){
                //已经登陆 放行
                chain.doFilter(req, resp);
            }else {
                System.out.println("您被拦截了,您需要先登录" );
                request.setAttribute("longinmessage","您尚未登录,请先登录!");
                request.getRequestDispatcher("/index.jsp").forward(request, resp);
            }
        }
    }

Then let's focus on the operation to realize the shielding of sensitive words. The idea of ​​this operation is very simple, that is, there is a txt file containing various sensitive words, one sensitive word per line. When you call the method to enter a sentence with a sensitive word, the sensitive word will be replaced with an asterisk. This replacement operation cannot be implemented in the request method, so we need to use a proxy mode, this That’s the trouble. *Why use proxy mode? *For example, when we call request.getParameter("name");this statement, we assign a value to the name , but this method itself does not support the replacement of sensitive characters. We need to enhance the function of this method so that it can replace sensitive words when it is called.
Then let us first talk about what is the agency model?
The proxy mode can enhance the function of some methods, just like the enhancement filtering function for a method mentioned above. When calling this method in the future, it will filter out some sensitive words. There is also a design pattern to enhance the function of the method. Called the decorator mode , both of these can achieve the function of the enhanced method. The agency model, as the name suggests, has a model of agents. If there is an agent, there must be a real big boss. Agents get goods from the big boss, just like an example in our daily life. Many shoes are sold in Putian. There are many big cows in Putian, and they have many agents under them. We buy shoes through agents instead of directly looking for big bosses. For example, the big boss sells this pair of shoes for 800, and the agent successfully bought it at 900. The agent increased the price and made me a hundred dollars tearfully. Then why don't we go to the big boss directly? Because the price is too high, or the big boss cannot be found, we can only get the goods through agents. In this way, the agency model will understand a lot. The agent acts for the big boss. We get the goods from the agent and achieve the purpose of getting the goods from the big boss .
Let’s use a simple example to illustrate. Let’s create an interface first. Both agents and big bosses sell shoes. We need an interface to illustrate the relevant methods:

package proxy;

/**
 * @author Shi Jun Yi
 * @version 1.0
 * @date 2021/1/25 12:32
 */
public interface SaleComputer {

    public String sale(double money);

    public void show();
}

With this interface, we must have a real big boss object

package proxy;

/**
 * @author Shi Jun Yi
 * @version 1.0
 * @date 2021/1/25 12:34
 */
public class Lenovo implements SaleComputer {
    @Override
    public String sale(double money) {
        System.out.println("花了"+money+"元买了一双回到未来....");
        return "耐克鞋子";
    }

    @Override
    public void show() {
        System.out.println("展示鞋子.....");
    }
}

Next, we write a test class:

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author Shi Jun Yi
 * @version 1.0
 * @date 2021/1/25 12:35
 */
public class ProxyTest {

    public static void main(String[] args ){
        //创建真实对象
        Lenovo lenovo = new Lenovo();

        //动态代理 增强lenovo对象
        /*
            三个参数
                类加载器 真实对象
                接口数组 真实对象
                处理器 很重要 核心业务逻辑
         */
        SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
            /*
                代理逻辑 代理对象调用的所有的方法都会触发该方法
                    参数
                        1 代理对象
                        2 代理对象调用的方法
                        3 调用对象的时候传递的参数
             */
            @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]);*/

               //使用真实对象的方法调用该方法

                if(method.getName().equals("sale")){
                    //增强参数
                    double money = (double)args[0];
                    money = money*0.85;
                    System.out.println("专车接....");
                    String obj = (String) method.invoke(lenovo, money);
                    System.out.println("专车送....");
                    //增强返回值
                    return obj+"_鞋垫";
                }else{
                    Object obj = method.invoke(lenovo,args);
                    return obj;
                }
            }
        });

        //调用方法
        String computer = proxy_lenovo.sale(80000);

        System.out.println(computer);
    }
}

Insert picture description here
Then let's talk about the general implementation steps:

  1. Since it is a proxy mode, we must proxy the real object, so we create a new real object.
  2. Proxy.newProxyInstance(....)Realize the proxy of the real object through a fixed format format. In this method, there is an overridden invoke method, which contains the core enhanced logic. All methods called by the proxy logic proxy object will trigger the method.
  3. There are three parameters in the invoke method. The first parameter is the proxy object, the second parameter is the method called by the proxy object, and the parameters passed when the proxy object calls the method.
  4. String computer = proxy_lenovo.sale(80000);Since we are calling the sale method, we need to determine whether the method name is sale or not, if it is, the return value will be enhanced, if not, the method will be executed by default. The implementation of this enhancement method is actually to execute the previously unenhanced method first, then add some content to the unenhanced return value, and return the new return value to achieve the effect of the enhanced method.
  5. When the method called by our proxy object is sale, the parameter will be passed first, and then this parameter will be multiplied by 0.85, and the method of the real object will be executed and a value will be returned. String obj = (String) method.invoke(lenovo, money);This sentence is the statement that calls the method of the real object. After getting the return value, add some content to the return value and return the output.
    This is a simple implementation. Next we come back to the issue of sensitive words.
    First, let’s create a file named "Sensitive Words.txt", the content is as follows:
    Insert picture description here
    I won’t say some extreme Zuan words, they are too sensitive, you add them by yourself ~
    First, we create a new filter named sesitivewordsfilter , we Naturally, we need to perform character filtering operations in the doFlter method . At the beginning, we create a proxy object. The mode is the same as above. Before doing the enhancement method, we must first load the sensitive vocabulary .txt file, and the initialization record file should be placed in init In the method, first we need to have a collection of sensitive words. private List<String> list = new ArrayList<>();In the inti method, there is a parameter called config. We can use the config config.getServletContext().getRealPath("敏感词汇.txt");method to load the file and read it after loading. We use the knowledge of the IO stream. Use a file with a buffer to read the file BufferedReader br = new BufferedReader(new FileReader(contextPath));, and then add each line of the file to the collection. When the file is read, close the stream, so that all our sensitive words will be stored in the list collection. We only need to compare whether it is included. Let’s first enhance the getParameter method of the request. The first step we must do is to determine whether it is the method or not, through the built-in parameter listmethod.getName();To return the method name, then execute the original getPramenter method and return its value. After the return, if the return value is not empty, then traverse the list combination to see if the return value contains sensitive words in the list collection, and if it contains, replace it with an asterisk . If it is not the called getParamenter method, it returns the original parameters return method.invoke(req,args);, and finally chain.doFilter(proxy_req, resp);returns the enhanced request.
    Filter code:
package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Shi Jun Yi
 * @version 1.0
 * @date 2021/1/25 15:03
 * 敏感词汇过滤器
 */
@WebFilter(filterName = "SensitiveWordsFilter", value = "/TestServlet")
public class SensitiveWordsFilter implements Filter {
    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //创建代理对象 增强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 {
                //增强方法 先判断是否是该方法
                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;
                }

                //增强getAttribute方法
                if (method.getName().equals("getAttribute")){
                    //增强返回值
                    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);
            }
        });

        //放行增强后的request方法
        chain.doFilter(proxy_req, resp);
    }

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

    @Override
    public void init(FilterConfig config) throws ServletException {

        try{
        //加载文件
            String contextPath = config.getServletContext().getRealPath("敏感词汇.txt");

            //读取文件
            BufferedReader br = new BufferedReader(new FileReader(contextPath));

            //将文件的每一行添加到list当中
            String line = null;
            while ((line = br.readLine()) != null){
                list.add(line);
             }
             br.close();
            System.out.println(list);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

We create a new servlet to call the enhanced method,

package control;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Shi Jun Yi
 * @version 1.0
 * @date 2021/1/25 15:33
 */
@WebServlet(name = "TestServlet", value = "/TestServlet")
public class TestServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        String msg = request.getParameter("msg");

        request.setAttribute("name2", "我diu,你这个大笨蛋,大SB...");
        System.out.println(request.getAttribute("name2"));

        System.out.println(name+":"+msg);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

Next, we check the effect: the
Insert picture description here
Insert picture description here
effect is not bad, hhh~~, the above is the content of this blog, if there are any shortcomings, please point out, thank you.

Reference content: https://www.bilibili.com/video/BV1u7411Z769?p=12

Guess you like

Origin blog.csdn.net/weixin_44475741/article/details/113118081