过滤器
在创建一个java类的时候,要实现Filter的一个接口,注意:要选择javax.servlet的
一、过滤器的实现
1.@WebFilter("/s01") 配置拦截的资源路径
2.doFilter() 方法中需要设置放行,否则请求无法到达资源 filterChain.doFilter(servletRequest,servletResponse);
3.如果是过滤器链(有多个过滤器Filter.java),则先配置的先执行(首字母在前的先执行);响应时,顺序相反。
package com.xxxx.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; /** * 拦截路径为s01的资源 */ @WebFilter("/s01") //@WebFilter("/*")//拦截所有的请求资源路径 public class Filter01 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("Filter01 init.."); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("s01正在过滤..."); //一定要加上放行资源,不然请求无法到达资源 filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { System.out.println("Filter01 destory..."); } }
二、乱码问题
1.POST请求:任意版本的Tomcat都是会乱码的
解决:request.setCharacterEncoding("UTF-8");
2.GET请求:只有Tomcat7及以下的版本才会出现乱码问题
解决:new String(request.getParameter("参数名").getBytes("ISO-8859-1"),"UTF-8");
也可以直接拷入下面的过滤器(重写getParameter()方法)
package com.xxxx.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; @WebFilter("/*") public class AEncodingFilter implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { //基于HTTP HttpServletRequest request = (HttpServletRequest) arg0; HttpServletResponse response = (HttpServletResponse) arg1; //处理请求乱码(处理POST请求) request.setCharacterEncoding("UTF-8"); //处理GET请求 String method = request.getMethod(); //如果是GET请求(不区分大小写) if("GET".equalsIgnoreCase(method)){ //获取服务器版本 Apache Tomcat/9.0.68 String serverInfo = request.getServletContext().getServerInfo(); //获取具体的版本号,获取'/'后面'.'前面的1位数字(注意只能取一个数字,如果是10的话就不行了) String versionStr = serverInfo.substring(serverInfo.indexOf("/")+1,serverInfo.indexOf(".")); //判断服务器版本是否小于8 if(Integer.parseInt(versionStr)<8){ //定义一个内部类继承HttpServletRequest对象像 HttpServletRequest myRequest = new MyWapper(request); //放行资源 chain.doFilter(myRequest,response); return; } } chain.doFilter(request,response); return; } class MyWapper extends HttpServletRequestWrapper { // 定义HttpServletRequest对象,用来提升带参构造器中的request private HttpServletRequest request; public MyWapper(HttpServletRequest request) { super(request); this.request = request; // 提升作用域 } //重写getParameter()方法 @Override public String getParameter(String name) { String value = request.getParameter(name); if (value != null && !"".equals((value.trim()))) { try { value = new String(value.getBytes("ISO-8859-1"), "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return value; } } }
三、实例
例子:在用户没有登录的情况下,是无法查询到购物车的信息的,这时候需要拦截下来,有些是登录前不能被访问到的。
1.下面这个代码,并不能实现,访问页面的时候,会出现下面图片这一种情况(重定向次数过多)
* 因为login.jsp也是一个请求,也会被拦截下来,所以又会继续进入login.jsp页面但是又会被拦截,就会出现重定向次数过多的问题
* 需要一个登录、注册入口,需要他们放行
* 所以,需要放行指定的页面(无需登录即可访问的页面,如登录页面,注册页面)
* 做法:获取请求的路径
package com.xxxx.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 非法访问的拦截 * 拦截资源:所有资源
* 需要放行的资源:
* 1.放行指定页面(无需登录即可访问的页面,例如:登录注册页面)
* 2.放行静态资源(image、js、css文件等)
*/ @WebFilter("/*")//拦截所有资源 public class LoginAccessFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); } @Override public void destroy() { Filter.super.destroy(); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //基于Http请求,就可以用Http的相关非法,如request.XXXXXX HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; //当用户未登录时候,拦截跳转到登录页面 response.sendRedirect("login.jsp"); } }
2.修改后的代码
@WebFilter("/*")//拦截所有资源 public class LoginAccessFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); } @Override public void destroy() { Filter.super.destroy(); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //基于Http请求,就可以用Http的相关非法,如request.XXXXXX HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; //获取请求的路径 String uri = request.getRequestURI(); if(uri.contains("/login.jsp")){ filterChain.doFilter(request,response); return; } //当用户未登录时候,拦截跳转到登录页面 response.sendRedirect("login.jsp"); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!