【过滤器】web中过滤器的使用与乱码问题解决
一、过滤器Filter
1.filter的简介
filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目 标资源访问前后进行逻辑处理
2.快速入门
步骤:
1)编写一个过滤器的类实现Filter接口
2)实现接口中尚未实现的方法(着重实现doFilter方法)
3)在web.xml中进行配置(主要是配置要对哪些资源进行过滤)
(1)创建Filter实现Filter
拦截之后要放行。
package filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class FirstFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 自动拦截请求 System.out.println("filter running......."); // 放行 chain.doFilter(request, response); } @Override public void destroy() { // TODO Auto-generated method stub } }
(2)Web.xml配置一下
<filter> <filter-name>FirstFilter</filter-name> <filter-class>filter.FirstFilter</filter-class> </filter> <filter-mapping> <filter-name>FirstFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
/*代表所有请求,如果不放行,客户端得不到响应。
3.Filter的API详解
(1)filter生命周期及其与生命周期相关的方法
Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法
init(Filterconfig):代表filter对象初始化方法 filter对象创建时执行
doFilter(ServletRequest,ServletResponse,FilterCha):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法
destory():代表是filter销毁方法 当filter对象销毁时执行该方法
Filter对象的生命周期:
Filter何时创建:服务器启动时就创建该filter对象
中间在客户端访问过滤器过滤的资源时调用doFilter方法
Filter何时销毁:服务器关闭时filter销毁
(2)Filter的API详解
1)init(FilterConfig)
其中参数config代表 该Filter对象的配置信息的对象,内部封装是该filter的配置信息。
2)destory()方法
filter对象销毁时执行
3)doFilter方法
doFilter(ServletRequest,ServletResponse,FilterChain)
其中的参数:
ServletRequest/ServletResponse:每次在执行doFilter方法时 web容器负责创建一个request和一个response对象作为doFilter的参数传递进来。该request个该response就是在访问目标资源的service方法时的request和response。
FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求
4.Filter的配置
<filter> <filter-name>Filter2</filter-name> <filter-class>filter.Filter2</filter-class> <init-param> <param-name>name</param-name> <param-value>dahua</param-value> </init-param> </filter> <filter-mapping> <filter-name>Filter2</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>
也可以直接拦截Servlet(等价于url-pattern /sertvle1)
<filter-mapping> <filter-name>Filter2</filter-name> <servlet-name>servlet</servlet-name> </filter-mapping>
①url-pattern配置时(不用写工程名字,直接写路径)
1)完全匹配 /sertvle1
2)目录匹配 /aaa/bbb/* ----最多的
/user/*:访问前台的资源进入此过滤器
/admin/*:访问后台的资源时执行此过滤器
3)扩展名匹配 *.abc *.jsp
注意:url-pattern可以使用servlet-name替代,也可以混用
dispatcher:访问的方式(了解)
REQUEST:默认值,代表直接访问某个资源时执行filter
转发拦截一次,重定向2次
FORWARD:转发时才执行filter
INCLUDE: 包含资源时执行filter
ERROR:发生错误时 进行跳转是执行filter
5.总结Filter的作用?
1)公共代码的提取
2)可以对request和response中的方法进行增强(装饰者模式/动态代理)
3)进行权限控制
6.总结
1.Filter先写实现方法,再在web.xml中配置(名字,映射以及拦截的请求)
url-pattern配置时 不写工程名字
1)完全匹配 /sertvle1
2)目录匹配 /aaa/bbb/* ----最多的
/user/*:访问前台的资源进入此过滤器
/admin/*:访问后台的资源时执行此过滤器
3)扩展名匹配 *.abc *.jsp
2.过滤器的执行顺序根据你在web.xml中映射的顺序执行。
3.可以过滤用户请求:
package web.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import daomain.User; public class RequestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub HttpServletRequest req =(HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; HttpSession session = req.getSession(); User user = (User) session.getAttribute("user"); if(user==null){ request.getRequestDispatcher("/index.jsp").forward(request, response); } else{ System.out.println(user); } chain.doFilter(request, response); } @Override public void destroy() { // TODO Auto-generated method stub } }
二、设置编码格式
1.post提交
(1)编写过滤器代码
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("utf-8"); chain.doFilter(request, response); }
(2)Web.xml中队所有请求拦截
(3)后台直接接受post提交的中文数据
2.get提交
接收前端:
String para = request.getParameter("name"); String para2 = new String(para.getBytes("iso-8859-1"),"utf-8");
向前端发送
//设置response查询的码表 //response.setCharacterEncoding("UTF-8"); //通过一个头 Content-Type 告知客户端使用何种码表 //response.setHeader("Content-Type", "text/html;charset=UTF-8"); // 这句与上句等价,开发中只用写这句,tomcat自动设置第一句 response.setContentType("text/html;charset=UTF-8");
三、装饰者模式解决乱码
package filter; import java.io.IOException; import java.io.UnsupportedEncodingException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class EncodingFilter implements Filter{ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //request.setCharacterEncoding("UTF-8"); //在传递request之前对request的getParameter方法进行增强 /* * 装饰者模式(包装) * * 1、增强类与被增强的类要实现统一接口 * 2、在增强类中传入被增强的类 * 3、需要增强的方法重写 不需要增强的方法调用被增强对象的 * */ //被增强的对象 HttpServletRequest req = (HttpServletRequest) request; //增强对象 EnhanceRequest enhanceRequest = new EnhanceRequest(req); chain.doFilter(enhanceRequest, response); } @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } } class EnhanceRequest extends HttpServletRequestWrapper{ private HttpServletRequest request; public EnhanceRequest(HttpServletRequest request) { super(request); this.request = request; } //对getParaameter增强 @Override public String getParameter(String name) { String parameter = request.getParameter(name);//乱码 try { parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return parameter; } }
四、过滤登录的过滤器
<filter> <filter-name>sessionFilter</filter-name> <filter-class>com.FlyPig.util.filter_session</filter-class> </filter> <filter-mapping> <filter-name>sessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
filter代码如下:起到了过滤登陆界面login.jsp和根路径以外的过滤
1 package com.FlyPig.util; 2 3 import java.io.IOException; 4 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 import javax.servlet.http.HttpSession; 14 15 public class filter_session implements Filter { 16 private String encoding; 17 18 public filter_session() { 19 } 20 21 public void init(FilterConfig filterconfig) throws ServletException { 22 encoding = "utf-8"; 23 } 24 25 public void doFilter(ServletRequest servletrequest, 26 ServletResponse servletresponse, FilterChain filterchain) 27 throws IOException, ServletException { 28 servletrequest.setCharacterEncoding(encoding); 29 servletresponse.setCharacterEncoding(encoding); 30 HttpServletRequest req=(HttpServletRequest)servletrequest; 31 HttpSession session=req.getSession(); 32 HttpServletResponse resp=(HttpServletResponse) servletresponse; 33 34 String url=req.getRequestURI(); 35 System.out.println(url); 36 if(!url.equals("/FlyPig")&&!url.equals("/FlyPig/login.jsp")){ 37 if(session.getAttribute("username")==null||session.getAttribute("username")==""){ 38 resp.sendRedirect("login.jsp"); 39 return ; 40 } 41 } 42 43 44 filterchain.doFilter(servletrequest, servletresponse); 45 } 46 47 public void destroy() { 48 } 49 }
补充:过滤器在请求前可以执行一次,请求后也可以执行:
//前处理 filterchain.doFilter(servletrequest, servletresponse); //后处理
也就是说在请求完成并且页面载入完成之后会执行后处理,从Java的语法来看放行之后方法没有retur,所以方法会继续执行。用于在处理所有请求的一次请求前和请求后处理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix