1.1 过滤器简介
过滤器是向Web应用程序的请求和响应处理添加功能的Web服务组件。在Servlet处理用户输入的请求之前,过滤器可以访问该请求。在将Web响应发送给用户之前,过滤器还可以访问该响应。在用户和Servlet之间可以有多个过滤器,它们连接为过滤器链。过滤器用法灵活且功能强大,通常过滤器可以执行以下操作。
(1) 授权请求:根据用户ID和密码授权用户登录。
(2) 修改请求标题和数据:针对请求修改用户提供的标题和数据。
(3) 修改响应标题和数据:针对响应修改Web资源提供的标题和数据。
过滤器参与请求与响应的过程如图1.1所示:
用 户 |
过 滤 器 |
Web资源 |
请求 |
响应 |
1.2 过滤器API
编写过滤器的应用程序接口由javax.servlet包中的Filter、FilterChain、FilterConfig接口定义。
1.2.1 Filter接口
Filter接口中的方法如图2.1所示:
Filter接口 |
init() |
doFilter() |
destroy() |
图2.1 Filter接口中的方法
(1) init():在使用过滤器之前由Web容器调用。init()方法的语法为:
public void init(FilterConfig filterConfig) throws ServletException { this.config=config;//获取过滤器配置信息 } |
init方法在整个过滤器的生命周期中仅执行一次,init()方法有一个FilterConfig参数,该参数用于保存与Filter配置相关的数据信息。
(2) doFilter()方法:每当传递请求或响应时由Web容器调用。doFilter()方法的语法为:
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException ServletException |
其中:
ServletRequest定义一个对象,用于封装用户的请求。
ServletResponse定义一个对象,用于封装用户的响应。
FilterChain用于调用过滤器链中的下一个过滤器。
(3) destroy()方法:在停止使用过滤之后,由容器调用。destroy()方法的语法为:
public void destroy() {} |
该方法可释放被Filter对象打开的资源,例如,关闭数据库连接和IO流等
1.2.2 FilterChian接口
FilterChina接口的doFilter方法用于通知Web容器把请求交给Filter链中的下一个Filter处理,如果当前调用此方法的Filter对象是Filter链中的最后一个Filter,则会调用Web资源,例如,Servlet或JSP等。
1.2.3 FilterConfig接口
Filter程序需要在web.xml文件中进行注册,在注册Filter程序时还可设置其初始化参数。如下所示:
<!-- 配置过滤器 -->
<filter>
<filter-name>loginFilter</filter-name> <filter-class>com.soft.javawebzx1.filter.LoginFilter</filter-class>
<!-- 配置初始化参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>gbk</param-value>
</init-param>
</filter>
其中的<init-param>用于配置Filter的初始化参数。<param-name>代表参数名称,<param-value>代表参数值。要访问这些参数必须借助于FilterConfig接口中的getInitParameter()方法。
1.3 过滤器定义和过滤器映射
使用过滤器之前,需要在web.xml文件中定义过滤器及其映射。过滤器定义用于将过滤器名称与特定的类关联起来。如下代码所示:
<filter>
<filter-name>filterName</filter-name>
<filter-class>className</filter-class>
</filter>
其中:
<filter-name>指定过滤器名称
<filter-class>指定类的名称
过滤器映射用于通过<filter-mapping>元素将过滤器映射到Web资源,如Servlet、JSP等。如下代码所示:
<filter-mapping>
<filter-name>filterName<filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
其中:
<filter-name>指定过滤器名称
<url-pattern>指定Filter所拦截的访问请求路径。
1.3 使用过滤器处理乱码
在JSP中,如果请求中出现中文,在接受时可能会出现乱码。如图3.1所示:
图3.1 根据商品名查询页面
提交之后,获取商品名称并显示,结果如图3.2所示:
图3.2 中文乱码
以前的做法是在负责接受中文请求数据的每个页面编写用于处理中文乱码的代码。这样不利于代码重用。由于过滤器可在请求执行之前进行预处理,所以可把处理中文乱码的代码置于过滤器中。该示例的编写步骤如下:
(1) 创建一个过滤器,命名为encodeFilter.java。代码如下:
public class CodeFilter implements Filter {
FilterConfig config;//定义FilterConfig对象,以读取初始化参数值
public void destroy()
{
}
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)arg0;//转化request对象
HttpServletResponse response=(HttpServletResponse)arg1;//转化response对象
String encoding=this.config.getInitParameter("encoding");//从web.xml中获取配置参数
request.setCharacterEncoding(encoding);//处理请求乱码
response.setContentType("text/html;charset="+encoding);//处理响应乱码
arg2.doFilter(arg0, arg1);//执行滤器链继续给请求的目标资源
}
public void init(FilterConfig config) throws ServletException {
this.config=config;//获取过滤器配置信息
}
}
(2) 在web.xml文件中配置该Filter。代码如下:
<!-- 配置过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>com.soft.javawebzx1.filter.CodeFilter</filter-class>
<!-- 配置encoding初始化参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>gbk</param-value>
</init-param>
</filter>
<!-- 配置过滤器映射 -->
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern><!-- 对所有资源进行过滤 -->
</filter-mapping>
(3) 再次运行以上中文乱码示例,测试该Filter。运行结果如图3.3所示:
图3.3 使用过滤器后解决中文乱码
1.4 使用过滤器避免JavaScript注入攻击
在开发留言板,“添加留言“功能时,如果用户将”<script>alert(‘hahaha’);</script>”这样的内容做为留言插入到数据库,当用户查看留言时,浏览器就会执行对应的JavaScript,从而实现JavaScript注入攻击,利用过滤器,可以改变响应的信息,把其中的”<script>”与”</script>”屏蔽掉,即可。该示例的开发步骤如下:
(1) 创建一个用于获取响应内容的JavaBean,命名为CharacterResponse.java。代码如下:
public class CharacterResponse extends HttpServletResponseWrapper {
private CharArrayWriter output;//实例化CharArrayWriter对象
public String toString() {//重写父类的toString方法
return output.toString();
}
//构造函数,传入response
public CharacterResponse(HttpServletResponse response){
super(response);
this.output=new CharArrayWriter();
}
public PrintWriter getWriter(){ //得到输出PrintWriter对象
return new PrintWriter(output);
}
}
(2) 创建一个过滤器,命名为CharacterResponse.java。代码如下:
public class CharacterFilter extends HttpServlet implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException,
IOException {
response.setCharacterEncoding("gb2312");//设置编码
PrintWriter out = response.getWriter();//得到输出对象
//实例化CharacterResponse对象
CharacterResponse wrapper = new CharacterResponse((HttpServletResponse)response);
//执行doFilter方法,传递请求给目标对象
filterChain.doFilter(request, wrapper);
String resStr = wrapper.toString();//获取响应后的结果
//过滤掉响应之后的<script>与</script>。
String newStr =resStr.replace("<script>", "<script>").replace("</script>", "</script>");
out.println(newStr);//输出结果
}
}
(3) 在web.xml中,配置该过滤器。代码如下:
<filter>
<filter-name>characterfilter</filter-name> <filter-class>com.soft.javawebzx1.filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>characterfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(4) 创建一个JSP页面,命名为test.jsp。代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title></title>
</head>
<body>
过滤器应用<hr/>
<script>
alert("这是一段javaScript注入攻击代码");
</script>
</body>
</html>
没有使用过滤器,浏览器会直接执行该JavaScript脚本,如图4.1所示:
图4.1 没有使用过滤器的运行结果
使用过滤器后,浏览器不再执行JavaScript而是按原样显示,如图4.2所示:
图4.2 使用过滤器后运行结果
Servlet过滤器(详询请加qq:2085920154)的更多相关文章
-
Oracle数据库导入导出命令总结 (详询请加qq:2085920154)
分类: Linux Oracle数据导入导出imp/exp就相当于oracle数据还原与备份.exp命令可以把数据从远程数据库服务器导出到本地的dmp文件,imp命令可以把dmp文件从本地导入到远处的 ...
-
SQL Server日期时间格式转换字符串详解 (详询请加qq:2085920154)
在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...
-
io流(详询请加qq:2085920154)
import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class ioTest ...
-
oracle,sqlserver同一个表两个字段和成一个列查询 (详询请加qq:2085920154)
sql 同一张表开两个字段合成一个字段 例如 SQL tab 字段1 字段2 字段3 3 4 莫 合成 tab 字段1 字段2 3-4 莫 SQL SERVER select 字段1 + ...
-
SQL SERVER 将表中字符串转换为数字的函数 (详询请加qq:2085920154)
在SQL SERVER 2005中,将表中字符串转换为数字的函数共2个:1. convert(int,字段名) 例如:select convert(int,'3')2. cast(字段名 as i ...
-
SQL SERVER增加、删除、更改表中的字段名 (详询请加qq:2085920154)
1. 向表中添加新的字段 alter table table_name add column_name varchar2(20) not null 2. 删除表中的一个字段 delete t ...
-
把文件打成zip或然rar下载 (详询请加qq:2085920154)
//文件打包下载 public static HttpServletResponse downLoadFiles(List<File> files, HttpServletRequest ...
-
Servlet过滤器基础及使用场景
Servlet过滤器详解 一.过滤器基础 1.Servlet过滤器是Servlet的一种特殊用法,主要用来完成一些通用的操作.比如编码的过滤,判断用户的登陆状态等等.Servlet过滤器的适用场合: ...
-
Servlet过滤器——过滤器分析流量
1.概述 Servlet过滤器可以对用户提交的数据或服务器返回的数据进行更改.任何到达服务器的请求都会首先经过过滤器的处理.本实例应用过滤器的这个特点,编写了一个在过滤器中统计网站流量的实例. 本实例 ...
随机推荐
-
ReactNative 根据scrollView/listview滑动距离动态修改NavBar颜色
我们常见某些APP上滑的时候,NavBar颜色会从透明渐变为某种颜色 原理非常简单,根据scrollView的回调动态修改NavBar的透明度即可. 在RN中,尤其是ListView中这个回调不是很好 ...
-
SPRING IN ACTION 第4版笔记-第十一章Persisting data with object-relational mapping-001-使用Hibernate(@Inject、@EnableTransactionManagement、@Repository、PersistenceExceptionTranslationPostProcessor)
一.结构 二.Repository层 1. package spittr.db; import java.util.List; import spittr.domain.Spitter; /** * ...
-
SPOJ DQUERY:D-query
主席树/树状数组.给一个区间,多次询问[l,r]内有多少个不重复的元素.每个前缀都建线段树,询问直接r的[l,r]就可以了.(似乎对主席树有一点了解了?...话说spoj好高级的样子... #incl ...
-
关于 Log4Net
Log4Net是用来记录日志的,可以将程序运行过程中的信息输出到一些地方(文件.数据库.EventLog等),日志就是程序的黑匣子,可以通过日志查看系统的运行过程,从而发现系统的问题.日志的作用:将运 ...
-
tp5实现邮件发送
项目中,用户修改密码,需要发送验证码到用户邮箱,于是就看了看,在此记录一下. 1.开启SMTP服务 测试用的是自己的qq邮箱,首先需要开启邮箱的SMTP服务,开启之后,要记得给你的授权码,授权码一定要 ...
-
MySQL 中 update 修改数据与原数据相同会再次执行吗?
阅读本文大概需要 2.8 分钟. 作者:powdba 来源:阿里云栖社区 一.背景 本文主要测试MySQL执行update语句时,针对与原数据(即未修改)相同的update语句会在MySQL内部重新执 ...
-
斯坦福大学公开课机器学习:machine learning system design | data for machine learning(数据量很大时,学习算法表现比较好的原理)
下图为四种不同算法应用在不同大小数据量时的表现,可以看出,随着数据量的增大,算法的表现趋于接近.即不管多么糟糕的算法,数据量非常大的时候,算法表现也可以很好. 数据量很大时,学习算法表现比较好的原理: ...
-
Dubbo 在maven项目中的应用
首先我们来看一下dubbo的架构: 所以通过此图,我们看到就是服务的提供者将服务注册到注册中心,服务的消费者从注册中心获取服务,monitor监控服务的调用. 关于dubbo的使用,我们举个简单的例子 ...
-
Bootstrap 图片
摘要: Bootstrap框架对图片样式的支持. <img>类 Bootstrap 提供了对图片应用简单样式的 class. .img-rounded:添加 border-radius:6 ...
-
web api HttpConfiguration
//设置web api configuration public static void Register(HttpConfiguration config){ config.Services.Rep ...