初识过滤器(Filter)-------简单的用法及用过滤器做设置编码模板

本文介绍了JavaWeb中的过滤器(Filter)基础,包括过滤器的工作原理、如何创建自定义过滤器、在`doFilter`中设置响应头以及在`web.xml`配置过滤器映射。示例代码展示了如何使用过滤器解决中文乱码问题,并通过过滤器实现安全登录的初步概念。过滤器的初始化顺序和执行顺序也在文中有所说明。
摘要由CSDN通过智能技术生成

老样子,PPT先贴上,想看PPT,就看PPT,想看代码,就在下面(^-^)V

 

PPT内容

过虑器简介:

    过虑器能对客户的请求进行预先处理,然后再将请求转发给其他web组件。
    过虑器是在Servlet2.3规范中定义的,它可以对Web组件的,ServletRequest和ServletResponse进行检查和修改。
    过虑器本身并不生成ServletRequest对象和ServletResponse对象,它只对web组件提供以下过虑功能:
   •在web组件调用之前检查request,并修改请求头和请求正文。
   •过虑器能够在web组件被调用之后检查response对像,修改响应头和响应正文。
 

过虑器的过虑过程:

 

创建自定义的过虑器:

         

自定义的过虑器必须实现:javax.servlet.Filter接口。此接口定义了以下三个方法:
•Init(FilterConfig conf) – 过虑器的初始化方法。-初始化工作执行一次(启动时)。
•doFilter(ServletRequest,ServletResponse,FilterChain)– 此方法完成实际的过虑操作。只要是配置的url匹配此过虑器的配置,即执行此方法。
•destroy()-Servlet窗口在销毁过虑器时执行此方法。-销毁工作也只执行一次。

 

QUICK-START:

用过虑器实现请求字符集的设置:
•第一步:实现Filter类。
•第二步:在doFilter方法中书写代码。
•第三步:在Web.xml中配置过虑器。

 

 

也可以在doFilter方法,设置response的响应头信息。设置好之后再其他的Servlet中就不用再设置响应头了,如下:

response.setContentType(“text/html;charset=UTF-8”);

 

发布过虑器:

 

将字符集配置到过虑器的初始化参数中:

 

Filter的一些小细节:
•doFilter方法中的chain.doFilter(r,p);不能忘记写,否则转不到目录页面。此方法的功能是将请求转到下一个过虑器链。
•在doFilter方法中,接收是与HTTP协议无关的request和response,要想使用session,必须进行强制类型转换,即 : (HttpServletRequest)servletRequest.
•在web.xml中配置的url-pattern通常以/开头,但也可以以*.do这样的形式加以定义。

 

 

过虑器的配置:以下几乎是所有单位的标准配置

<filter>

• <filter-name>autoLoginFilter</filter-name>
• <filter-class>cn.itcast.autologinfilter.AutoLoginFilter</filter-class>

</filter>

<filter-mapping>

• <filter-name>autoLoginFilter</filter-name>
•  <url-pattern>/*</url-pattern>

</filter-mapping>

lfilter-name是过虑器的名称
lfilter-class是过虑器的类文件
linit-param是过虑器的初始化参数。
•param-name– 是参数名。
•param-value- 是参数值。
lfilter-mapping是过虑器的映射信息。
•url-pattern-是需要过虑的资源url.

 

 

Filter-mapping子的元素:
•对于一个<filter/>元素,可以设置多个filter-mapping对应的元素。
•<serlvet-name/>如果不配置<url-pattern/>元素,也可以通过配置<serlvet-name/>元素的形式设置需要拦截的Servlet。
•<dispatcher/>元素:可以为FORWARD-INCLUDE- REQUEST(默认)-ERROR之一。指定需要拦截的Servlet的请求试。

 

 

<filter-mapping>

  <filter-name>jspcache</filter-name>

  <url-pattern>*.jsp</url-pattern>

  <url-pattern>*.html</url-pattern>

  <servlet-name>login</servlet-name>

  <dispatcher>REQUEST</dispatcher>

  <dispatcher>ERROR</dispatcher><!–必须要在web.xml中配置error-page信息才可以拦截 -->

  <dispatcher>INCLUDE</dispatcher>

  <dispatcher>FORWARD</dispatcher><!–应该添加此配置 -- >

</filter-mapping>

 

代码奉上

canFilterDemoWeb

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
  
  <body>
   <h2>主页页面</h2>
   <form action="<c:url value='/LoginServlet'/>" method="post">
   	姓名<input type="text" name="name" />
   	<input type="submit" value="登录" />
   </form>
  </body>
</html>

 

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  
  <!-- 这一段的顺序绝对了初始化时执行的顺序 -->
  <filter>
  	<filter-name>hello</filter-name>
  	<filter-class>cn.hncu.filter.HelloFilter</filter-class>
  </filter>
  <filter>
  	<filter-name>second</filter-name>
  	<filter-class>cn.hncu.filter.SecondFilter</filter-class>
  </filter>
  
  	<!-- 字符设置编码的过滤器 -->
  	<filter>
  		<filter-name>charset</filter-name>
  		<filter-class>cn.hncu.filter.CharacterFilter</filter-class>
  		<init-param>
			<param-name>charset</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
  	</filter>
  	<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.LoginServlet</servlet-class>
  	</servlet>

	<!-- 这一段决定了拦截顺序(过滤顺序) -->
	<filter-mapping>
		<filter-name>second</filter-name>
		<!-- 指定拦截后台的哪些资源,  /*  表示拦截所有 -->
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>hello</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<filter-mapping>
		<filter-name>charset</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>	
  
  
  <!-- 
  	拦截路径设置说明:
  	1.  /*               表示拦截所有
  	2.  *.jsp            表示拦截所有jsp页面的请求与响应
  	3.  /jsps/*.jsp      这是非法格式,不能这样配置
  	4.  /jsps/*          这才是正确的配置,拦截jsps文件夹下的所有资源
  	5.  /LoginServlet    表示只拦截映射路径(url-pattern)为“/LoginServlet”的这一个servlet
  	6.  login            表示只拦截name为login的servlet(可以把jsp页面配成servlet)
  -->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

 


LoginServlet.java这个服务器没什么内容就是,接收前台的name值,然后输出来

package cn.hncu.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String name=request.getParameter("name");
		System.out.println("name: "+name);
	}

}


 

HelloFilter.java

package cn.hncu.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/*
 * 过滤器开发:
 * 1.写一个类实现Filter的三个抽象方法
 * 2.配置web.xml(需要的参数可以通过F2查看)
 */
public class HelloFilter implements Filter{
	
	//过滤器的init方法在服务器启动的时候就执行
	//servlet要配置load-on-startup,就可以在服务器启动时执行初始化,否则只有第一次请求时才会执行
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("这里执行了过滤器的init方法");
	}

	@Override//该方法只有在拦截到相应请求时或者响应时才会执行
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("这里执行了过滤器的doFilter方法");//拦截请求
		
		chain.doFilter(request, response);//放行,如果不放行,请求就被拦在这里了,无法到达后台
		
		System.out.println("这里是服务器的响应....");//拦截响应
	}

	@Override
	public void destroy() {
		System.out.println("这里执行了过滤器的destroy方法");
	}

}


 

SecondFilter.java

package cn.hncu.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SecondFilter implements Filter{
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("这里是第二个filter执行了过滤器的init方法");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("这里是第二个filter执行了过滤器的doFilter方法");
		
		chain.doFilter(request, response);
		
		System.out.println("这里是第二个filter是服务器的响应....");
	}

	@Override
	public void destroy() {
		System.out.println("这里是第二个filter执行了过滤器的destroy方法");
	}

}

 

这是一个设置编码,解决中文乱码问题的较好的一个模板!


CharacterFilter.java

package cn.hncu.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class CharacterFilter implements Filter{
	String charset;
	@Override
	public void init(FilterConfig config) throws ServletException {
		charset=config.getInitParameter("charset");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
//			request.setCharacterEncoding("utf-8");这里的设置编码写死了
			request.setCharacterEncoding(charset);//这里更灵活,应让用户在xml中配置编码
			
			chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
		
	}

}

 


init方法在服务器启动的时候就执行

 

doFilter方法放行

 

destroy方法,在服务器关闭的时候执行

 

两个过滤器时,init方法的执行顺序:详细见web.xml中有解释!

 

两个过滤器时,doFilter方法的执行顺序:

 

中文乱码问题:

 

用过滤器就解决了:

 

包、类分布图:

 

canFilterDemoWeb2

    利用过滤器实现安全登录

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
  
  <body>
   <h2>主页页面</h2>
   <form action="<c:url value='/LoginServlet'/>" method="post">
   	姓名<input type="text" name="name" />
   	<input type="submit" value="登录" />
   </form>
   <a href="<c:url value='/buy/BuyServlet'/>">购物1</a>
   <a href="<c:url value='/buy/BuyServlet2'/>">购物2</a>
   <a href="<c:url value='/jsps/a.jsp'/>">会员专区</a>
  </body>
</html>


 

web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  
  
  	<filter>
  		<filter-name>charset</filter-name>
  		<filter-class>cn.hncu.filter.CharacterFilter</filter-class>
  		<init-param>
			<param-name>charset</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
  	</filter>
  	<filter>
  		<filter-name>LoginSecureFilter</filter-name>
  		<filter-class>cn.hncu.filter.LoginSecureFilter</filter-class>
  	</filter>
  	<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.LoginServlet</servlet-class>
  	</servlet>
  	<servlet>
  		<servlet-name>BuyServlet</servlet-name>
  		<servlet-class>cn.hncu.servlet.BuyServlet</servlet-class>
  	</servlet>
  	<servlet>
  		<servlet-name>BuyServlet2</servlet-name>
  		<servlet-class>cn.hncu.servlet.BuyServlet2</servlet-class>
  	</servlet>

	<filter-mapping>
		<filter-name>charset</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>LoginSecureFilter</filter-name>
		<url-pattern>/jsps/*</url-pattern>
		<url-pattern>/buy/*</url-pattern>
		<url-pattern>/imgs/*</url-pattern>
		
  	<!-- 通过servlet的名字来拦单个servlet ,,,也可通过url-pattern来配置一个死路径来拦单个
		<servlet-name>BuyServlet2</servlet-name>
  	-->
  	<!-- 默认是REQUEST拦截重定向 -->
  	<dispatcher>REQUEST</dispatcher>
  	
  	<!-- 如果添加了此配置,则会拦截转发,否则不会拦截 -->
  	<dispatcher>FORWARD</dispatcher>
	</filter-mapping>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>	
  <servlet-mapping>
    <servlet-name>BuyServlet</servlet-name>
    <url-pattern>/buy/BuyServlet</url-pattern>
  </servlet-mapping>	
  
  <servlet-mapping>
    <servlet-name>BuyServlet2</servlet-name>
    <url-pattern>/buy/BuyServlet2</url-pattern>
  </servlet-mapping>	
  
  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>


 

LoginServlet.java

package cn.hncu.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//这里省去若干代码(service,dao到数据库中验证身份)
		String name=request.getParameter("name");
		if(name!=null&&! "".equals(name.trim())&&name.length()>2){
			//这里假设登录成功
			request.getSession().setAttribute("name", name);
		}
		response.sendRedirect(request.getContextPath()+"/jsps/welcome.jsp");
	}

}

 


welcome.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
  
  <body>
 	 welcome ${name } !
  
  </body>
</html>


 

那个CharacterFilter.java过滤器,在上面已经贴过,这里不再重复。

LoginSecureFilter.java

package cn.hncu.filter;

import java.io.IOException;

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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginSecureFilter implements Filter{

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req=(HttpServletRequest)request;
		if(req.getSession().getAttribute("name")==null){
			//这里就表示没有登录-----踢到登录界面
		HttpServletResponse	resp=(HttpServletResponse) response;
		//注意这里是重定向,要用绝对路径
		resp.sendRedirect(req.getContextPath()+"/index.jsp");
		}
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
		
	}

}


 

BuyServlet.java和BuyServlet2.java没有实际意义的代码,只是用来测试过滤器的,也不再贴出了。

 

a.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
  
  <body>
 	 welcome 会员${name } !
  	这里有图片可以浏览:
  	<img  src="<c:url value='/imgs/4.jpg'/>">
  	<img  src="<c:url value='/imgs/5.jpg'/>">
  	<img  src="<c:url value='/imgs/10.jpg'/>">
  </body>
</html>


 

主页图:

 

 

登录成功图:


 

 

 包、类分布图:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值