↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

原文地址:http://t.csdn.cn/ZD88A

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理
通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理

大概流程图如下

应用场景:
  自动登录
  统一设置编码格式
  访问权限控制
  敏感字符过滤等

创建Filter

在Servlet中我们一般都会对request和response中的字符集编码进行配置,如果Servlet过多字符集编码发生变化时修改起码会很麻烦,这些通用的字符集编码配置等工作我们可以放到Filter中来实现。
下面我们来创建一个处理字符集编码的Filter。

右键包名—>new ---->Filter

输入过滤器名称,跟创建Servlet一样,这里我们直接使用 @WebFilter 注解,不再去web,xml中进行配置了。

创建完成后默认代码,可以看到,CharsetFilter实现了Filter接口,实现了3个方法。3个方法的作用已经在注释中写清楚了。

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException; @WebFilter(filterName = "CharsetFilter")
public class CharsetFilter implements Filter {
public void destroy() {
/*销毁时调用*/
} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
/*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/ chain.doFilter(req, resp);//交给下一个过滤器或servlet处理
} public void init(FilterConfig config) throws ServletException { /*初始化方法 接收一个FilterConfig类型的参数 该参数是对Filter的一些配置*/ } }

配置Filter

可配置的属性有这些

常用配置项
urlPatterns
配置要拦截的资源

以指定资源匹配。例如"/index.jsp"
以目录匹配。例如"/servlet/*"
以后缀名匹配,例如"*.jsp"
通配符,拦截所有web资源。"/*"
initParams
配置初始化参数,跟Servlet配置一样

例如

initParams = {
@WebInitParam(name = "key",value = "value")
}

dispatcherTypes
配置拦截的类型,可配置多个。默认为DispatcherType.REQUEST
例如

dispatcherTypes = {DispatcherType.ASYNC,DispatcherType.ERROR}

其中DispatcherType是个枚举类型,有下面几个值

FORWARD,//转发的
INCLUDE,//包含在页面的
REQUEST,//请求的
ASYNC,//异步的
ERROR;//出错的

下面我们来对CharsetFilter 代码进行一下修改

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException; @WebFilter(filterName = "CharsetFilter",
urlPatterns = "/*",/*通配符(*)表示对所有的web资源进行拦截*/
initParams = {
@WebInitParam(name = "charset", value = "utf-8")/*这里可以放一些初始化的参数*/
})
public class CharsetFilter implements Filter {
private String filterName;
private String charset; public void destroy() {
/*销毁时调用*/ System.out.println(filterName + "销毁");
} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
/*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
System.out.println(filterName + "doFilter()");
req.setCharacterEncoding(charset);
resp.setCharacterEncoding(charset);
chain.doFilter(req, resp);
} public void init(FilterConfig config) throws ServletException { /*初始化方法 接收一个FilterConfig类型的参数 该参数是对Filter的一些配置*/ filterName = config.getFilterName();
charset = config.getInitParameter("charset"); System.out.println("过滤器名称:" + filterName);
System.out.println("字符集编码:" + charset); } }

这样一个简单的字符集编码处理的过滤器就完成了
我们看看执行打印的结果

需要注意的是
过滤器是在服务器启动时就会创建的,只会创建一个实例,常驻内存,也就是说服务器一启动就会执行Filter的init(FilterConfig config)方法.
当Filter被移除或服务器正常关闭时,会执行destroy方法

多个Filter的执行顺序

在我们的请求到达Servle之间是可以经过多个Filter的,一般来说,建议Filter之间不要有关联,各自处理各自的逻辑即可。这样,我们也无需关心执行顺序问题。
如果一定要确保执行顺序,就要对配置进行修改了,执行顺序如下

1.在web.xml中,filter执行顺序跟<filter-mapping>的顺序有关,先声明的先执行
2.使用注解配置的话,filter的执行顺序跟名称的字母顺序有关,例如AFilter会比BFilter先执行
3.如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter

我们写个小例子看一下

新建3个Filter,加上之前的CharsetFilter一共四个

其中CharsetFilter和ABFilter是通过注解声明的

CharsetFilter注解配置

@WebFilter(filterName = "CharsetFilter",
urlPatterns = "/*",/*通配符(*)表示对所有的web资源进行拦截*/
initParams = {
@WebInitParam(name = "charset", value = "utf-8")/*这里可以放一些初始化的参数*/
})

ABFilter

@WebFilter(filterName = "ABFilter",urlPatterns = "/*")

AFilter和BFilter是在web.xml配置的。
执行顺序跟<filter>的顺序无关
<filter-mapping>的顺序才决定执行顺序

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
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">
<filter>
<filter-name>AFilter</filter-name>
<filter-class>filter.AFilter</filter-class>
</filter>
<filter>
<filter-name>BFilter</filter-name>
<filter-class>filter.BFilter</filter-class>
</filter> <!--这里BFilter在AFilter之前-->
<filter-mapping>
<filter-name>BFilter</filter-name>
<url-pattern>/filter.jsp</url-pattern>
</filter-mapping> <filter-mapping>
<filter-name>AFilter</filter-name>
<url-pattern>/filter.jsp</url-pattern>
</filter-mapping>
</web-app>

每个Filter添加了打印语句,如下
以ABFilter为例

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException; @WebFilter(filterName = "ABFilter",urlPatterns = "/*")
public class ABFilter implements Filter {
private String filterName; public void destroy() {
} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println(filterName + " doFilter()");
chain.doFilter(req, resp);
} public void init(FilterConfig config) throws ServletException {
filterName= config.getFilterName();
System.out.println("过滤器名称:" + filterName +" init");
} }

下面我们来访问filter.jsp看看打印结果

可以看到,执行结果符合预期。
BFilter和AFilter是在web.xml中声明的,且BFilter的<filter-mapping>在前,故BFilter在AFilter之前执行。
ABFilter和CharsetFilter是通过注解声明的,故他俩在BFilter和AFilter之后执行,但是ABFilter的名称以A开头,故在CharsetFilter之前执行

访问权限控制小例子

下面我们写一个访问控制权限控制的小例子。
我们在浏览一些网站经常有这个情况,没有登录时是不允许我们访其主页的,只有登录过后才能访问。
下面我们就用Filter简单实现一下。

需求分析

  1. 登录时将登录的账号密码保存到cookie中,下次访问时携带账号和密码,过滤器中进行校验
  2. 用户没有登录直接访问主页时,要跳转到登录页面
  3. 登录过滤器不对登录页面进行过滤

我们先来看一下项目结构

这里主要看一下LoginFilter的代码

我们在LoginFilter中对非登录页面的其他jsp都会进行过滤,判断cookie中是否携带了account和pwd。
如果有这两个数据表示之前登录过,那么对数据进行校验,正确的话就进行下一个操作。
否则的话,跳转到登录界面

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebFilter(filterName = "LoginFilter", urlPatterns = "*.jsp", dispatcherTypes = {})
public class LoginFilter implements Filter {
public void destroy() {
} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { System.out.println("LoginFilter doFilter"); HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp; String url = request.getRequestURI(); System.out.println("请求的url:" + url);
/*登录页面不需要过滤*/ int idx = url.lastIndexOf("/");
String endWith = url.substring(idx + 1); if (!endWith.equals("login.jsp")) {
/*不是登录页面 进行拦截处理*/ System.out.println("不是登录页面,进行拦截处理"); if (!isLogin(request)) {
System.out.println("没有登录过或者账号密码错误,跳转到登录界面");
response.sendRedirect("login.jsp");
} else {
System.out.println("已经登录,进行下一步");
chain.doFilter(req, resp);
} } else { System.out.println("是登录页面,不进行拦截处理");
chain.doFilter(req, resp);
} } private boolean isLogin(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); String account = "";
String pwd = ""; if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("account")) {
account = cookie.getValue();
} else if (cookie.getName().equals("pwd")) {
pwd = cookie.getValue();
}
}
} if (account.equals("") || pwd.equals("")) {
return false; } else if (account.equals("yzq") && pwd.equals("123")) {
return true;
} return false;
} public void init(FilterConfig config) throws ServletException {
System.out.println("LoginFilter init");
} }

执行效果

可以看到,我们在没有登录的情况下直接去访问index.jsp页面时会自动跳转到登录页面,在登录成功后,再次直接访问index页面则可以访问。

原文地址:http://t.csdn.cn/ZD88A

java过滤器的写法的更多相关文章

  1. cookie、session和java过滤器

    基础知识理解: cookie.session和过滤器通常都是用在web应用中,cookie和session用来保存一定的数据,过滤器Filter则是在浏览器发出请求之后,而后台执行特定的请求之前发生一 ...

  2. Java 过滤器的作用

    Servlet API 非常久曾经就已成为企业应用开发的基石,而 Servlet 过滤器则是对 J2EE 家族的相对较新的补充.在 J2EE 探索者 系列文章的最后一篇中,作者 Kyle Gabhar ...

  3. Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求

    Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求 >>>>>>>>>>>>>>&g ...

  4. java过滤器(过滤器排序)

    java过滤器(过滤器排序) 定义过滤器顺序是很简单的:匹配请求的过滤器将按照它们出现在部署描述符或者编程式配置中的顺序添加到过滤器链中(记住,如果同时再部署描述符或者编程式配置中设置了一些过滤器,那 ...

  5. Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,java 判断请求是不是ajax请求

    Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,java 判断请求是不是ajax请求   Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求 java ...

  6. java 过滤器(理解二)

    request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf ...

  7. java 过滤器(Filter)与springMVC 拦截器(interceptor)的实现案例

    java 过滤器Filter: package com.sun.test.aircraft.filter;import javax.servlet.*;import java.io.IOExcepti ...

  8. Java 链式写法

    Java链式写法,子类继承父类的属性,也可以返回子类的对象,只是需要重写基类的Set方法 public class MyLS { public static void main(String[] ar ...

  9. Java链式写法

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11613067.html Java 链式写法:详细看代码 package chain; /** ...

随机推荐

  1. STC8H开发(十): SPI驱动Nokia5110 LCD(PCD8544)

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  2. .NET Core 企业微信回调配置

    1.配置API接收 2.下载加密解密库 地址:https://developer.work.weixin.qq.com/devtool/introduce?id=36388,也可以复制下面的代码 2. ...

  3. 【Redis】Redis Cluster初始化及PING消息的发送

    Cluster消息类型定义 #define CLUSTERMSG_TYPE_PING 0 /* Ping消息类型,节点间进行通信交换信息的消息 */ #define CLUSTERMSG_TYPE_P ...

  4. rpm 系 linux 系统中 repo 文件中的 $release 到底等于多少?

    rpm 系 linux 系统中 repo 文件中的 $release 到底等于多少? 结论 对于 8 来说,通过以下命令 #/usr/libexec/platform-python -c 'impor ...

  5. [WUSTCTF2020]朴实无华-1

    1.打开连接只有如下界面:    2.用bp抓包分析包内数据,未发现有用的信息:    3.进行目录扫描,获得robots.txt文件并进行访问:       4.访问/fAke_f1agggg.ph ...

  6. 你真的了解git的分支管理跟其他概念吗?

    现在前端要学的只是太多了,你是不是有时会有这个想法,如果我有两个大脑.一个学Vue,一个学React,然后到最后把两个大脑学的知识再合并在一起,这样就能省时间了. 哈哈,这个好像不能实现.现实点吧!年 ...

  7. ms12-020漏洞

    一.环境说明 kali linux windows 7 sp1 二.ms12-020漏洞利用 msf5 exploit(windows/browser/ms10_002_aurora) > se ...

  8. 学习C4C的视频分享

  9. NC20012 [HEOI2014]南园满地堆轻絮

    NC20012 [HEOI2014]南园满地堆轻絮 题目 题目描述 小 Z 是 ZRP(Zombies' Republic of Poetry,僵尸诗歌共和国)的一名诗歌爱好者,最近他研究起了诗词音律 ...

  10. # Vue3 toRef 和 toRefs 函数

    Vue3 toRef 和 toRefs 函数 上一篇博文介绍了 vue3 里面的 ref 函数和 reactive 函数,实现响应式数据,今天主要来说一下 toRef 函数和 toRefs 函数的基本 ...