Web-过滤器

本文介绍了Java Web中过滤器的作用,包括拦截请求和过滤响应。详细阐述了过滤器的实现方式,执行顺序,以及如何在web.xml中配置。文章还提及了常见的问题,如无法实现Filter接口的解决方案。此外,重点讨论了登录校验的实现,特别是如何通过会话校验登录状态,并分别讲解了校验特定资源和所有资源的配置策略。对于敏感词汇过滤,作者承认尚未完全理解其流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作用

拦截请求,过滤响应

实现

实现 Filter 接口

执行顺序

根据过滤器的配置方式分别

  1. 配置文件(web.xml)配置,执行顺序由<filter-mapping>标签的配置顺序决定

  2. 注解配置,执行顺序由filterName属性值的字母顺序决定

常见问题

无法实现Filter接口

找到apache-tomcat-8.5.75->lib->Servlet-api.jar导入

字符编码设置

@WebFilter(urlPatterns = {"/*"})
public class CharsetFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("text/html;charset=UTF-8");
        filterChain.doFilter(servletRequest, servletResponse);
    }
    @Override
    public void destroy() {
    }
}

web.xml配置Filter

<!--配置过滤器-->
<filter>
    <filter-name>Charser</filter-name>
    <filter-class>com.xxx.controller.filter.CharsetFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Charser</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

敏感词汇过滤(没怎么搞懂流程)

@WebFilter(urlPatterns = {"*.do"})
public class BanFilter implements Filter {
    // 存放违规字符的集合
    private List<String> words = new ArrayList<>();
​
    // 加载时读取文件字符存入集合
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\Knowledge\\编程\\00-资料库\\05-File\\words.txt"), "utf-8"))) {
            String str = null;
            while ((str = reader.readLine()) != null) {
                words.add(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
​
    // 过滤违规字符
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        String text = servletRequest.getParameter("text");
        // 创建请求对象的代理对象,
        // 在代理对象的方法执行过程中判断当前方法是不是getParameter
        // 是则获取值进行相应修改
        // 最后将代理传递给servlet
        ServletRequest requestProxy = (ServletRequest) Proxy.newProxyInstance(servletRequest.getClass().getClassLoader(),
                servletRequest.getClass().getInterfaces(), new InvocationHandler() {
                    // method:真实对象调用某个方法的方法对象
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 调用真实对象方法
                        Object returnValue = method.invoke(servletRequest, args);
                        // 获取真实对象调用的方法的方法名
                        String methodName = method.getName();
                        if (methodName.equals("getParameter")) {
                            String value = (String) returnValue;
                            for (String word : words) {
                                if (value.contains(word)) {
                                    value = value.replace(word, "*");
                                }
                            }
                            return value;
                        }
                        return returnValue;
                    }
                });
        // 放行时传递的是代理对象
        filterChain.doFilter(requestProxy,servletResponse);
    }
​
    @Override
    public void destroy() {
​
    }
}

登录校验

基于会话完成登录状态的保存,向系统中发送请求时,通过过滤器拦截请求,验证会话中是否存储了登录状态,如果有,则放行,如果没有,则重定向到登录页面(登录成功必须向会话对象中保存登录状态)

校验特定资源

重点在登录校验过滤器的url-pattern的配置上

// 对特定资源进行登录校验
@WebFilter(urlPatterns = "*.do")
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        // 获取Session值
        Object loginUser = req.getSession().getAttribute("user");
        // 未登录状态
        if (null == loginUser) {
            // 跳转回主页面
            resp.sendRedirect("/html/main.html");
        // 登录状态    
        } else {
            // 放行
            filterChain.doFilter(req, resp);
        }
    }
    @Override
    public void destroy() {}
}

校验所有资源

重点在需要放行的资源上

// 对所有资源进行登录校验
@WebFilter(urlPatterns = {"/*"})
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    // 在该方法内部完成登录校验
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        // 获取请求地址,如:@WebServlet("/test.do") == /test.do
        String requestURI = req.getRequestURI();
        if (requestURI.endsWith("login.jsp")
                || requestURI.endsWith("register.jsp")
                || requestURI.endsWith("login.do")
                || requestURI.endsWith("register.do")
        ) {
            //请求特定资源放行
            filterChain.doFilter(req,resp);
        //其它所有的请求和页面都必须进行登录校验
        }else{
            Object loginUser = req.getSession().getAttribute("User");
            //没有登录:打回
            if (null == loginUser) {
                resp.sendRedirect("/html/login.html");
            //登录过了:放行
            }else{
                filterChain.doFilter(req,resp);
            }
        }
    }
    @Override
    public void destroy() {}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值