java filter过滤器_JavaWeb之 Filter(过滤器)

FIlter作用

过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。

当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。

其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码。

FIlter实现步骤

1.创建AFilter类实现javax.servlet.Filter接口

2.添加@WebFilter("/*")注解或者添加web.xml配置

AFilter

com.yuan.web.filter.AFilter

AFilter

/*

3.已经完成了

4.@WebFilter参数说明

编写简单一个Filter

package com.yuan.web.filter;

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import java.io.IOException;

@WebFilter("/*")

public class AFilter implements Filter {

/*** 初始化 创建后立即执行** @param filterConfig* @throws ServletException*/

@Override

public void init(FilterConfig filterConfig) throws ServletException {

System.out.println("AFilter出生啦");

}

/*** 每次过滤时都会执行** @param request* @param response* @param chain* @throws IOException* @throws ServletException*/

@Override

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

//访问时过滤 System.out.println("拦截!留下买路财");

//放行 chain.doFilter(request,response);

//响应时过滤 System.out.println("你又~回来啦?");

}

/*** 销毁前立即执行*/

@Override

public void destroy() {

System.out.println("AFilter去世啦");

}

}

FIlter说明Filter是单例的!

void init(FilterConfig)

创建之后,马上执行;Filter会在服务器启动时就创建!

FilterConfig-->与ServletConfig相似获取初始化参数:getInitParameter()

获取过滤器名称:getFilterName()

获取appliction:getServletContext()

void destory()

销毁之前执行!在服务器关闭时销毁

void doFilter(ServletRequest,ServletResponse,FilterChain)

每次过滤时都会执行

FilterChaindoFilter(ServletRequest, ServletResponse):放行!

执行目标资源就相当于调用了目标Servlet的service()方法!,或是执行下一个过滤器!如果没有下一个过滤器那么执行的是目标资源,如果有,那么就执行下一个过滤器!

多个过滤器执行顺序

1.的配置顺序决定了过滤器的执行顺序!

2.过滤时遵守先进先出

过滤器的N种拦截方式

REQUEST默认的!

FORWARD

INCLUDE

ERROR

@WebFilter(value = "/CServlet",

dispatcherTypes = {

DispatcherType.ASYNC,//异步 DispatcherType.ERROR,//错误 DispatcherType.FORWARD,//转发 DispatcherType.INCLUDE,//包含 DispatcherType.REQUEST})//请求public class AFilter implements Filter {}

应用场景

执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作

通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;

在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理;

设置目标资源/:所有资源

/xx/xx/ :xx/xx/下的所有资源

/aaa/bbb/ccc/Servlet:具体AServlet

案例

案例一【分ip统计网站的访问次数】

分析

统计工作需要在所有资源之前都执行,那么就可以放到Filter中了。

我们这个过滤器不做拦截操作!因为我们只是用来做统计的。

用什么东西来装载统计的数据。Map

整个网站只需要一个Map即可!

Map什么时候创建(使用ServletContextListener,在服务器启动时完成创建,并只在到ServletContext中),Map保存到哪里!(Map保存到ServletContext中!!!)

Map需要在Filter中用来保存数据

Map需要在页面使用,打印Map中的数据

代码实现

Listener

package com.yuan.web.listener;

import javax.servlet.ServletContext;

import javax.servlet.ServletContextEvent;

import javax.servlet.ServletContextListener;

import javax.servlet.annotation.WebListener;

import java.util.HashMap;

import java.util.LinkedHashMap;

@WebListener()

public class CListener implements ServletContextListener {

@Override

public void contextInitialized(ServletContextEvent sce) {

//1.创建ServletContext ServletContext application = sce.getServletContext();

//2.Map HashMap ipMap = new LinkedHashMap<>();

//3.把Map保存到ServletContext中 application.setAttribute("ipMap",ipMap);

}

@Override

public void contextDestroyed(ServletContextEvent sce) {

}

}

Filter

package com.yuan.web.filter;

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import java.io.IOException;

import java.util.LinkedHashMap;

/*** @author Yuan-9826*/

@WebFilter("/*")

public class CFilter implements Filter {

@Override

public void init(FilterConfig config) throws ServletException {

}

@Override

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {

//1.得到ServletContext中的IPMap ServletContext application = req.getServletContext();

//2.获取客户端IP String IP = req.getRemoteAddr();

//3.获得并操作Map LinkedHashMap ipMap = (LinkedHashMap) application.getAttribute("ipMap");

if (ipMap.containsKey(IP)) {

int ipValue = ipMap.get(IP);

ipMap.put(IP, ++ipValue);

System.out.println("添加了map IP = " + IP + "次数 = " + ipValue);

} else {

ipMap.put(IP, 1);

System.out.println("添加了map IP = " + IP + "次数 = " + 1);

}

application.setAttribute("ipMap", ipMap);

//4.放行 chain.doFilter(req, resp);

}

@Override

public void destroy() {

}

}

jsp

显示IP

${applicationScope.ipMap }

IP地址次数
${entry.key}${entry.value}

效果

image.png

案例二【粗粒度权限过滤】

只有文字描述步骤

游客、会员、管理员三个粒度

1.创建一个Fileter,过滤会员下的资源访问,这是保安1号 ,doFilter里检查session中权限标记,第一道检查工序,不是管理员=> 放行,第二道检查工序,不是会员=> 打回到登录/注册页面,如果是会员就放行!

2.创建一个Fileter,过滤管理员下的资源访问,这是保安2号 ,doFilter里检查session中权限标记,查看是不是管理员,不是管理员=>打回到登录/注册页面,如果是管理员就放行!

案例三【解决全站字符乱码(POST和GET中文编码问题)】

工具类

package com.yuan.encoding;

import java.io.UnsupportedEncodingException;

/*** 编码转换*/

public class EncodeingUtils {

/*** iso-8859-1 转成 utf-8** @param code* @return*/

public static String i2u(String code) {

try {

return new String(code.getBytes("iso-8859-1"), "utf-8");

} catch (UnsupportedEncodingException e) {

new RuntimeException("转码失败");

return null;

}

}

/*** iso-8859-1 转成 gbk** @param code* @return*/

public static String i2g(String code) {

try {

return new String(code.getBytes("iso-8859-1"), "gbk");

} catch (UnsupportedEncodingException e) {

new RuntimeException("转码失败");

return null;

}

}

/*** gbk 转成 iso-8859-1** @param code* @return*/

public static String g2i(String code) {

try {

return new String(code.getBytes("gbk"), "iso-8859-1");

} catch (UnsupportedEncodingException e) {

new RuntimeException("转码失败");

return null;

}

}

/*** gbk 转成 utf-8** @param code* @return*/

public static String g2u(String code) {

try {

return new String(code.getBytes("gbk"), "utf-8");

} catch (UnsupportedEncodingException e) {

new RuntimeException("转码失败");

return null;

}

}

/*** utf-8 转成 iso-8859-1** @param code* @return*/

public static String u2i(String code) {

try {

return new String(code.getBytes("utf-8"), "iso-8859-1");

} catch (UnsupportedEncodingException e) {

new RuntimeException("转码失败");

return null;

}

}

/*** utf-8 转成 gbk** @param code* @return*/

public static String u2g(String code) {

try {

return new String(code.getBytes("utf-8"), "gbk");

} catch (UnsupportedEncodingException e) {

new RuntimeException("转码失败");

return null;

}

}

}

package com.yuan.web.filter;

import com.yuan.encoding.EncodeingUtils;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

/*** 被掉包了的Request*/

public class HttpRequest extends HttpServletRequestWrapper {

private HttpServletRequest request;

public HttpRequest(HttpServletRequest request) {

super(request);

this.request = request;

}

/*** 处理编码问题* @param name* @return*/

@Override

public String getParameter(String name) {

String value = request.getParameter(name);

return EncodeingUtils.i2u(value);

}

}

package com.yuan.web.filter;

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;

/*** 乱码过滤器*/

public class EncodingFilter implements Filter {

private String GET = "GET";

private String POST = "POST";

private Integer version = 8;

@Override

public void init(FilterConfig filterConfig) throws ServletException {

System.out.println("编码过滤器执行");

final String version = filterConfig.getInitParameter("tomcatVersion");

this.version = Integer.valueOf(version);

System.out.println(version);

}

@Override

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

//处理post请求编码问题 req.setCharacterEncoding("utf-8");

/*** tomcat8之后自己做了get请求的处理*/

if (version < 8) {

System.out.println("Tomcat版本低于8 做GET请求处理");

//掉包request 和 HttpServletRequest HttpServletRequest request = (HttpServletRequest) req;

//放行时 if (GET.equals(request.getMethod())) {

HttpRequest hr = new HttpRequest(request);

chain.doFilter(hr, res);

} else if (POST.equals(request.getMethod())) {

chain.doFilter(req, res);

}

}else {

chain.doFilter(req, res);

System.out.println("Tomcat版本不低于8 不做GET请求处理");

}

}

@Override

public void destroy() {

}

}

只要配置了这个过滤器 即可使用

encoding

com.yuan.web.filter.EncodingFilter

tomcatVersion

8

encoding

/*

案例四【页面静态化 改日补充】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值