JavaWeb------Servlet过滤器

(1)过滤器是web服务器上的组件,它们对客户和资源之间的请求和响应进行过滤。Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。

@(2)过滤器的工作原理是:

当servlet容器接收到对某个资源的请求,它要检查是否有过滤器与之关联。如果有过滤器与该资源关联,servlet容器将把该请求发送给过滤器。在过滤器处理完请求后,它将做下面3件事:
• 产生响应并将其返回给客户;
• 如果有过滤器链,它将把(修改过或没有修改过)请求传递给下一个过滤器;
• 将请求传递给不同的资源。
当请求返回到客户时,它是以相反的方向经过同一组过滤器返回。过滤器链中的每个过滤器够可能修改响应。

(3)过滤器API主要包括:Filter、FilterConfig和FilterChain接口。

1.FilterConfig 使用
Filter 的 init 方法中提供了一个 FilterConfig 对象。
如 web.xml 文件配置如下:
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.runoob.test.LogFilter</filter-class>
<init-param>
<param-name>Site</param-name>
<param-value>abc</param-value>
</init-param>
</filter>
2.在 init 方法使用 FilterConfig 对象获取参数:
public void init(FilterConfig config) throws ServletException {
// 获取初始化参数
String site = config.getInitParameter("Site");
// 输出初始化参数
System.out.println("网站名称: " + site);
}

(4)回答一下两个问题

1. 试简述过滤器有哪些功能?

	1)转换字符编码
中文网页编码常用的就是gb2312或是UTF-8,但TOMCAT会默认用编码iso-8859-1,所以需要把所有经过TOMCAT的中文字符进行转换,如果手动在request里改很麻烦,可以用一个filter对所有的request进行拦截,进行编码转换。
2)管理Hibernate的session
在Web 里用Hibernate常常是把session绑定到线程,但往往要求一个session在一个请求的活动中都有效,这样可以保证同一活动中能共享 lazy bean。用filter能到达这个目的,在doFilter之前绑定session到线程,在doFilter后关闭session,这样既可以保证 session不会泄漏,也能让lazy bean在同一请求周期里共享
3)做权限审查
在web层里需要对很多资源进行逻辑类似的安全保障,通过filter可以在调用这些资源前加上一个屏障,这样既可以把安全代码和逻辑代码相分离,也可以很好的reuse这些安全模块
4)做cache
在web层常常需要对一些请求返回进行缓存,这样可以有效的减轻服务器的压力,filter可以对请求进行拦截,查询缓存,若有效则直接返回缓存内容,若无效则进行实际的服务器请求,返回给用户,并对缓存进行更新,以备下次请求
5)做拦截器的代理
有的时候需要把一些拦截器用到web层,filter可以很好地充当代理的角色,比如可以在Spring里做好拦截器的Bean,再通过filter把这些Bean和相应的web请求桥接起来。
6)过滤特殊字符
有时需要过滤特殊字符,比如防止sql注入,Filter可以很好达到这个目的

(5)web.xml配置各节点说明

~~<filter>指定一个过滤器。
~~<filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
~~<filter-class>元素用于指定过滤器的完整的限定类名。
~~<init-param>元素用于为过滤器指定初始化参数,它的子元素param-name>指定参数的名字,<param-value>指定参数的值。
~~在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
~~<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径 filter-name>子元素用于设置filter的注册名称。该值必须是在filter>元素中声明过的过滤器的名字
<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式) ~~<servlet-name>指定过滤器所拦截的Servlet名称。
~~<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher>子元素用来指定 Filter 对资源的多种调用方式进行拦截。 ~~<dispatcher>子元素可以设置的值及其意义 REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。 ~~INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。 ~~FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。 ~~ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

总结:过滤器中我们可以根据 doFilte() 方法中的 request 对象获取表单参数信息,例如:我们可以获取到请求的用户名和密码进行逻辑处理,也可以通过 response 对用户做出回应。比如,如果验证用户名不正确,禁止用户访问 web 资源,并且向浏览器输出提示,告诉用户用户名或者密码不正确等等;


public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException { //获取请求信息(测试时可以通过get方式在URL中添加name)
//http://localhost:8080/servlet_demo/helloword?name=123
String name = req.getParameter("name"); // 过滤器核心代码逻辑
System.out.println("过滤器获取请求参数:"+name);
System.out.println("第二个过滤器执行--网站名称:www.runoob.com"); if("123".equals(name)){
// 把请求传回过滤链
chain.doFilter(req, resp);
}else{
//设置返回内容类型
resp.setContentType("text/html;charset=GBK"); //在页面输出响应信息
PrintWriter out = resp.getWriter();
out.print("<b>name不正确,请求被拦截,不能访问web资源</b>");
System.out.println("name不正确,请求被拦截,不能访问web资源");
}
}

(6)实验题目:编写一个过滤器改变请求编码。

【步骤1】编写一个loginform.html文件
//loginform.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>使用过滤器改变请求编码</title>
<meta http-equiv="Content-Type" content="text/html;charset=GB2312">
</head>
<body>
<center>
<h2>请输入用户名和口令:</h2>
<form method="post" action="servlet/CheckParamServlet">
<table>
<tr>
<td>用户名:</td>
<td><input name="name" type="text"></td>
</tr>
<tr>
<td>口 令:</td>
<td><input name="pass" type="password"></td>
</tr>
<tr>
<td></td>
<td>
<input name="ok" type="submit" value="提交">
<input name="cancel" type="reset" value="重置">
</td>
</tr>
</table>
</form>
</center>
</body>
</html>

【步骤2】编写处理请求参数的Servlet
package servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CheckParamServlet extends HttpServlet{
private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException { String name = request.getParameter("name");
String pass = request.getParameter("pass");
response.setContentType("text/html;charset=gb2312");
PrintWriter out = response.getWriter(); out.println("<html><head><title>Param Test</title></head>");
out.println("<h3 align=center>你的用户名为:"+name+"</h3>");
out.println("<h3 align=center>你的口令为:"+pass+"</h3>");
out.println("</body></html>");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}

【步骤3】修改web.xml文件,加入下面代码:
<servlet>
<servlet-name>CheckParamServlet</servlet-name>
<servlet-class>CheckParamServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CheckParamServlet</servlet-name>
<url-pattern>/servlet/check</url-pattern>
</servlet-mapping>

实验结果:当用户点击提交会出现用户名会变成问号的情况

【步骤5】过滤器代码如下:
package filter;
import java.io.IOException;
import javax.servlet.*;
public class EncodingFilter implements Filter {
protected String encoding = null;
protected FilterConfig config;
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
// 得到在web.xml中配置的编码
this.encoding = filterConfig.getInitParameter("Encoding");
}
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
if (request.getCharacterEncoding() == null) {
// 得到指定的编码
String encode = getEncoding();
if (encode != null) {
//设置request的编码
request.setCharacterEncoding(encode);
response.setCharacterEncoding(encode);
}
}
chain.doFilter(request, response);
}
protected String getEncoding() {
return encoding;
}
public void destroy() {
}
}
【步骤6】在web.xml文件中配置过滤器,加入下面代码:
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>filter.EncodingFilter</filter-class>
<init-param>
<param-name>Encoding</param-name>
<param-value>gb2312</param-value>
</init-param>
</filter> <filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

实验结果:输入的用户名实现了中文转换

2017.11.7 JavaWeb------Servlet过滤器的更多相关文章

  1. 2017.11.29 JSP+Servlet 中功能验证码及验证的实现

    源代码如下: validate.jsp <%@ page language="java" import="java.util.*" pageEncodin ...

  2. 2017.11.27 用Servlet在JSP中加入验证码

    登陆界面 <%@ page pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ...

  3. 2017.11.15 JavaWeb的学生体质管理系统

    (11)案例-----学生身体体质信息管理系统的开发 11.1 功能划分: 1.添加记录模块:完成向数据库添加新纪录 2.查询记录模块:完成将数据库的记录以网页的方式显示出来,一般采用有条件的查询 3 ...

  4. 2017.11.12 web中JDBC 方式访问数据库的技术

    JavaWeb------ 第四章 JDBC数据库访问技术 在JavaWeb应用程序中数据库访问是通过Java数据库连接(JavaDateBase Connectivity简称JDBC)数据库的链接一 ...

  5. TODO java-web相关 servlet过滤器+监听器

    servlet过滤器 定义: 过滤器是小型的web组件,它负责拦截请求和响应,以便查看.提供或以某种方式操作正在客户机和服务器之间交换的数据. 与过滤器相关的servlet共包含3个简单接口:Filt ...

  6. JavaWeb学习篇之----Servlet过滤器Filter和监听器

    首先来看一下Servlet的过滤器内容: 一.Servlet过滤器的概念: ************************************************************** ...

  7. Servlet过滤器

    Servlet过滤器 [TOC] 1.过滤器的基本概念 1.1.基本概念 过滤器(Filter)属于tomcat服务器中的Servlet功能.在普通的javaweb服务中,jsp中的请求要被Servl ...

  8. [JavaWeb] Servlet Filter

    作用: Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息. 可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet.Servle ...

  9. JavaWeb—Servlet

    1.什么是Servlet 用来扩展web服务器功能的组件——早期的web服务器只能处理静态资源的请求,即需要事先将html文件准备好,并存放到web服务器上面.不能够处理动态资源的请求(需要计算,动态 ...

随机推荐

  1. linux面试题:删除一个目录下的所有文件,但保留一个指定文件

    面试题:删除一个目录下的所有文件,但保留一个指定文件 解答: 假设这个目录是/xx/,里面有file1,file2,file3..file10 十个文件 [root@oldboy xx]# touch ...

  2. php数组·的方法1-数组的操作

    //range() 创建一个含指定范围的数组 可设置间隔 var_dump(range(1, 9, 2)); echo '<br>'; //array_combine() 合并两个数组创建 ...

  3. hduoj 2062Subset sequence

    Subset sequence Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  4. js面向对象之属性

    1.属性的设置和获取,方式有两种:   .和[ ]   .是取自身属性   [ ]可以是变量 var obj={}; obj.name="sonia"; obj['age']=22 ...

  5. c#-day02学习笔记

    类型转化 为什么要类型转化:因为C#语言是强类型的语言,所以区分了很多的类型,类型和类型之间是不能直接赋值的,如果要赋值 就需要转换类型 类型转换分为两大类: 第一类:隐式转换 隐式转换是系统默认的转 ...

  6. Redis-Service.Stack的初级使用

    主要解决Redis服务器带有密码的情况下初始化. 创建RedisHelper类,直接贴代码: using ServiceStack.Redis;using System;class RedisHelp ...

  7. Linux如何上查看和退出tomcat实时日志

    1.先切换到:cd usr/local/tomcat/logs 目录下 2.tail -f catalina.out Ctrl+c 是退出tail命令. alt+E+R重置.

  8. maven课程 项目管理利器-maven 2-2第一个maven案例hellomaven

    maven 目录结构 pom.xml src -main -java -package -test -java -package -resources

  9. (八)JavaScript之[JSON]与[void]

    14].JSONJSON 格式在语法上与创建 JavaScript 对象代码是相同的. 方法:JSON.parse(); //将JSON字符串转换为JavaScript对象JSON.stringify ...

  10. 【起航计划 003】2015 起航计划 Android APIDemo的魔鬼步伐 02 SimpleAdapter,ListActivity,PackageManager参考

    01 API Demos ApiDemos 详细介绍了Android平台主要的 API,android 5.0主要包括下图几个大类,涵盖了数百api示例: