`
huangyongxing310
  • 浏览: 490327 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

Spring filter的用法

阅读更多
Spring filter的用法

1.Filter技术是servlet 2.3新增加的功能。它能够对Servlet容器的请求和响应对象进行检查和修改。
2.过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。
3.Filter本身并不生成请求和响应对象,只是提供过滤功能。
4.Filter能够在Servlet被调用之前检查Request对象,并修改Request Header和Request内容;在Servlet被调用之后检查Response对象,修改Response Header和Response的内容。
5.所有的过滤器都必须实现Filter接口
6.web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter



Filter的执行流程:
1.执行第一个过滤器的chain.doFilter()之前的代码-->
2.第二个过滤器的chain.doFilter()之前的代码-->……-->第n个过滤器的chain.doFilter()之前的代码-->
3.所请求servlet的service()方法中的代码-->所请求servlet的doGet()或doPost()方法中的代码-->
4.第n个过滤器的chain.doFilter()之后的代码-->……-->
5.第二个过滤器的chain.doFilter()之后的代码-->第一个过滤器的chain.doFilter()之后的代码。



Filter生命周期的四个阶段
(1)实例化:Web容器在部署Web应用程序时对所有过滤器进行实例化。Web容器回调它的无参构造方法。
(2)初始化:实例化完成之后,马上进行初始化工作。Web容器回调init()方法。
(3)过滤:请求路径匹配过滤器的URL映射时。Web容器回调doFilter()方法--主要的工作方法。
(4)销毁: Web容器在卸载Web应用程序前,Web容器回调destroy()方法。



例子:
1.编写java类实现Filter接口,并实现其doFilter方法。
public class FilterTest implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		String username = filterConfig.getInitParameter("username");
		System.out.println("init username == " + username);

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 转换成实例的请求和响应对象
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;

		System.out.println("doFilter before");
		chain.doFilter(req, resp);
		System.out.println("doFilter after");
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("FilterTest destroy == ");
	}
}



2.在web. xml中配置过滤器(多个filter就是多个复制)
<filter>
	<filter-name>filterTest</filter-name>
	<filter-class>com.proserver.common.controller.Test.filter.FilterTest</filter-class>
	<init-param>
		<param-name>userName</param-name>
		<param-value>HelloWorld</param-value>
	</init-param>
</filter>

<filter-mapping>
	<filter-name>filterTest</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
	<filter-name>filterTest3</filter-name>
	<filter-class>com.proserver.common.controller.Test.filter.FilterTest3</filter-class>
	<init-param>
		<param-name>userName</param-name>
		<param-value>HelloWorld</param-value>
	</init-param>
</filter>

<filter-mapping>
	<filter-name>filterTest3</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
	<filter-name>filterTest2</filter-name>
	<filter-class>com.proserver.common.controller.Test.filter.FilterTest2</filter-class>
	<init-param>
		<param-name>userName</param-name>
		<param-value>HelloWorld</param-value>
	</init-param>
</filter>

<filter-mapping>
	<filter-name>filterTest2</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>



1.filter定义过滤器的类
2.filter-mapping定义过滤器的的匹配规则(url-pattern匹配规则)
3.init-param为配置参数,可从FilterConfig中得到
4.servlet-name指定过滤器所拦截的Servlet名称。(过滤器规则),<servlet-name>元素给出的Servlet名字必须是 在<servlet>元素中声明过的Servlet的名字。
5.url-pattern指定过滤器规则,正则表达式。加了/表示绝对路径http://localhost:8080/ ,没有加 / 表示的是相对路径
6.dispatcher指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。(就是请求的来源)
(1)REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
(2)INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
(3)FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
(4)ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。



HttpServletRequestWrapper、HttpServletResponseWrapper,HttpSessionWrapper 用法
1.用于filter操作请求和回应包信息的

例子:
package com.proserver.common.controller.Test.filter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class WrapperedResponse extends HttpServletResponseWrapper {

	private ByteArrayOutputStream buffer = null;
	private ServletOutputStream out = null;
	private PrintWriter writer = null;

	public WrapperedResponse(HttpServletResponse resp) throws IOException {
		super(resp);
		buffer = new ByteArrayOutputStream();// 真正存储数据的流
		out = new WapperedOutputStream(buffer);
		writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding()));
	}

	/** 重载父类获取outputstream的方法 */
	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		return out;
	}

	/** 重载父类获取writer的方法 */
	@Override
	public PrintWriter getWriter() throws UnsupportedEncodingException {
		return writer;
	}

	/** 重载父类获取flushBuffer的方法 */
	@Override
	public void flushBuffer() throws IOException {
		if (out != null) {
			out.flush();
		}
		if (writer != null) {
			writer.flush();
		}
	}

	@Override
	public void reset() {
		buffer.reset();
	}

	/** 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 */
	public byte[] getResponseData() throws IOException {
		flushBuffer();
		return buffer.toByteArray();
	}

	/** 内部类,对ServletOutputStream进行包装 */
	private class WapperedOutputStream extends ServletOutputStream {
		private ByteArrayOutputStream bos = null;

		public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
			bos = stream;
		}

		@Override
		public void write(int b) throws IOException {
			bos.write(b);
		}

		@Override
		public void write(byte[] b) throws IOException {
			bos.write(b, 0, b.length);
		}
	}
}


package com.proserver.common.controller.Test.filter;

import java.io.CharArrayWriter;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class ResponseWrapper extends HttpServletResponseWrapper{
	private PrintWriter cachedWriter;
	private CharArrayWriter bufferedWriter;

	public ResponseWrapper(HttpServletResponse response) {
		super(response);
		// 这个是我们保存返回结果的地方
		bufferedWriter = new CharArrayWriter();
		// 这个是包装PrintWriter的,让所有结果通过这个PrintWriter写入到bufferedWriter中
		cachedWriter = new PrintWriter(bufferedWriter);
	}

	@Override
	public PrintWriter getWriter() {
		return cachedWriter;
	}

	/**
	 * 获取原始的HTML页面内容。
	 * @return
	 */
	public String getResult() {
		return bufferedWriter.toString();
	}
}



package com.proserver.common.controller.Test.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FilterTest2 implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		String username = filterConfig.getInitParameter("username");
		System.out.println("FilterTest2 init username == " + username);

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 转换成实例的请求和响应对象
		 HttpServletRequest req = (HttpServletRequest) request;
		 HttpServletResponse resp = (HttpServletResponse) response;

		 System.out.println("begin filter invoke!");
		 WrapperedResponse wrapResponse = new WrapperedResponse((HttpServletResponse)response);

		 chain.doFilter(req, wrapResponse);
		 byte[] data = wrapResponse.getResponseData();
		 System.out.println("原始数据: " + new String(data));

		 String tempData = new String("jack xing xing");
		 ServletOutputStream out = resp.getOutputStream();
		 resp.setContentLength(tempData.getBytes().length);//一定要更改长度
		 out.write(tempData.getBytes());
		 out.flush();
		 System.out.println("end filter invoke!");
	}

	@Override
	public void destroy() {
		System.out.println("FilterTest2 FilterTest destroy == ");
	}
}


http://zhangzhaoaaa.iteye.com/blog/1853787
分享到:
评论

相关推荐

    springsecurity2 自定义filter实现

    - 使用`http.addFilterBefore/After`方法将自定义Filter添加到过滤器链中,决定它在哪些过滤器之前或之后执行。 3. **配置AuthenticationManager**: - 自定义Filter需要一个`AuthenticationManager`实例来处理...

    spring-boot 过滤器 filter

    二、Spring Boot中使用Filter 在Spring Boot中,我们可以通过以下两种方式注册Filter: 1. 实现`javax.servlet.Filter`接口:创建一个类,实现`doFilter()`方法,然后在`WebApplicationInitializer`或`...

    spring MVC所需jar包和filter的配置

    - 编写自定义Filter:扩展`javax.servlet.Filter`类,实现`doFilter`方法,然后在`web.xml`中配置。 3. **配置步骤**: - 将所有必需的jar包放入项目的`WEB-INF/lib`目录下。 - 在`web.xml`文件中配置Filter,...

    cors-filter-1.7.jar spring解决跨域问题 java

    本篇将详细讲解如何利用Spring解决跨域问题,以及如何使用`cors-filter-1.7.jar`和`java-property-utils-1.9.1.jar`这两个库来辅助实现。 一、Spring解决跨域问题的基本原理 1. CORS定义:跨域是指浏览器遵循同源...

    spring boot 拦截器拦截/Filter 过滤session案例

    在本文中,我们将深入探讨如何在Spring Boot应用中使用拦截器(Interceptor)和过滤器(Filter)来处理用户的登录session。这两个组件都是Spring框架的重要部分,它们在处理HTTP请求和响应时发挥着关键作用。 首先...

    springsecurity使用配置详解

    在本文中,我们将深入探讨Spring Security的配置及其在实际应用中的使用。 首先,Spring Security的核心概念包括用户、角色、权限和访问控制。它提供了一种机制来验证用户身份(身份验证),并决定用户是否可以访问...

    Spring LDAP 简单使用

    在开始使用Spring LDAP之前,你需要在项目中添加相关的依赖。如果你使用的是Maven,可以在pom.xml文件中添加如下依赖: ```xml &lt;groupId&gt;org.springframework.ldap &lt;artifactId&gt;spring-ldap-core 版本号 ``` 请...

    精彩:Spring Security 演讲PPT

    &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt; &lt;url-pattern&gt;/* &lt;/filter-mapping...

    spring-web-5.2.3.RELEASE和spring-webmvc-5.2.3.RELEASE

    此外,它还提供了对Servlet、Filter和Listener的集成,使得Spring能够与任何Servlet容器(如Tomcat、Jetty)无缝协作。WebSocket API的集成则允许开发者创建实时双向通信的应用。 Spring Web MVC模块(spring-web...

    springsecurity学习笔记

    - 使用@Secured和@PreAuthorize注解进行方法级别的访问控制。 - 配置和使用RememberMe服务以实现自动登录功能。 - 实现CSRF防护,理解CSRFTokenRepository的工作原理。 - 学习如何集成Spring Security与OAuth2,为...

    Spring Boot集群管理工具KafkaAdminClient使用方法解析

    Spring Boot 集群管理工具 KafkaAdminClient 使用方法解析 KafkaAdminClient 是 Spring Boot 集群管理工具中的一部分,主要用于管理和检视 Kafka 集群中的Topic、Broker、ACL 等对象。下面将详细介绍 Kafka...

    spring-security 官方文档 中文版

    Spring Security 的设计目标是为应用程序提供一个高度可配置且强大的安全性框架,同时保持易于集成和使用。 **1.2 历史** Spring Security 最初是由 Luke Taylor 和 Ray Ryan 开发的名为 Acegi Security 的项目,...

    Spring在web中使用

    6. **Filter**:Spring还提供了一些Filter,如CharacterEncodingFilter用于设置字符编码,HttpPutFormContentFilter帮助处理PUT请求的表单数据。 7. **WebSocket支持**:自Spring 4.0开始,Spring Web模块包含了对...

    特殊情况(ActionForm,Servlet, Filter, Listener)下Spring如何注入对象

    2. **Filter**: 同样,可以在Filter的init()方法中获取ApplicationContext,或者通过ServletContextAware接口,将Spring上下文注册到ServletContext,然后在doFilter()方法中使用。 3. **Listener**: 在监听器的...

    狂神spring-security静态资源.zip

    - 使用`@Secured`或`@PreAuthorize`注解:在Controller方法上使用这些注解,根据方法级别的权限控制静态资源的访问。 4. **Web安全配置** Spring Security的配置通常在Java配置类中完成,通过`...

    spring security 3 demos

    3. **过滤器链(Filter Chain)**:Spring Security 使用一系列过滤器来处理HTTP请求,如`DelegatingFilterProxy`,`FilterSecurityInterceptor`等。通过配置`http`元素,你可以定制过滤器链以实现特定的安全需求。 ...

    过滤器 spring4.1+jdk1.7版本

    总结,这个"过滤器 spring4.1+jdk1.7版本"的压缩包提供了一个学习和实践Spring Filter和Interceptor的平台,通过分析和运行其中的代码,开发者可以深入理解这两种机制在Java Web开发中的应用和重要性。同时,对于...

    Spring Security 把授权信息写入数据库

    目标是将现有的Acegi配置迁移到Spring Security 2.0,同时保持使用数据库作为认证和授权数据源的能力,避免依赖XML配置文件。 24.3. 实现步骤 要实现这一目标,首先需要将Spring Security 2.0的库文件添加到项目的...

    Spring集成SpringSecurity依赖包

    2. **配置Spring Security**:创建一个配置类,继承自`WebSecurityConfigurerAdapter`,并覆盖其方法以定制安全行为。例如,你可以定义哪些URL需要保护,以及如何进行认证和授权。 3. **定义认证和授权策略**:实现...

    spring-security Jar包

    Spring Security 3.0.5.RELEASE版本可能使用的是XML配置,而在后续版本中,更倾向于使用Java配置API,使得配置更加直观和简洁。 10. **安全性测试**:Spring Security 提供了专门的测试支持,帮助开发者编写单元...

Global site tag (gtag.js) - Google Analytics