20160418javaweb之 Filter过滤器
Servlet规范中 Servlet Listener Filter
1.开发Filter
想要开发一个过滤器需要如下两个步骤:
(1)写一个类实现特定的接口Filter
生命周期:当服务器启动时,web应用加载后,立即创建这个web应用中的所有的过滤器,过滤器创建出来后立即调用init方法执行初始化的操作.
创建出来后一直驻留在内存中为后续的拦截进行服务.每次拦截到请求后都会导致doFilter方法执行.
在服务器关闭或web应用被移除出容器时,随着web应用的销毁过滤器对象销毁.销毁之前调用destory方法执行善后工作.
init
FilterConfig:代表web.xml中对当前过滤器的配置信息
~获取ServletContext对象
~获取初始化信息
getInitParameter
getInitParameterNames
doFilter
request
response
FilterChain:
代表过滤器链的对象.
一个资源可能被多个过滤器所拦截到,拦截的顺序和过滤器在web.xml中filter-mapping的配置顺序相同.
所有对当前资源访问进行拦截的过滤器按照拦截顺序就组成了一个过滤器链.这个过滤器链的最后一个节点是要访问的资源.
Filter中调用FilterChain提供了doFilter方法,这个方法一旦被调用就表明当前过滤器没有问题了,请执行过滤器链的下一个节点.如果下一个节点是资源则直接执行了资源
destory
(2)在web.xml中注册一下过滤器
<filter>
<filter-name>Demo1Filter</filter-name> -- 给过滤器起一个名字
<filter-class>com.itheima.filter.Demo1Filter</filter-class> -- 过滤器的处理类
<init-param>--可以配置当前过滤器的初始化信息,可以配置多个,在Filter中利用FilterConfig对象来获取
<param-name>name1</param-name>
<param-value>value1</param-value>
</init-param>
</filter>
<filter-mapping> -- 一个Filter可以配置多个filter-mapping
<filter-name>Demo1Filter</filter-name>
<url-pattern>/servlet/Demo1Servlet</url-pattern> -- 一个Filtermapping中可以配置多个url-partten,这个url-partten的写法和servlet-mapping中的写法相同
<url-pattern>/servlet/*</url-pattern>
<url-pattern>/*</url-pattern>
<url-pattern>*.do</url-pattern>
<servlet-name>Demo3Servlet</servlet-name>
--也可以配置多个servlet-name,其中填入servlet的名字明确的通知要拦截哪个名字的Servlet
<dispatcher>REQUEST</dispatcher>
--配置拦截哪种方式的对资源的访问可以是REQUEST/FORWARD/INCLUDE/ERROR四个值之中的一个,可以配置多个dispatcher,如果一个都不配则默认是REQUEST
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
3、客户端访问被拦截目标资源之前,服务器调用Filter的doFilter方法 ,执行过滤
4、Filter的doFilter方法中传入 FilterChain, 如果调用FilterChain的doFilter 就会执行目标资源,否则目标资源不会执行
chain.doFilter(request, response);
FilterChain
在客户端访问服务器web资源时,服务器端为一个web资源,配置多个过滤器拦截 ,这多个过滤器,就会组成过滤器链 FilterChain, 调用FilterChain的doFilter 表示要执行过滤器链下一个资源,如果当前过滤器已经是链上最后一个过滤器,就会执行目标资源
* web服务器根据Filter在web.xml文件中的注册顺序<mapping>,决定先调用哪个Filter
Filter生命周期 init(FilterConfig) doFilter(request,response,filterChain) destroy()
1、Filter对象在tomcat服务器启动时 创建,调用init方法 (只会创建一个对象,init方法执行一次)
2、doFilter 每次拦截目标资源时,执行
3、destroy 服务器关闭时执行
FilterConfig 作用和 ServletConfig 类似,用来在Filter初始化阶段,将参数传递给过滤器
1、通过 String getInitParameter(String name) 获得过滤器初始化参数
2、通过 ServletContext getServletContext() 获得ServletContext对象
* FilterConfig 提供参数,是Filter类私有参数,Filter2的初始化参数,不能在Filter1 中进行获取
* 配置全局参数,<context-param> 进行配置,通过ServletContext 获得
<filter-mapping> 过滤器拦截配置
1、如果连接目标资源是一个Servlet,可以选择url和servlet名称两种配置方式
<!-- 拦截/hello是Servlet 路径 -->
<url-pattern>/hello</url-pattern>
<!-- 拦截Servlet 还可以通过Servlet 名称进行拦截 -->
<servlet-name>HelloServlet</servlet-name>
2、url-pattern 和 Servlet中路径写法一样,有三种 : 完全匹配、目录匹配、扩展名匹配
3、<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式
容器调用服务器端资源 有四种方式
REQUEST、FORWARD、INCLUDE、ERROR
案例分析:
全站乱码过滤器:
对于get请求,如何处理乱码
ackage com.dzq.filter; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map; 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.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; @WebFilter(filterName = "AEncodeFilter", urlPatterns ="/*",initParams={@WebInitParam(name="encode",value="utf-8")})
public class EncodeFilter implements Filter {
private FilterConfig config = null;
private String encode = null;
public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset="+encode); //--解决响应乱码
chain.doFilter(new MyHttpServletRequest((HttpServletRequest) request), response);//--包装改造request中和获取请求参数相关的方法解决请求参数乱码
} public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
encode = config.getInitParameter("encode") == null
?"utf-8"
:config.getInitParameter("encode");
}
class MyHttpServletRequest extends HttpServletRequestWrapper{
private HttpServletRequest request = null;
private boolean isNotEncode = true;
public MyHttpServletRequest(HttpServletRequest request) {
super(request);
this.request = request;
} @Override
public Map getParameterMap() {
try{
if(request.getMethod().equalsIgnoreCase("POST")){//--如果是post提交,一行代码解决post提交请求参数乱码
request.setCharacterEncoding(encode);
return request.getParameterMap();
}else if(request.getMethod().equalsIgnoreCase("GET")){//--如果是get提交,则应该手动编解码解决乱码
Map<String,String[]> map = request.getParameterMap();//获取有乱码的map
if(isNotEncode){//只能在第一次解决乱码
for(Map.Entry<String, String[]> entry : map.entrySet()){//遍历map,解决所有值的乱码
String [] vs = entry.getValue();
for(int i=0;i<vs.length;i++){
vs[i] = new String(vs[i].getBytes("iso8859-1"),encode);
}
}
isNotEncode = false;//设置为false,第二次就不会再进这个代码块了
}
return map;
}else{
return request.getParameterMap();
}
}catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
} @Override
public String[] getParameterValues(String name) {
return (String[]) getParameterMap().get(name);
} @Override
public String getParameter(String name) {
return getParameterValues(name) == null ? null : getParameterValues(name)[0];
} }
}
30天自动登录过滤器:
package com.dzq.filter; import java.io.IOException;
import java.sql.SQLException; 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.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler; import com.dzq.domain.User;
import com.dzq.utils.DaoUtils; /**
* Servlet Filter implementation class AutoLoginFilter
*/
@WebFilter(filterName="/AutoLoginFilter",urlPatterns="/*")
public class AutoLoginFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse res=(HttpServletResponse) response;
if(req.getSession(false)==null||req.getSession().getAttribute("user")==null){
Cookie[] cs=req.getCookies();
Cookie findc=null;
if(cs!=null){
for(Cookie c:cs){
if("autologin".equals(c.getName())){
findc=c;
break;
}
}
}
if(findc!=null){
String name=findc.getValue().split(":")[0];
String password=findc.getValue().split(":")[1];
String sql="select * from user where name=? and password =?";
User user=new User();
QueryRunner runner=new QueryRunner(DaoUtils.getSource());
try {
user=runner.query(sql, new BeanHandler<User>(User.class),name,password);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
if(user!=null){
req.getSession().setAttribute("user", user);
}
}
}
chain.doFilter(request, response);
} public void init(FilterConfig fConfig) throws ServletException { } }
20160418javaweb之 Filter过滤器的更多相关文章
- filter 过滤器(监听)
Filter 过滤器 1.简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, ...
- Java防止SQL注入2(通过filter过滤器功能进行拦截)
首先说明一点,这个过滤器拦截其实是不靠谱的,比如说我的一篇文章是介绍sql注入的,或者评论的内容是有关sql的,那会过滤掉:且如果每个页面都经过这个过滤器,那么效率也是非常低的. 如果是要SQL注入拦 ...
- Filter(过滤器)学习
一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...
- javaweb学习总结(四十二)——Filter(过滤器)学习
一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...
- Filter过滤器简单应用( 接口访问控制 )
一.描述 在提供安卓.IOS客户端接口时,可以在登陆接口分配Session给客户端,用于判断其他接口是否是合法访问,以避免将所有的接口都暴露在web中可以由路径直接访问.但是最近的一个项目中的移动接口 ...
- 如何配置Filter过滤器处理JSP中文乱码
参考Tomcat服务器目录webapps的examples示例 简单配置步骤:1.在项目web.xml文件添加过滤器标记<filter>和<filter-mapping>:2. ...
- Filter(过滤器)常见应用
孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(四十六)——Filter(过滤器)常见应用 一.统一全站字符编码 通过配置参数charset指明使用何种字符编码,以处理Html F ...
- Filter过滤器(1)
Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 ht ...
- Servlet的学习之Filter过滤器技术(1)
本篇将讲诉Servlet中一项非常重要的技术,Filter过滤器技术.通过过滤器,可以对来自客户端的请求进行拦截,进行预处理或者对最终响应给客户端的数据进行处理后再输出. 要想使用Filter过滤器, ...
随机推荐
- spring--AOP1--6
AOP 之 6.1 AOP基础 6.1.1 AOP是什么 考虑这样一个问题:需要对系统中的某些业务做日志记录,比如支付系统中的支付业务需要记录支付相关日志,对于支付系统可能相当复杂,比如可能有自己的 ...
- 【HTML】Beginner6:Link
1.Link HTML wich basically means a system of linked text link to another HTML file or any file a ...
- aix 文件大小相关查询
一.aix中查看文件夹占用空间大小 du命令默认是显示当前目录下每个文件以及每个子目录以及下属文件的大小的 用du -sg 可看出当前文件夹的大小,包括文件夹下文件和文件夹(以G为单位):用du -s ...
- BestCoder Round #81 (div.2)C String
总体思路好想,就是在找K个不同字母的时候,卡时间. 看了大神代码,发现goto的!!!!998ms #include<cstdio> #include<cstring> #in ...
- Visual Studio的.NET内存分配分析器解析
Visual Studio 2012拥有丰富的有价值的功能,以至于我听到开发者反馈的需要的新功能新版本已经有了.另外,我听到开发人员询问具体的功能的某个特性,实际上他真正需要的是另外一个功能点. 上面 ...
- Esper系列(七)数据缓存、外部事件应用(静态方法)
LRU Cache 功能:最近最少使用策略. 数据库查询缓存应用配置: 1 ); 12 } 13 return bean; 14 } 15 } ...
- 【Java基础】继承的一些总结
什么是继承 把一些类的具有共性的东西剥离出来形成一个新的类,然后各个其他类保留自己独有的特性,并用关键字extends继承这个剥离出来的新的类,可以最终达到各类原始相同效果,但是在每个类中,单用一个“ ...
- HW4.12
public class Solution { public static void main(String[] args) { int n = 0; while(n * n < 12000) ...
- iOS xcodebuild 打包app
1.传统的app打包(没有使用cocopods) 在打包之前,先把证书和配置文件选好. step1:打开终端,cd 进入到工程目录中 step2:xcodebuild clean(如果buid文件存在 ...
- 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
http://blog.csdn.net/leixiaohua1020/article/details/25430449 本文介绍一个最简单的基于FFMPEG的音频编码器.该编码器实现了PCM音频采样 ...