Filter过滤器

      Filter 技术是servlet 2.3新增加的功能。servlet2.3是sun公司于2000年10月发布的,它的开发者包括许多个人和公司团体,充分体现了sun公司所倡导的代码开放性原则。在众多参与者的共同努力下,servlet2.3比以往功能都强大了许多,而且性能也有了大幅提高。

一、Filter(过滤器)

 

1.过滤器的概念

Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。

优点:过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题

2.过滤器的作用描述

 

  • 在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest 。 
  •   根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。 
  •  在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。 
  • 根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。

 

二、Filter体系结构

 

 

Filter接口

 

 Servlet API提供三个接口类供我们编写:javax.servlet.Filter;FilterChain和FilterConfig,作为Servlet的拦截器。

  1. FilterConfig在重写Filter接口时,在init方法里主要通过getInitParameter("参数名")调用web.xml里的配置信息。在destroy里付值null销毁.
  2. FilterChain在重写Filter接口时,在doFilter方法里通过FilterChain的对象调用doFilter(request,responte)来开始调用Servlet
  3. Filter重写三个方法init;destroy;doFilter。

可以根据WEB.XML里对Filter的配置来组成Filter链,在配置中的前一个Filter里调用FilterChain的doFilter会跳到配置的下一个去,最后一个就会跳到Servlet去。

HttpServlet类

当编写一个Servlet时,必须直接或间接实现Servlet接口,最可能实现的方法就是扩展javax.servlet.GenericServlet或javax.servlet.http.HttpServlet当实现javax.servlet.Servlet接口时必须实现5个方法

init(ServletConfig   config) 
service(ServletRequest   req,ServletResponse   resp) 
destroy() 
getServletConfig() 
getServletInfo() 
别的方法就不说了 
service是执行应用逻辑的入口点,包容器调用此方法来响应进来得请求,只是在servlet被成功初始化后才能调用它 
其实servlet和applet差不多,当一个servlet被实例化后,包容器自动去调用固定的方法首先是init(),然后是service()..... 
所以service必须有. 

GenericServlet类提供了Servlet接口的基本实现,所以他的子类都必须实现service()方法 
HttpServlet类扩展了GenericServlet并且提供了Servlet接口中具体于HTTP的实现它更   象一个其他所有的servlet都要扩展的类,其中他定义了两种形式的service方法:

service(Servirequest   req,Servletresponse   resp) 
此方法是GenericServlet的service()方法的实现,他把resquest,response对象分别转化为HttpServletRequest和HttpServletResponse并且调用下面重载的service()方法,所以不应当重载上面的service()方法:

protect   void   service(HttpServirequest   req,HttpServletresponse   resp) 
他用HTTP的request,response对象作为参数,并且由上面的方法调用,HttpServlet实现这个方法后就成为一个HTTP请求的分发者,他把请求代理给doGet(),doPost().....等doXXXX()方法,因此不应当重载他.
当包容器为一个servlet收到一个请求时,包容器调用公共的service方法在把参数转换为HttpServirequest,HttpServletresponse   后,这个公共的方法调用保护的service根据HTTP请求方法的类型,保护的service方法调用doXXXX()方法之一.
doGet()方法是当得到一个GET类型的请求时调用,把内容放在url上传输,所以最多只能传输240个字节 
doPost()方法是当得到一个POST类型的请求时调用 

 

 

 

三、多个Filter拦截的顺序

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

 

四、字符编码过滤器

  示例:

index.jsp

<body>
<h2>这里是主页面</h2>
   用户名:${uname}<br/>
   密码:${upass}
</body>

 

 

 
loginTwo.jsp <body> <h1>登录界面二</h1> <form action="loginTwo.do" method="post"> 用户名:<input type="text" name="uname" /> <br/> 密码:<input type="password" name="upass" /> <br/> <input type="submit" value="登录" /> <br/> </form> </body>

 

 


loginOne.jsp<body><h1>登录界面一</h1><form action="loginTwo.do" method="post">用户名:<input type="text" name="uname"><br/>密码:<input type="password" name="upass"><br/><input type="submit" value="登录"><br/></form></body>

 

 

 

 

 

 

 

 

 

 

success.jsp

<body>
   用户名:${uname}<br/>
   密码:${upass}
</body>

 

 

 

 

 

 

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>Web_16</display-name>
  <!-- 配置编码filter -->
 <filter>
  <filter-name>EncodingOneFilter</filter-name>
  <filter-class>com.sun.filter.EncodingFilter</filter-class>
  </filter>
  <!-- 映射Filter -->
  <filter-mapping>
  <filter-name>EncodingOneFilter</filter-name>
  <url-pattern>*.do</url-pattern>
  </filter-mapping>
  
  <!-- 配置编码filter -->
  <!-- <filter>
  <filter-name>EncodingTwoFilter</filter-name>
  <filter-class>com.sun.filter.EncodingFilter</filter-class>
  </filter> -->
  <!-- 映射Filter -->
  <!-- <filter-mapping>
  <filter-name>EncodingTwoFilter</filter-name>
  <url-pattern>/loginTwo.do</url-pattern>
  </filter-mapping> -->
  
  
  
  <!--配置servlet-->
  <servlet>
  <servlet-name>loginOneServlet</servlet-name>
  <servlet-class>com.sun.servlet.loginOneServlet</servlet-class> 
  </servlet>
  <!-- 映射 -->
  <servlet-mapping>
  <servlet-name>loginOneServlet</servlet-name>
  <url-pattern>/loginOne.do</url-pattern>
  </servlet-mapping>
  
    <!--配置servlet-->
  <servlet>
  <servlet-name>loginTwoServlet</servlet-name>
  <servlet-class>com.sun.servlet.loginTwoServlet</servlet-class> 
  </servlet>
  <!-- 映射 -->
  <servlet-mapping>
  <servlet-name>loginTwoServlet</servlet-name>
  <url-pattern>/loginTwo.do</url-pattern>
  </servlet-mapping>
  
  

  
  <!-- 配置filter(1) -->
  <filter>
  <filter-name>OneFilter</filter-name>
  <filter-class>com.sun.filter.OneFilter</filter-class>
  </filter>
  <!-- 映射filter -->
  <filter-mapping>
  <filter-name>OneFilter</filter-name>
  <url-pattern>/index.jsp</url-pattern>
  </filter-mapping>
  
    <!-- 配置filter(2) -->
  <filter>
  <filter-name>TwoFilter</filter-name>
  <filter-class>com.sun.filter.TwoFilter</filter-class>
  </filter>
  <!-- 映射filter -->
  <filter-mapping>
  <filter-name>TwoFilter</filter-name>
  <url-pattern>/index.jsp</url-pattern>
  </filter-mapping>
  
    <!-- 配置filter(3)-->
  <filter>
  <filter-name>ThreeFilter</filter-name>
  <filter-class>com.sun.filter.ThreeFilter</filter-class>
  </filter>
  <!-- 映射filter -->
  <filter-mapping>
  <filter-name>ThreeFilter</filter-name>
  <url-pattern>/index.jsp</url-pattern>
  </filter-mapping>
  
  
  
  
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

 

public class EncodingFilter extends HttpFilter{
	@Override
	protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		 request.setCharacterEncoding("UTF-8");
		 //放出
		 chain.doFilter(request, response);
		 System.out.println("进来啦........");
	}

}

 
public class loginOneServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //super.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //super.doPost(req, resp); String uname=req.getParameter("uname"); String upass=req.getParameter("upass"); System.out.println("uname:"+uname+" upass:"+upass); req.setAttribute("uname", uname); req.setAttribute("upass", upass); req.getRequestDispatcher("success.jsp").forward(req, resp); } }

 

 

 

 

 

 

 

 

public class loginTwoServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//super.doGet(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//super.doPost(req, resp);
		 String uname=req.getParameter("uname");
    	 String upass=req.getParameter("upass");   	 
    	 System.out.println("uname:"+uname+"     upass:"+upass);
    	 req.setAttribute("uname", uname);
    	 req.setAttribute("upass", upass);
       req.getRequestDispatcher("index.jsp").forward(req, resp);
	}

}

 

 

 

五、Filter的<dispatcher>

<dispatcher>子元素可以设置的值及其意义

REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。

 

INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

 

FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

 

 

ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除

 

此之外,过滤器不会被调用。

 

六、检查用户是否登陆

       示例:

 
   list.jsp    

<body>
你好:${uname}<br/>
<a href="one.jsp">跳至one.jsp</a><br/>
<a href="two.jsp">跳至two.jsp</a><br/>
<a href="three.jsp">跳至three.jsp</a><br/>
</body>

 

 

 

login.jsp

<body>
<h1>登录页面</h1>
<form action="login.do" method="post">
用户名:<input type="text" name="uname"/><br/>
密码:<input type="password" name="upass"/><br/>
<input type="submit" value="登录"/>
</form>
</body>

 

 

 

one.jsp

<body>
这是One.jsp网页
</body>

 

two.jsp

 

<body>
这是Two.jsp网页
</body>

 

 

 

three.jsp

 

 

<body>
这是Three.jsp网页
</body>                                                                                                                                         

 

Web.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>Web_17</display-name>
  <!-- 配置默认放行文件 -->
  <context-param>
  <param-name>discharged</param-name>
  <param-value>/login.jsp,/list.jsp,/login.do,/three.jsp</param-value>
  </context-param>

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- 配置登录的servlet -->
   <servlet>
   <servlet-name>loginServlet</servlet-name>
   <servlet-class>com.sun.servlet.LoginServlet</servlet-class>
   </servlet>
  <!-- 映射登录的servlet -->
  <servlet-mapping>
  <servlet-name>loginServlet</servlet-name>
  <url-pattern>/login.do</url-pattern>
  </servlet-mapping>
  
  <!-- 配置过滤器 -->
  <filter>
  <filter-name>loginFilter</filter-name>
  <filter-class>com.sun.filter.LoginFilter</filter-class>
  </filter>
  <!-- 映射过滤器 -->
  <filter-mapping>
  <filter-name>loginFilter</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>
  
</web-app>


Loginservlet.class

 

public class LoginServlet extends HttpServlet{

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取登录的用户名密码
String uname=req.getParameter("uname");
String upass=req.getParameter("upass");
if("admin".equals(uname)&&"123".equals(upass)){
//存值
HttpSession session=req.getSession();
//跳转
session.setAttribute("uname",uname);
session.setAttribute("upass",upass);
req.getRequestDispatcher("list.jsp").forward(req, resp);
}else{
//登录不成功,重定向到login.jsp
resp.sendRedirect("login.jsp");
}

}


}
 

LoginFilter.class

public class LoginFilter extends HttpFilter{
private List<String> list;

@Override
public void init(FilterConfig filterConfig) throws ServletException {
  //获取servletContext(application)中的值
ServletContext servletContext=filterConfig.getServletContext();
  //获取应用程序初始化的配置信息
String discharged=servletContext.getInitParameter("discharged");
//将配置信息转成集合
String[] str=discharged.split(",");
list=Arrays.asList(str);
              System.out.println("discharged"+discharged);
}


@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
            //获取请求路径
String path=request.getServletPath();
System.out.println(path);
   //判断是否包含,包含就放行,不包含继续判断
     if(list.contains(path)){
     System.out.println("放行啦....");
     chain.doFilter(request, response);
     }else{
     //获取session中的值
     HttpSession session=request.getSession();
     Object name=session.getAttribute("uname");
     if(name!=null){
     System.out.println("终于放行啦....");
     chain.doFilter(request, response);  
     }else{
     //重定向到登录页面
     response.sendRedirect("login.jsp");
     }
     }

}

}

 

 

 

loginOne.jsp

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值