10---Filter过滤器

本文介绍了Java Web中的Filter过滤器,包括JSTL Core标签库的<c:forEach>和<c:url>标签,以及Filter的基本概念、实现拦截的原理、生命周期和配置方法。通过实例展示了如何使用Filter拦截和处理请求,以及实现用户自动登录的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSTL中的Core标签库:

<c:forEach>标签:

在JSP页面中,经常需要对集合对象进行循环迭代操作,为此,Core标签库提供了一个
<c:forEach>标签,该标签专门用于迭代集合对象中的元素,如Set、List、Map、数组等,并且能重复执行标签体中的内容,它有两种语法格式,具体如下。

迭代包含多个对象的集合:

<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>

迭代指定范围内的集合:

<c:forEach [var="varName"] [varStatus="varStatusName"] begin="begin"

end="end" [step="step"]>
body content
</c:forEach>

var属性用于指定将当前迭代到的元素保存到page域中的名称。

items属性用于指定将要迭代的集合对象。

varStatus属性用干指定当前代状态信息的对象保存到page域中的名称。

begin属性用于指定从集合中第几个元素开始进行迭代,begin的索引值从0开始。如果没有指定items属性,就从begin指定的值开始迭代,直到迭代结束为止。

step属性用于指定迭代的步长,即迭代因子的增量。

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head></head>
<body>
	<%
		String[] fruits = { "apple", "orange", "grape", "banana" };
	%>
	String数组中的元素:
	<br />
	<c:forEach var="name" items="<%=fruits%>">
 		${name}<br />
	</c:forEach>
	<%
		Map userMap = new HashMap();
		userMap.put("Tom", "123");
		userMap.put("Make", "123");
		userMap.put("Lina", "123");
	%>
	<hr/>
	HashMap集合中的元素:
	<br />
	<c:forEach var="entry" items="<%=userMap%>">
			${entry.key}&nbsp;${entry.value}<br />
	</c:forEach>
</body>
</html>

<c:forEach>标签的begin、end和step属性分别用于指定循环的起始索引、结束索引和步长。使用这些属性可以迭代集合对象中某一范围内的元素。


<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head></head>
<body>
  colorsList集合(指定迭代范围和步长)<br />
	<%
		List colorsList=new ArrayList();
		colorsList.add("red");
		colorsList.add("yellow");
		colorsList.add("blue");
		colorsList.add("green");
		colorsList.add("black");
	%>
	<c:forEach var="color" items="<%=colorsList%>" begin="1" 
     end="3" step="2">
		${color}&nbsp;
	</c:forEach>
</body>
</html>

 

 count:表示元素在集合中的序号,从1开始计数。

index:表示当前元素在集合中的索引,从0开始计数。

first:表示当前是否为集合中的第1个元素。

last:表示当前是否为集合中的最后一个元素。


<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head></head>
<body style="text-align: center;">
	<%
		List userList = new ArrayList();
		userList.add("Tom");
		userList.add("Make");
		userList.add("Lina");
	%>
	<table border="1">
		<tr>
			<td>序号</td>
			<td>索引</td>
			<td>是否为第一个元素</td>
			<td>是否为最后一个元素</td>
			<td>元素的值</td>
		</tr>
		<c:forEach var="name" items="<%=userList%>" varStatus="status">
			<tr>
				<td>${status.count}</td>
				<td>${status.index}</td>
				<td>${status.first}</td>
				<td>${status.last}</td>
				<td>${name}</td>
			</tr>
		</c:forEach>
	</table>
</body>
</html>

<c:url> 标签:

在访问一个JSP页面时,通常会在URL中传递一些参数信息。为了方便完成这种功能,Core
标签库中提供了一个<c:url>标签,该标签可以在JSP页面中构造一个新的地址,实现URL的重写。<c:url>标签有两语法格式,具体如下。

没有标签实体的情况:

<c:url value="value" [context="context"] [var="varName"]
[scope="{page|request|session|application}"]>

有标签实体的情况,在标签体中指定构造URL参数:

<c:url value="value"[context="context"] [var="varName"]
[scope="{page|request|session|application}"]>
<c:param>标签
</c:url>

Var属性用于指定将构造的URL地址保存到域对象的属性名称。

value属性用于指定构造的URL。

context属性用于指定导入同一个服务器下其他Web应用的名称。

scope属性用于指定将构造好的URL保存到域对象中。


<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head></head>
<body>
	使用绝对路径构造URL:<br />
	<c:url var="myURL" 
     value="http://localhost:8080/chapter07/register.jsp">
		<c:param name="username" value="张三" />
		<c:param name="country" value="中国" />
	</c:url>
	<a href="${myURL}">register.jsp</a><br />
	使用相对路径构造URL:<br />
	<c:url var="myURL" 
     value="register.jsp?username=Tom&country=France" />
	<a href="${ myURL}">register.jsp</a>
</body>
</html>

 

Filter过滤器

什么是Filter:

Filter被称作过滤器,其基本功能就是对Servlet容器调用Servlet的过程进行拦截,从而在
Servlet进行响应处理前后实现一些特殊功能。

过滤器如何实现拦截?

1、当客户端发生请求后,在HttpServletRequest到达Servlet之前,过滤器拦截客户的HttpServletRequest
2、根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据
3、在过滤器中调用doFilter方法,对请求放行。请求到达Servlet后,对请求进行处理并产生HttpServletResponse发送给客户端
4、在HttpServletResponse到达客户端之前,过滤器拦截HttpServletResponse
5、根据需要检查HttpServletResponse,可以修改HttpServletResponse头和数据
6、最后,HttpServletResponse到达客户端

Filter生命周期

Filter接口中三个重要的方法

1. init()方法:初始化参数,在创建Filter时自动调用,当我们需要设置初始化参数的时候,可以写到 该方法中。

2.doFilter()方法:拦截到要执行的请求时,doFilter就会执行。这里面写我们对请求和响应的预处理

3.destory()方法:在销毁Filter时自动调用

在web.xml文件配置servlet

拦截MyServlet


package cn.itcast.chapter08.filter;
 
import java.io.IOException;
 
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
 
public class MyFilter extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    
    public MyFilter() {
        
    }
    public void destroy() {
    	
    }
	
	protected void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws  IOException, ServletException {
		response.setContentType("text/html;charset=utf-8");
		System.out.println("输出内容表示拦截了响应");
		response.getWriter().print("这是filter输出到网页的内容");
		
		if(true)
		{
			chain.doFilter(request, response);
		}
	}
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
 
}

在web.xml文件配置servlet

  <servlet>
  <servlet-name>MyServlet</servlet-name>
  <servlet-class>cn.itcast.chapter08.filter.MyServlet</servlet-class>
   </servlet>
  <servlet-mapping>
  <servlet-name>MyServlet</servlet-name>
  <url-pattern>/MyServlet</url-pattern>
  </servlet-mapping>  

配置信息:

1.<filter>根元素用于注册一个Filter。
2.<filter-name>子元素用于设置Filter名称。
3.<filter-class>子元素用于设置Filter类的完整名称。
4.<filter-mapping>根元素用于设置一个过滤器所拦截的资源。
5.<filter-name>子元素必须与<filter>中的<filter-name>子元素相同。
6.<url-pattern>子元素用于匹配用户请求的URL,例如“/MyServlet”,这个URL还可以使用通配符“*”来表示,例如“*.do”适用于所有以“.do”结尾的Servlet路径。

Filter映射:

使用通配符“*”拦截用户的所有请求

Filter的<filter-mapping>元素用于配置过滤器拦截的资源信息,如果想让过滤器拦截所有的请求访问,那么需要使用通配符“*”来实现,具体示例如下。

<filter>
<filter-name>Filterl</filter-name>
<filter-class>cn.itcast.chapter08.filter.MyFilter</filter-class></filter>
<filter-mapping>
<filter-name>Filterl</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

拦截不同方式的访问请求

在 web.xml文件中,一个<filter-mapping>元素用于配置一个Filter所负责拦截的资源。<filter-mapping>元素中有一个特殊的子元素<dispatcher>,该元素用于指定过滤器所拦截的资源被Servlet容器调用的方式,<dispatcher>元素的值共有4个,具体如下。
1) REQUEST
当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的 include()或forward()方法访问的,那么该过滤器将不会被调用。
2) INCLUDE
如果目标资源是通过RequestDispatcher的include()方法访问的,那么该过滤器将被调用。
程序
除此之外,该过滤器不会被调用。
1下。
3) FORWARD
如果目标资源是通过RequestDispatcher的forward()方法访问的,那么该过滤器将被调用。
除此之外,该过滤器不会被调用。
如果目标资源是通过声明式异常处理机制调用的,那么该过滤器将被调用。除此之外,过滤
4) ERROR
器不会被调用。


例 forwardservlet的servlet类用于将请求转发给first.jsp


package cn.itcast.chapter08.filter;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ForwardServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public void doGet(HttpServletRequest request,
           HttpServletResponse response)
			throws ServletException, IOException {
		request.getRequestDispatcher("/first.jsp").forward(request,
       response);
	}
	public void doPost(HttpServletRequest request, 
      HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

建一个first.jsp页面:

 

 

 

说明没有拦截到forwardservlet转发的first.jsp

需要添加一个<dispatcher>

 

 Filter链:

在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为一个Filter链.

web服务器根据Filter在web.xml文件中的注册顺序<mapping>,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传递给该方法.在doFilter方法中,开发人员如果调用了FilterChain对象doFilter方法,则Web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第二个filter,如果没有,则调用目标资源.
 

注意:

1.FilterChain.doFilter(request,response)它代表的是向下执行,如果下一个还是filter,那么访问这个filter,如果当前filter已经是整个链的末尾,那么访问web资源.

    2.Filter的顺序由<Filter-mapping>的配置顺序决定.

<url-pattern>有几种写法:

    1.完全匹配    必须以"/"开始

    2.可以使用*通配符

        -->1.目录匹配        /a/*        /*        要求必须以"/"开始

        -->2.扩展名匹配

            *.do        *.action    要求,不能以"/"开始,要以*.XXX结束.

新建两个过滤器myfiltero1,myfiltero2:


package cn.itcast.chapter08.filter;
import java.io.*;
import javax.servlet.*;
public class MyFilter01 implements Filter {
	public MyFilter01() {
		super();
		// TODO Auto-generated constructor stub
	}
	public void init(FilterConfig fConfig) throws ServletException {
		// 过滤器对象在初始化时调用,可以配置一些初始化参数
	}
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用
		PrintWriter out=response.getWriter();
		out.write("Hello MyFilter01<br />");
		chain.doFilter(request, response);
	}
	public void destroy() {
		// 过滤器对象在销毁时自动调用,释放资源
	}
}

package cn.itcast.chapter08.filter;
import java.io.*;
import javax.servlet.Filter;
import javax.servlet.*;
public class MyFilter02 implements Filter {
	public void init(FilterConfig fConfig) throws ServletException {
		// 过滤器对象在初始化时调用,可以配置一些初始化参数
	}
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用
		PrintWriter out=response.getWriter();
		out.write("MyFilter02 Before<br />");
		chain.doFilter(request, response);
		out.write("<br />MyFilter02 After<br />");	
	}
	public void destroy() {
		// 过滤器对象在销毁时自动调用,释放资源
	}
}

配置过滤器myfiltero1,myfiltero2映射:

 FilterConfig接口

为了获取 Filter程序在 web.xml文件中的配置信息,Servlet API提供了一个FilterConfig 接口,该接口封装了Fiter程序在web.xml中的所有注册信息,并且提供了一系列获取这些配置信息的方法。


package cn.itcast.chapter08.filter;
import java.io.*;
import javax.servlet.*;
public class MyFilter03 implements Filter {
	public MyFilter03() {
		super();
		// TODO Auto-generated constructor stub
	}
	private String characterEncoding;
	FilterConfig fc;
	public void init(FilterConfig fConfig) throws ServletException {
		// 获取FilterConfig对象
		this.fc = fConfig;
	}
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// 输出参数信息
		characterEncoding=fc.getInitParameter("encoding");
		System.out.println("encoding初始化参数的值为:"+characterEncoding);
		chain.doFilter(request, response);
	}
	public void destroy() {
	}
}

 配置过滤器myfilter03映射:

 

 使用Filter实现用户自动登录:

编写user类:

 实现登录页面和首页:

 

 用于显示用户的登录信息。如果没有用户登录,在index.jsp页面中就显示一个用户登录的超链接。如果用户已经登录,在index.jsp页面中显示登录的用户名,以及一个注销的超链接

 编写loginservlet用于处理用户的登录请求:

  注销用户登录:

 创建过滤器

该类用于拦截用户登录的访问请求,判断请求中是否包含用户自动登录的Cookie。如果包含,则获取Cookie中的用户名和密码,并验证用户名和密码是否正确。如果正确,则将用户的登录信息封装到User对象存入Session域中,完成用户自动登录

 配置映射信息:

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值