SpringBoot (7) Use of Filter

    Think about a question, should the server really accept all the requests from the client? no. For example, take the user registration function we implemented before. If the user’s nickname contains some unfriendly letters or Chinese characters, should you filter it out for him or let him register? There is no doubt that we need to filter out some unfriendly requests. 

    If you are a novice and have not read my previous series of SpringBoot articles, it is recommended to at least read this one:

SpringBoot (4) SpringBoot builds a simple server_springboot makes a service_heart poisoned blog-CSDN blog

    If you want to study systematically from beginning to end, please pay attention to my column and keep updating:

https://blog.csdn.net/qq_21154101/category_12359403.html

Table of contents

1. Filter

Two, create Filter

3. SpringBoot uses Filter

1. @WebFilter annotation + @ServletComponentScan annotation

2. Use @Component annotation

4. Practice - sensitive word filter


1. Filter

    Filter, a filter, is a middleware used between the client and the server to filter some requests. Its role usually includes the following aspects:

1. Session verification

2. Judgment of user authority

3. Sensitive word filtering

4. Set encoding, etc.

    There can be 0-multiple filters, as shown in the figure below:

Two, create Filter

    Filter is an interface under servlet. The method of creating a filter is relatively simple, just implement the Filter interface. Usually, we don't need to modify the implementation of init and destroy, just rewrite the doFiler method:

import javax.servlet.*;
import java.io.IOException;

public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

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

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

3. SpringBoot uses Filter

    SpringBoot supports the use of Filter, so how to use it? There are many ways, except for the configuration method that dogs do not use, here are two ways. Both methods have their own advantages and disadvantages, and you can use them according to your actual needs.

1. @WebFilter annotation + @ServletComponentScan annotation

    The first way is to use the @WebFilter annotation in the Filter implementation class (indicating that the class is a Filter) and add the ServletComponentScan annotation in the Application class (tell the Application which path to scan the Filter). As follows:

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(urlPatterns = "/*")
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("测试第一个过滤器");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan(basePackages = "com.zhaojun.server.filter")
public class AndroidServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(AndroidServerApplication.class, args);
	}
}

    Run the project and try to access the following interface:

http://localhost:8080/register?name=hhh&phone=19999999999&password=123456

 It can be seen that the following log is output, indicating that the filter is effective:

Using the @WebFilter annotation + @ServletComponentScan annotation to use Filter, you can specify the url to be intercepted, but you cannot specify the filter execution order.

2. Use @Component annotation

    We also mentioned earlier that the filter can have 0-more than one. In an actual project, we may have multiple filters and there may be a necessary sequence for multiple filters. Then, using the first method mentioned above cannot meet our demands. In this scenario, you can use the second @Component annotation. as follows:

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import java.io.IOException;

@Component
@Order(1)
public class Filter1 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("第1个过滤器");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import java.io.IOException;

@Component
@Order(2)
public class Filter2 implements Filter {

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

    Build it, or visit this interface:

​​​​​​​http://localhost:8080/register?name=hhh&phone=19999999999&password=123456

    As you can see, the execution order of Filter:

Using Filter with @Component annotation can guarantee the order of execution, but the filter cannot specify the intercepted url, and can only intercept all by default.

4. Practice - sensitive word filter

    The two methods of using filters are introduced above. Next, we implement a sensitive word filter based on the registration interface written before. When the request of the registration interface contains sensitive words, intercept the request, and release it if it does not contain sensitive words. Here I am using the first method:

package com.zhaojun.server.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {

    String[] sensitiveWords = {"sb", "2b", "cnm"};

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) servletResponse);
        String uri = request.getRequestURI();
        // 暂时只针对register接口过滤
        if (uri.contains("/register")) {
            String queryString = request.getQueryString();
            System.out.println(queryString);
            // 敏感字过滤校验通过,放行
            if (checkSensitiveWords(queryString)) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                // 校验不通过,重定向到fail接口
                wrapper.sendRedirect("/fail");
                System.out.println("敏感词过滤拦截");
            }
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    /**
     * 校验请求参数敏感字是否通过
     *
     * @param queryString 请求参数
     * @return true/false
     */
    private boolean checkSensitiveWords(String queryString) {
        for (int i = 0; i < sensitiveWords.length; i++) {
            if (queryString.contains(sensitiveWords[i])) {
                return false;
            }
        }
        return true;
    }
}

    If the sensitive word verification fails, the redirected fail interface is implemented as follows:

package com.zhaojun.server.controller;

import com.zhaojun.server.result.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RegisterFailController {
    @RequestMapping("fail")
    public Result registerFail() {
        Result result = new Result();
        result.code = 0;
        result.status = "fail";
        result.msg = "昵称含有敏感字";
        return result;
    }
}

Try the request interface ,     pay attention, this time use a name that contains sensitive words :

    As you can see, redirect to the fail interface, and the nickname contains sensitive words:

    This article introduces the role of Filter, two ways to use Filter in SpringBoot, and introduces the advantages and disadvantages of the two ways (order and specified url). Finally, based on the previous registration interface, a simple sensitive word filter is implemented. If you think this article is helpful to you, please leave a message or like it.

Guess you like

Origin blog.csdn.net/qq_21154101/article/details/131717615