系列六、过滤器(二)#案例演示

一、案例演示

说明:如下案例通过springboot的方式演示Filter是如何使用的,以获取Controller中的请求参数为切入点进行演示

1.1、前置准备工作

1.1.1、pom


	
	
		org.springframework.boot
		spring-boot-starter-web
	
	
		org.springframework.boot
		spring-boot-devtools
		runtime
		true
	
	
		org.springframework.boot
		spring-boot-starter-test
		test
	

	
		org.projectlombok
		lombok
		true
	
	
		com.alibaba
		fastjson
		1.2.76
	

1.1.2、UserDTO

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 18:32
 * @Description:
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class UserDTO implements Serializable {

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

}

1.1.3、StreamUtil

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/5 1:15
 * @Description:
 */
public class StreamUtil {

    public static String getBody(HttpServletRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return stringBuilder.toString();
    }

    public static ServletInputStream getServletInputStream(byte[] byteArr) {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArr);
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }

}

1.1.4、MyHttpServletRequestWrapper

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 20:50
 * @Description:
 */
@Getter
@Setter
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {

    /**
     * 用于保存读取到的body中的数据
     */
    private String body;


    public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.body = StreamUtil.getBody(request);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return StreamUtil.getServletInputStream(this.body.getBytes(Charset.forName("UTF-8")));
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

}

1.1.5、LoginService

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 23:49
 * @Description:
 */
@Service
public class LoginService {

}

二、创建过滤器

参考:
(1)https://blog.csdn.net/bzu_mei/article/details/126644963
(2)https://blog.csdn.net/worilb/article/details/129616956

2.1、方式一:@WebFilter + @ServletComponentScan

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 23:46
 * @Description:
 * @WebFilter(urlPatterns = "/login"):标识在类上,表明这个类是一个过滤器类,当访问 /login 接口时先执行此处的doFilter(执行业务逻辑),
 * 当执行chain.doFilter(wrapper, servletResponse);时,才会真正执行Controller层的代码逻辑
 */
@WebFilter
@Slf4j
public class LoginFilter implements Filter {

	// 实现方法处理逻辑

}
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 23:43
 * @Description:
 *
 * @ServletComponentScan的作用:将标识了@WebServlet、@WebFilter、@WebListener注解标注的类注入到IOC容器中
 */
@ServletComponentScan
@SpringBootApplication
public class SpringbootFilterApplication {

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


}

2.2、方式二:FilterRegistrationBean

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/5 1:53
 * @Description:
 *
 */
@Slf4j
public class AuthorityFilter implements Filter {

    // 业务逻辑代码    

}
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/5 1:59
 * @Description:
 *
 * 注意事项:
 *      此处也可以不写此配置,不写的话,AuthorityFilter由于加了@Component注解,也会被Spring容器管理,但是@Component注解没有路径过滤规则,
 * 即会将所有请求都过滤,配置的意义主要就是为了过滤某一类的请求,如下的配置是只有访问以 /privilege/* 打头的请求才会过滤,访问其他的则不过滤
 */
@Configuration
public class MyFilterConfig {

    @Bean
    public FilterRegistrationBean registrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new AuthorityFilter());
        registrationBean.setName("authorityFilter");
        registrationBean.addUrlPatterns("/privilege/*");
        registrationBean.setOrder(1);

        return registrationBean;
    }

}

三、使用过滤器(案例)

3.1、获取Controller层@RequestBody中的对象参数

3.1.1、LoginController#login()

@PostMapping("/login")
public String login(@RequestBody UserDTO param) {
    log.info("LoginController login param : {}", param);
    return "OK";
}

3.1.2、LoginFilter#doFilter()

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
	log.info("==================== LoginFilter doFilter ====================");
	log.info("bean loginService exist result : {} 存在", loginService == null ? "不" : "");

	HttpServletRequest request = (HttpServletRequest) servletRequest;
	MyHttpServletRequestWrapper wrapper = new MyHttpServletRequestWrapper(request);
	String jsonParam = wrapper.getBody();
	log.info("jsonParam:{}", jsonParam);

	chain.doFilter(wrapper, servletResponse);
}

3.1.3、测试

系列六、过滤器(二)#案例演示_第1张图片

系列六、过滤器(二)#案例演示_第2张图片

3.2、获取Controller层普通的对象参数

3.2.1、LoginController#login2()

@PostMapping("/login2")
public String login2(UserDTO param) {
    log.info("LoginController login2 param : {}", param);
    return "OK";
}

3.2.2、LoginFilter#doFilter()

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
    log.info("==================== LoginFilter doFilter ====================");
    log.info("bean loginService exist result : {} 存在", loginService == null ? "不" : "");
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    Map parameterMap = request.getParameterMap();
    Map requestMap = new HashMap<>();
    for (String key : parameterMap.keySet()) {
        String[] values = parameterMap.get(key);
        requestMap.put(key,values[0]);
    }
    log.info("requestMap:{}",requestMap);
    chain.doFilter(servletRequest, servletResponse);
}

3.2.3、测试#form-data

系列六、过滤器(二)#案例演示_第3张图片

3.2.4、测试#x-www-form-urlencoded

系列六、过滤器(二)#案例演示_第4张图片

3.3、获取Controller层字符串参数

3.3.1、LoginController#login3()

@GetMapping("/login3")
public String login3(String username, String password) {
    log.info("LoginController login3 username:{},password:{}", username, password);
    return "OK";
}

3.3.2、LoginFilter#doFilter()

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
    log.info("==================== LoginFilter doFilter ====================");
    log.info("bean loginService exist result : {} 存在", loginService == null ? "不" : "");
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    Map paramMap = new HashMap<>(2);
    paramMap.put("username", username);
    paramMap.put("password", password);
    log.info("paramMap:{}", paramMap);
    chain.doFilter(servletRequest, servletResponse);
}

3.3.3、测试

系列六、过滤器(二)#案例演示_第5张图片

系列六、过滤器(二)#案例演示_第6张图片

你可能感兴趣的:(SpringBoot系列,java,spring,mybatis)