游侠网云服务,免实名免备案服务器 游侠云域名,免实名免备案域名

统一声明:

1.本站联系方式
QQ:709466365
TG:@UXWNET
官方TG频道:@UXW_NET
如果有其他人通过本站链接联系您导致被骗,本站一律不负责!

2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET
3.免实名域名注册购买- 游侠云域名
4.免实名国外服务器购买- 游侠网云服务
JSP Filter过滤器功能与简单用法示例|新手一看就会的实操教程

这篇文章不讲复杂理论,只给新手“一看就会”的实操:从创建Filter类、重写doFilter核心方法,到配置web.xml映射规则,每一步都有简单示例——比如用Filter实现全局UTF-8编码,或者拦截未登录用户访问首页。跟着步骤走,5分钟就能跑通第一个Filter案例,马上体会到“统一处理”的爽感。不管你是刚入门想学实用技巧,还是想解决开发里的重复劳动,这篇教程都能帮你快速掌握Filter的功能和用法,看完就能上手解决实际问题,告别“到处贴代码”的麻烦!

你有没有过写JSP项目时的崩溃瞬间?比如每个Servlet都要写response.setCharacterEncoding("UTF-8"),漏一个就乱码;或者每个页面都要判断用户有没有登录,写着写着就烦了——这些重复活其实压根不用自己扛,JSP里的Filter过滤器就是专门解决这事儿的“工具人”。我去年帮刚毕业的小杨调他的电商项目,他之前每个页面都埋了登录判断的代码,改个逻辑要翻10几个文件,我给他加了个Filter,直接把登录验证集中到一个地方,他当时眼睛都亮了:“原来还有这操作?”今天就把我教他的那套东西拆开来讲,保证你看完就能上手。

JSP Filter到底是啥?先搞懂它的核心功能

其实Filter的本质特简单:它是Servlet规范里的一个组件,相当于Web应用的“拦截岗”——用户发请求过来,它先拦下来“检查检查”;Servlet处理完返回响应,它再拦下来“加工加工”。你可以把它理解成快递驿站:快递(请求)过来,驿站(Filter)先查有没有违禁品(验证权限),再贴个标签(设置编码),然后传给收件人(Servlet);收件人寄快递(响应)回去,驿站再查一遍(加缓存头),最后发给用户。

那它到底能帮我们干哪些活?我 了几个最常用的核心功能,都是新手必懂的:

第一个是统一字符编码处理。你肯定遇过这种情况:写了个Servlet,忘了设置编码,结果用户输入的中文变成乱码——要是每个Servlet都要写一遍request.setCharacterEncoding("UTF-8"),不仅麻烦还容易漏。用Filter就不一样了,写一个EncodingFilter,拦截所有请求,把request和response的编码都设成UTF-8,一次搞定。我之前做的教育平台项目,用户上传的文件名经常有特殊字符,导致下载时出错,后来加了个Filter把文件名里的“/”“”都替换成“-”,问题直接解决,省了我改10几个上传接口的时间。

第二个是集中权限验证。比如用户没登录就想访问订单页面,这时候Filter就能拦下来,直接跳转到登录页——不用在每个页面都写if(session.getAttribute("user") == null)。小杨之前的电商项目就是这么改的,改完他说:“原来10分钟才能改完的逻辑,现在1分钟就搞定了。”

第三个是过滤非法参数。比如防止SQL注入,用户输入的内容里有'或者or 1=1,Filter可以把这些特殊字符替换成安全的内容。我之前帮一个论坛项目做安全优化,加了个Filter把请求参数里的'换成'',把or换成空字符串,后来测试用SQL注入脚本试了试,根本进不去——这比在每个接口里写参数过滤省心多了。

第四个是静态资源缓存。比如CSS、JS这些静态文件,每次请求都从服务器拿,很耗资源。Filter可以给这些资源加个Cache-Control响应头,让浏览器缓存几天,这样用户第二次访问就直接从本地拿,服务器压力小了,页面加载也快了。Oracle官网的Servlet 3.1规范里明确提到,Filter的设计目标就是“在请求处理前后插入通用逻辑”,避免代码重复——这不是我说的,是官方认证的“偷懒工具”。

新手必看的Filter实操:从0到1写一个能用的过滤器

说了这么多,不如直接动手写一个——我拿最常用的字符编码Filter登录验证Filter举例子,步骤都是我当年踩过坑 出来的,保证你跟着做就能成。

第一步:写一个Filter类(核心中的核心)

Filter是个接口,你得写个类实现它,然后重写三个方法:init()(初始化,比如拿参数)、doFilter()(核心逻辑,拦截请求和响应)、destroy()(销毁资源,一般不用写)。

比如写一个EncodingFilter

import javax.servlet.;

import java.io.IOException;

public class EncodingFilter implements Filter {

private String encoding; // 要设置的编码格式

// 初始化方法:获取web.xml里的init-param

@Override

public void init(FilterConfig filterConfig) throws ServletException {

// 从web.xml里拿encoding参数,默认是UTF-8

encoding = filterConfig.getInitParameter("encoding");

if (encoding == null) {

encoding = "UTF-8";

}

}

// 核心方法:处理请求和响应

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

// 设置请求和响应的编码

request.setCharacterEncoding(encoding);

response.setCharacterEncoding(encoding);

response.setContentType("text/html;charset=" + encoding); // 避免响应乱码

// 关键!把请求传给下一个Filter或Servlet,忘了写就拦截死了

chain.doFilter(request, response);

}

// 销毁方法:一般不用写

@Override

public void destroy() {

}

}

我当年学的时候,一开始忘了写chain.doFilter(),结果请求发出去,浏览器一直转圈圈,调试了半小时才发现——这坑你可别踩。

再写个LoginFilter,判断用户有没有登录:

import javax.servlet.;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import java.io.IOException;

public class LoginFilter implements Filter {

private String loginUrl; // 登录页URL

private String excludeUrls; // 要排除的URL(比如登录接口、静态资源)

private String[] excludeUrlArray;

@Override

public void init(FilterConfig filterConfig) throws ServletException {

// 从web.xml拿参数

loginUrl = filterConfig.getInitParameter("loginUrl");

excludeUrls = filterConfig.getInitParameter("excludeUrls");

// 把排除的URL拆成数组

if (excludeUrls != null) {

excludeUrlArray = excludeUrls.split(",");

}

}

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) servletRequest;

HttpServletResponse response = (HttpServletResponse) servletResponse;

HttpSession session = request.getSession();

// 获取请求的URL

String requestUrl = request.getRequestURI();

// 检查是不是要排除的URL,是的话直接放行

if (isExclude(requestUrl)) {

chain.doFilter(request, response);

return;

}

// 检查用户有没有登录

if (session.getAttribute("user") == null) {

// 没登录,跳转到登录页

response.sendRedirect(request.getContextPath() + loginUrl);

} else {

// 登录了,放行

chain.doFilter(request, response);

}

}

// 判断请求URL是不是在排除列表里

private boolean isExclude(String requestUrl) {

if (excludeUrlArray == null) {

return false;

}

for (String url excludeUrlArray) {

if (requestUrl.startsWith(requestUrl.getContextPath() + url)) { // 注意加上下文路径

return true;

}

}

return false;

}

@Override

public void destroy() {

}

}

这里要注意:ServletRequestServletResponse要转成HttpServletRequestHttpServletResponse,不然拿不到session和重定向方法——我当年第一次写的时候没转,结果getSession()报错,查了半天才明白。

第二步:配置web.xml(让容器知道你的Filter)

写好Filter类还不够,得告诉Web容器(比如Tomcat)“我有个Filter,要用来拦截请求”——这就得靠web.xml里的配置了。下面是EncodingFilterLoginFilter的配置:

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"

version="4.0">

<!-

  • 配置EncodingFilter >
  • EncodingFilter

    com.example.filter.EncodingFilter

    <!-

  • 初始化参数:编码格式 >
  • encoding

    UTF-8

    EncodingFilter

    <!-

  • 拦截所有请求 >
  • /

    <!-

  • 配置LoginFilter >
  • LoginFilter

    com.example.filter.LoginFilter

    <!-

  • 初始化参数:登录页URL、排除的URL >
  • loginUrl

    /login.jsp

    excludeUrls

    /login,/css/,/js/ <!-

  • 排除登录接口、CSS、JS >
  • LoginFilter

    <!-

  • 拦截所有请求 >
  • /

    这里有几个关键细节,新手一定要记牢:

  • 要和里的一致:不然容器找不到你的Filter。
  • 的写法/拦截所有请求,.jsp拦截所有JSP页面,/user/拦截/user开头的请求——小杨之前写的时候把url-pattern设成.jsp,结果漏掉了Servlet的请求(比如/addProduct),后来改成/才覆盖所有请求。
  • 排除静态资源:比如LoginFilter要是拦截了CSS、JS,那登录页的样式就乱了——所以要加excludeUrls参数,把/css//js/排除掉,我之前就踩过这坑,改了半小时才好。
  • 为了让你更清楚配置参数的作用,我做了个表格:

    参数名 作用说明 示例值
    filter-name Filter的唯一标识,关联filter和filter-mapping EncodingFilter
    filter-class Filter类的全路径(包名+类名) com.example.filter.EncodingFilter
    url-pattern 要拦截的URL模式,支持通配符 /
    init-param 初始化参数,在init方法中获取(比如编码、排除URL) encoding=UTF-8

    第三步:测试!看看Filter管用不

    写好之后,部署到Tomcat,然后做几个测试:

  • 测试字符编码:写个Servlet,输出中文,要是之前没设置编码会乱码,现在用了EncodingFilter,应该显示正常。
  • 测试登录验证:没登录就访问/order.jsp,应该自动跳转到/login.jsp;登录之后再访问,应该能正常打开。
  • 测试排除静态资源:没登录的时候访问/css/style.css,应该能正常加载——要是加载不了,说明排除参数没写对。
  • 我当年测试的时候,第一次部署就成功了,把所有setCharacterEncoding都删了,页面还是正常显示中文——那种成就感,跟小时候拼完乐高一样。

    别觉得Filter很高深,其实它就是个“把重复活集中干”的工具。我当年学的时候,也是跟着文档写了个字符编码过滤器,然后把项目里所有的重复代码都删了,那种“一身轻”的感觉至今还记得。你要是按我讲的步骤试一次,肯定也会爱上这工具—— 能偷懒又能提高效率的事,谁不爱呢?

    要是你写Filter的时候遇到问题,比如拦截不到请求、乱码,或者配置错了,都可以在评论区说,我帮你看看——咱们都是踩过坑的人,互相帮忙总比自己瞎琢磨强~


    JSP Filter主要能帮我解决哪些重复工作?

    像每个Servlet都要写的response.setCharacterEncoding(“UTF-8”)字符编码设置,每个页面都要加的用户登录判断,还有用户输入里的非法字符(比如SQL注入的’、or 1=1)过滤,这些重复写起来烦还容易漏的活,Filter都能帮你集中到一个地方处理,不用再翻10几个文件改代码。我去年帮小杨改电商项目时,他之前每个页面都埋了登录判断,加了Filter后直接把逻辑集中到一个地方,改起来特省心。

    比如字符编码,写一个EncodingFilter拦截所有请求,把request和response的编码都设成UTF-8,一次搞定;登录验证也是,写个LoginFilter拦所有请求,没登录就跳登录页,不用每个页面都写if(session.getAttribute(“user”) == null)。

    Filter的url-pattern写/会拦截所有请求吗?包括CSS、JS这些静态资源吗?

    写/确实会拦截所有请求,不管是JSP页面、Servlet接口,还是CSS、JS、图片这些静态资源都能拦到。但静态资源一般不用验证权限,比如登录页的CSS要是被拦了,页面样式就乱了,所以得在Filter的配置里加init-param参数,比如excludeUrls,把/css/、/js/、/images/这类静态资源的路径写进去,让Filter跳过这些请求。

    我之前踩过这坑,第一次写LoginFilter时没排除静态资源,结果登录页的样式全乱了,后来加了excludeUrls=”(/css/,/js/)”才好,你写的时候记得检查这块。

    doFilter方法里的chain.doFilter()能不能漏掉?漏掉会有什么问题?

    绝对不能漏!这是Filter的核心关键,我当年第一次写EncodingFilter时就忘了加,结果部署后请求发出去,浏览器一直转圈圈加载不出来,查了半小时才发现是漏了这句话。

    chain.doFilter()的作用是把拦截下来的请求传给下一个Filter或者目标Servlet,如果漏掉,请求就被Filter“卡住”了,不会往下传递,Servlet根本收不到请求,自然没法处理。所以不管写什么Filter,chain.doFilter(request, response)这句话一定要记得加。

    Filter的init-param是干嘛用的?怎么在代码里拿到这些参数?

    init-param是给Filter传递初始化配置的,比如你想让EncodingFilter用UTF-8编码,或者让LoginFilter知道登录页的URL是/login.jsp,这些不用硬写在代码里的配置,都可以通过init-param传进去,这样改配置不用动代码,直接改web.xml就行。

    代码里拿参数也简单,Filter的init方法里有个FilterConfig对象,用filterConfig.getInitParameter(“参数名”)就能拿到。比如EncodingFilter里的encoding参数,就是用filterConfig.getInitParameter(“encoding”)拿到的,要是没传这个参数,还能给个默认值UTF-8,特灵活。

    怎么测试写好的Filter有没有生效?比如字符编码Filter?

    测试字符编码的话,你可以写个简单的Servlet,里面不写任何编码设置,直接用response.getWriter().write(“测试中文”),然后访问这个Servlet,如果之前没加Filter会显示乱码,加了EncodingFilter之后应该能正常显示中文,说明Filter生效了。

    测试登录验证Filter的话,你可以先不登录,直接访问需要权限的页面(比如/order.jsp),如果自动跳转到login.jsp,说明Filter拦住了未登录的请求;登录之后再访问,能正常打开页面,就说明验证没问题。要是没生效,先检查web.xml的filter-mapping是不是和filter-name对应上了,或者url-pattern有没有写错。