国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

JavaWeb——過濾器

2019-11-14 23:28:52
字體:
供稿:網(wǎng)友
javaWeb——過濾器過濾器簡(jiǎn)介

  WEB過濾器是一個(gè)服務(wù)器端組件,它可以截取用戶端的請(qǐng)求與相應(yīng)信息,并對(duì)這些信息過濾。

過濾器的工作原理和生命周期

  在沒有Web過濾器的情況下,用戶直接訪問服務(wù)器上的Web資源。但是如果存在過濾器,用戶就不可以直接訪問過濾器了。

  Web容器啟動(dòng)的時(shí)候過濾器就已經(jīng)啟動(dòng)了,用戶的請(qǐng)求到達(dá)過濾器,過濾器判斷用戶的請(qǐng)求是否符合過濾規(guī)則,如果符合規(guī)則則將用戶的請(qǐng)求發(fā)送給Web資源,Web資源將響應(yīng)信息發(fā)送給過濾器,過濾器將Web資源的響應(yīng)發(fā)送給用戶。工作原理如下圖所示:

  過濾器的生命周期:

  其中實(shí)例化方法在Web容器開始裝載的時(shí)候就執(zhí)行,初始化方法配置一些初始化參數(shù),Web容器卸載(服務(wù)器關(guān)閉)的時(shí)候執(zhí)行銷毀方法。過濾方法會(huì)執(zhí)行多次,其他方法只會(huì)執(zhí)行一次。

第一個(gè)過濾器

    1.創(chuàng)建一個(gè)類實(shí)現(xiàn)javax.servlet.Filter接口。需要實(shí)現(xiàn)該接口中的3個(gè)方法。

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 12 public class FirstFilter implements Filter {13 14     public void destroy() {15         System.out.FirstFilter.java
  • init(FilterConfig):過濾器的初始化方法,Web容器創(chuàng)建過濾器之后將調(diào)用這個(gè)方法,在這個(gè)方法中可以讀取web.xml中的過濾器參數(shù)。
  • doFilter(ServletRequest,ServletResponse,FilterChain):完成實(shí)際的過濾操作,是過濾器的核心方法。當(dāng)用戶請(qǐng)求訪問與過濾器相關(guān)聯(lián)的URL的時(shí)候,Web容器將先調(diào)用過濾器的doFilter方法。FilterChain參數(shù)可以調(diào)用chain.doFilter方法【放行方法】,將請(qǐng)求傳送給下一個(gè)過濾器(或者目標(biāo)資源),或利用轉(zhuǎn)發(fā)、重定向?qū)⒄?qǐng)求轉(zhuǎn)發(fā)給其他資源。
  • destroy():Web容器在銷毀過濾器實(shí)例前調(diào)用該方法,在這個(gè)方法中可以釋放過濾器占用的資源。【大多數(shù)情況下用不到】

    2.在web.xml中配置過濾器(和再web.xml中注冊(cè)servlet類似)

  在MyEclipse中提供了可視化的配置web.xml,如下圖:

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5"  3     xmlns="http://java.sun.com/xml/ns/javaee"  4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7   <display-name></display-name>     8   <welcome-file-list> 9     <welcome-file>index.jsp</welcome-file>10   </welcome-file-list>11   12       <!-- 配置過濾器開始 -->13     <filter>14         <filter-name>FirstFilter</filter-name>15         <filter-class>filter.FirstFilter</filter-class>16     </filter>17     <filter-mapping>18         <filter-name>FirstFilter</filter-name>19         <url-pattern>/*</url-pattern>20     </filter-mapping>21     <!-- 配置過濾器結(jié)束 -->22     23 </web-app>
web.xml

  在index.jsp中我們?cè)诳刂婆_(tái)打印一行信息:"**********這是index.jsp*********";  

  將項(xiàng)目部署到服務(wù)器,啟動(dòng)服務(wù)器:

  在Servlet容器裝載的時(shí)候,執(zhí)行過濾器的init方法,當(dāng)用戶請(qǐng)求頁面的時(shí)候首先執(zhí)行doFilter()方法,當(dāng)Servlet容器卸載的時(shí)候執(zhí)行過濾器的銷毀方法。【注意:用戶的請(qǐng)求先是到達(dá)過濾器并不是直接訪問的Web資源】

  還有一點(diǎn)需要注意:用戶雖然能夠改變用戶請(qǐng)求的資源(例如:網(wǎng)上購物的時(shí)候點(diǎn)擊“立即購買”,這個(gè)請(qǐng)求先要到達(dá)過濾器,如果過濾器檢測(cè)到用戶沒有登錄,就會(huì)將頁面重定向到登陸頁),但是過濾器不能直接處理用戶的請(qǐng)求(過濾器不是Servlet),不能直接返回?cái)?shù)據(jù)。

過濾器鏈

  針對(duì)同一個(gè)用戶請(qǐng)求(url-pattern),與之匹配的過濾器有多個(gè),這個(gè)時(shí)候用戶請(qǐng)求就會(huì)依次通過各個(gè)過濾器到達(dá)web資源。

  新建2個(gè)過濾器:

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 12 public class FirstFilter implements Filter {13 14     public void destroy() {15         System.out.println("*********過濾器1----->銷毀方法*******");16 17     }18 19     public void doFilter(ServletRequest request, ServletResponse response,20             FilterChain filterChain) throws IOException, ServletException {21         System.out.println("*******開始執(zhí)行過濾器1----->doFilter方法*********");22         filterChain.doFilter(request, response);23         System.out.println("*******結(jié)束執(zhí)行過濾器1----->doFilter方法**********");24     }25 26     public void init(FilterConfig arg0) throws ServletException {27         System.out.println("*******執(zhí)行過濾器1------>初始化方法***********");28 29     }30 31 }
FirstFilter.java
 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 12 public class SecondFilter implements Filter {13 14     public void destroy() {15         System.out.println("*********過濾器2----->銷毀方法*******");16     }17 18     public void doFilter(ServletRequest request, ServletResponse response,19             FilterChain filterChain) throws IOException, ServletException {20         System.out.println("*******開始執(zhí)行過濾器2----->doFilter方法*********");21         filterChain.doFilter(request, response);22         System.out.println("*******結(jié)束執(zhí)行過濾器2----->doFilter方法**********");23     }24 25     public void init(FilterConfig arg0) throws ServletException {26         System.out.println("*******執(zhí)行過濾器2------>初始化方法***********");27     }28 29 }
SecondFilter.java

  在web.xml中配置兩個(gè)過濾器(第一個(gè)過濾器在前面,兩個(gè)過濾器都匹配index.jsp)

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5"  3     xmlns="http://java.sun.com/xml/ns/javaee"  4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7   <display-name></display-name>     8   <welcome-file-list> 9     <welcome-file>index.jsp</welcome-file>10   </welcome-file-list>11   12       <!-- 配置過濾器開始 -->13       <!-- 過濾器1 -->14     <filter>15         <filter-name>FirstFilter</filter-name>16         <filter-class>filter.FirstFilter</filter-class>17     </filter>18     <filter-mapping>19         <filter-name>FirstFilter</filter-name>20         <url-pattern>/index.jsp</url-pattern>21     </filter-mapping>22     <!-- 過濾器2 -->    23     <filter>24         <filter-name>SecondFilter</filter-name>25         <filter-class>filter.SecondFilter</filter-class>26     </filter>27     <filter-mapping>28         <filter-name>SecondFilter</filter-name>29         <url-pattern>/index.jsp</url-pattern>30     </filter-mapping>31    <!-- 配置過濾器結(jié)束 -->32     33 </web-app>
web.xml

  在index.jsp中我們打印如下的一句話:System.out.println("******** 這是index.jsp,處理過程完成 *********");

運(yùn)行結(jié)果:

過濾器的分類:

  Servlet 2.5中將過濾器分為4種,如下圖所示:

1.REQUEST過濾器

  新建一個(gè)過濾器FirstFilter(在web.xml中配置兩個(gè)過濾地址index.jsp和main.jsp): 

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5"  3     xmlns="http://java.sun.com/xml/ns/javaee"  4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7   <display-name></display-name>     8   <welcome-file-list> 9     <welcome-file>index.jsp</welcome-file>10   </welcome-file-list>11   12       <!-- 配置過濾器開始 -->13     <filter>14         <filter-name>FirstFilter</filter-name>15         <filter-class>filter.FirstFilter</filter-class>16     </filter>17     <filter-mapping>18         <filter-name>FirstFilter</filter-name>19         <url-pattern>/index.jsp</url-pattern>20         <dispatcher>REQUEST</dispatcher>21     </filter-mapping>22     <filter-mapping>23         <filter-name>FirstFilter</filter-name>24         <url-pattern>/main.jsp</url-pattern>25         <dispatcher>REQUEST</dispatcher>26     </filter-mapping>27    <!-- 配置過濾器結(jié)束 -->28     29 </web-app>
web.xml

  在FirstFilter的doFilter方法中將頁面重定向到main.jsp

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 import javax.servlet.http.HttpServletRequest;12 import javax.servlet.http.HttpServletResponse;13 14 public class FirstFilter implements Filter {15 16     public void destroy() {17         System.out.println("*********過濾器1----->銷毀方法*******");18 19     }20 21     public void doFilter(ServletRequest request, ServletResponse response,22             FilterChain filterChain) throws IOException, ServletException {23         24         HttpServletRequest req = (HttpServletRequest) request;25         HttpServletResponse res = (HttpServletResponse) response;26         27         System.out.println("*******開始執(zhí)行過濾器1----->doFilter方法*********");28         res.sendRedirect(req.getContextPath() + "/main.jsp");//重定向29         System.out.println("*******結(jié)束執(zhí)行過濾器1----->doFilter方法**********");30     }31 32     public void init(FilterConfig arg0) throws ServletException {33         System.out.println("*******執(zhí)行過濾器1------>初始化方法***********");34 35     }36 37 }
FirstFilter.java

  啟動(dòng)服務(wù)器:

  當(dāng)我們?cè)L問index.jsp的時(shí)候,過濾器將頁面重定向到main.jsp——相當(dāng)于我們又重新請(qǐng)求了main.jsp,main.jsp又會(huì)遇到過濾器,如此頁面不停重定向到main.jsp,產(chǎn)生了死循環(huán)不會(huì)輸出任何內(nèi)容!

  換一種方式,我們?cè)谶^濾器中使用服務(wù)器內(nèi)部轉(zhuǎn)發(fā)的方式將頁面轉(zhuǎn)發(fā)到main.jsp(main.jsp向頁面打印"這是main.jsp")。

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 import javax.servlet.http.HttpServletRequest;12 import javax.servlet.http.HttpServletResponse;13 14 public class FirstFilter implements Filter {15 16   public void destroy() {17     System.out.println("*********過濾器1----->銷毀方法*******");18 19   }20 21   public void doFilter(ServletRequest request, ServletResponse response,22       FilterChain filterChain) throws IOException, ServletException {23     24     HttpServletRequest req = (HttpServletRequest) request;25     HttpServletResponse res = (HttpServletResponse) response;26     27     System.out.println("*******開始執(zhí)行過濾器1----->doFilter方法*********");28     req.getRequestDispatcher("main.jsp").forward(request, response);//使用服務(wù)器內(nèi)部轉(zhuǎn)發(fā)29     System.out.println("*******結(jié)束執(zhí)行過濾器1----->doFilter方法**********");30   }31 32   public void init(FilterConfig arg0) throws ServletException {33     System.out.println("*******執(zhí)行過濾器1------>初始化方法***********");34 35   }36 37 }
FirstFilter.java

  運(yùn)行結(jié)果:

2.FORWARD過濾器

  將main.jsp的過濾規(guī)則改為FORWARD。

1 …… 2 <filter-mapping>3         <filter-name>FirstFilter</filter-name>4         <url-pattern>/main.jsp</url-pattern>5         <dispatcher>FORWARD</dispatcher>6  </filter-mapping>7 ……

  重新訪問index.jsp

3.INCLUDE過濾器

  INCLUDE和FORWARD過濾器的使用類似,對(duì)應(yīng)的jsp動(dòng)作是include。

4.ERROR過濾器

  例如我們?cè)L問一個(gè)錯(cuò)誤的頁面時(shí),系統(tǒng)會(huì)給出一個(gè)錯(cuò)誤,用戶看不懂這個(gè)錯(cuò)誤是什么概念——我們需要給出一些人性化的提示。

  以下是沒有在web.xml中配置錯(cuò)誤頁,用戶訪問一個(gè)不存在的頁面:

  在web.xml中配置錯(cuò)誤頁:

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5"  3   xmlns="http://java.sun.com/xml/ns/javaee"  4   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  6   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7   <display-name></display-name>  8   <welcome-file-list> 9     <welcome-file>index.jsp</welcome-file>10   </welcome-file-list>11 12   <!-- 配置錯(cuò)誤頁面 -->13   <error-page>14     <error-code>404</error-code>15     <location>/error.jsp</location>16   </error-page>17 18 </web-app>
web.xml

  在web.xml中配置404錯(cuò)誤的頁面為error.jsp則當(dāng)用戶訪問一個(gè)不存在的頁面時(shí)將會(huì)將error.jsp中的內(nèi)容輸出(以人性化的方式提示用戶):

  當(dāng)頁面出現(xiàn)錯(cuò)誤或者異常的時(shí)候,ERROR過濾器可以將錯(cuò)誤或者異常捕捉到,系統(tǒng)會(huì)記錄下錯(cuò)誤的信息,程序員就可以查找錯(cuò)誤的來源。

  新建一個(gè)ErrorFilter,并在web.xml中進(jìn)行如下配置:

 1 <!-- 配置錯(cuò)誤頁面 --> 2   <error-page> 3     <error-code>404</error-code> 4     <location>/error.jsp</location> 5   </error-page> 6 …… 7 <filter> 8     <filter-name>ErrorFilter</filter-name> 9     <filter-class>filter.ErrorFilter</filter-class>10 </filter>11 <filter-mapping>12     <filter-name>ErrorFilter</filter-name>13     <url-pattern>/error.jsp</url-pattern>14     <dispatcher>ERROR</dispatcher>15 </filter-mapping>16 ……
web.xml

  錯(cuò)誤過濾器ErrorFilter

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 12 public class ErrorFilter implements Filter {13 14     public void destroy() {15 16     }17 18     public void doFilter(ServletRequest request, ServletResponse response,19             FilterChain filterChain) throws IOException, ServletException {20         System.out.println("檢測(cè)到錯(cuò)誤信息!");21         filterChain.doFilter(request, response);//注意打印錯(cuò)誤后要放行,不然頁面不會(huì)顯示22     }23 24     public void init(FilterConfig filterConfig) throws ServletException {25 26     }27 28 }
ErrorFilter.java

  

  J2EE5默認(rèn)的web.xml是Servlet 2.5,J2EE6默認(rèn)的web.xml是Servlet 3.0【支持異步處理】。

  異步處理:如果在過濾器的doFilter()方法中頁面跳轉(zhuǎn)到了一個(gè)Servlet用于業(yè)務(wù)的處理,加入Servlet處理的業(yè)務(wù)時(shí)間花費(fèi)很多,這時(shí)過濾器就會(huì)一直等待Servlet執(zhí)行完成。這樣用戶體驗(yàn)就會(huì)非常差。Servlet 3.0支持異步處理。

  在Servlet中新加入了@WebFilter Annotation。該Annotation用于將一個(gè)類聲明為過濾器,該注解將會(huì)在部署時(shí)被容器處理,容器將根據(jù)具體的屬性配置相應(yīng)的類,將響應(yīng)的類部署為過濾器。——因此我們不需要在web.xml中配置過濾器,只需要用注解的方式。@WebFilter的常用屬性如下:

  下面使用J2EE6.0創(chuàng)建一個(gè)Web項(xiàng)目,創(chuàng)建一個(gè)過濾器名稱為AsyncFilter,使用@WebFilter Annotation配置該過濾器(PS:可以不再web.xml中注冊(cè)該過濾器):

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.DispatcherType; 6 import javax.servlet.Filter; 7 import javax.servlet.FilterChain; 8 import javax.servlet.FilterConfig; 9 import javax.servlet.ServletException;10 import javax.servlet.ServletRequest;11 import javax.servlet.ServletResponse;12 import javax.servlet.annotation.WebFilter;13 14 @WebFilter(filterName = "AsyncFilter", value = { "/servlet/AsyncServlet" }, asyncSupported = true, dispatcherTypes = {15         DispatcherType.ASYNC, DispatcherType.REQUEST })16 public class AsyncFilter implements Filter {17 18     @Override19     public void destroy() {20         System.out.println("***** 銷毀AsyncFilter *****");21     }22 23     @Override24     public void doFilter(ServletRequest request, ServletResponse response,25             FilterChain filterChain) throws IOException, ServletException {26         System.out.println("***** 開始AsyncFilter *****");27         filterChain.doFilter(request, response);//放行28         System.out.println("***** 結(jié)束AsyncFilter *****");29     }30 31     @Override32     public void init(FilterConfig filterConfig) throws ServletException {33         System.out.println("***** 初始化AsyncFilter *****");34     }35 36 }
AsyncFilter.java

  創(chuàng)建一個(gè)處理業(yè)務(wù)的Servlet(該Servlet在doGet方法中使用了線程的休眠方法休眠了10s模擬業(yè)務(wù)的花費(fèi)時(shí)間)

 1 package servlet; 2  3 import java.io.IOException; 4 import java.util.Date; 5  6 import javax.servlet.AsyncContext; 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 12 public class AsyncServlet extends HttpServlet {13     14     public class Excutor implements Runnable{15         private AsyncContext context;16         public Excutor(AsyncContext context) {17             this.context = context;18         }19 20         @Override21         public void run() {22             // 執(zhí)行相關(guān)的復(fù)雜業(yè)務(wù)23             try {24                 Thread.sleep(1000*10);//休眠10s25 //                context.getRequest();26 //                context.getResponse();27                 System.out.println("業(yè)務(wù)完成執(zhí)行時(shí)間:"+new Date());28             } catch (InterruptedException e) {29                 e.printStackTrace();30             }31         }32         33     }34 35     public AsyncServlet() {36         super();37     }38 39     public void destroy() {40         super.destroy(); // Just puts "destroy" string in log41     }42 43     public void doGet(HttpServletRequest request, HttpServletResponse response)44             throws ServletException, IOException {45         46         AsyncContext context = request.startAsync(); //HttpServletRequest對(duì)象開始異步方法47 //        context.getRequest();48 //        context.getResponse();49         50         System.out.println("Servlet執(zhí)行開始時(shí)間:"+new Date());51         new Thread(new Excutor(context)).start();52         request.getRequestDispatcher("/index.jsp").forward(request, response);53         System.out.println("Servlet執(zhí)行結(jié)束時(shí)間:"+new Date());54     }55 56     public void doPost(HttpServletRequest request, HttpServletResponse response)57             throws ServletException, IOException {58 59         doGet(request, response);60     }61 62     public void init() throws ServletException {63 64     }65 66 }
AsyncServlet.java

  編寫好異步處理業(yè)務(wù)的Servlet類之后一定要在web.xml中配置該Servlet啟用異步,如下圖所示:

  在index.jsp中有一個(gè)鏈接指向AsyncServlet:

<a href="<%=request.getContextPath() %>/servlet/AsyncServlet">點(diǎn)擊跳轉(zhuǎn)到AsyncServlet處理業(yè)務(wù)</a>

  運(yùn)行結(jié)果:

過濾器在實(shí)際項(xiàng)目中的應(yīng)用場(chǎng)景

用戶身份的驗(yàn)證

  例如現(xiàn)在有一個(gè)web項(xiàng)目,登陸頁login.jsp將用戶名和密碼提交給LoginServlet處理,Servlet使用request.getParameter方法獲得表單中的用戶名和密碼,將用戶名和密碼進(jìn)行驗(yàn)證,驗(yàn)證成功則頁面重定向到success.jsp,顯示登陸成功和登錄的用戶名【保存在session中再從session中取出】;如果登錄失敗則重定向到failure.jsp。

  在不使用過濾器的情況下,即使用戶不進(jìn)行登錄也可以訪問到success.jsp——任何人都可以訪問到success.jsp,這顯然來說不安全。

  驗(yàn)證用戶身份的Servlet(驗(yàn)證用戶名和密碼都是admin):

 1 package servlet; 2  3 import java.io.IOException; 4  5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 import javax.servlet.http.HttpSession;10 11 public class LoginServlet extends HttpServlet {12 13     public LoginServlet() {14         super();15     }16 17     public void destroy() {18         super.destroy(); // Just puts "destroy" string in log19     }20 21     public void doPost(HttpServletRequest request, HttpServletResponse response)22             throws ServletException, IOException {23         String username = request.getParameter("username");24         String passWord = request.getParameter("password");25         26         if ("admin".equals(username)&&"admin".equals(password)) {27             // 驗(yàn)證通過28             HttpSession session = request.getSession();29             session.setAttribute("username", username);//把用戶名放入session中30             response.sendRedirect(request.getContextPath()+"/success.jsp");31         }else {32             // 驗(yàn)證失敗33             response.sendRedirect(request.getContextPath()+"/failure.jsp");34         }35     }36 37     public void init() throws ServletException {38 39     }40 41 }
LoginServlet.java

如下圖所示:

  現(xiàn)在我們要做這樣一件事:只有用戶登錄成功才可以訪問到success.jsp,反之跳轉(zhuǎn)到登錄界面。即:不允許未登錄用戶訪問success.jsp。

  創(chuàng)建一個(gè)登錄校驗(yàn)的過濾器LoginFilter并在web.xml中配置該過濾器的url為success.jsp

 1 package servlet; 2  3 import java.io.IOException; 4  5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 import javax.servlet.http.HttpSession;10 11 public class LoginServlet extends HttpServlet {12 13     public LoginServlet() {14         super();15     }16 17     public void destroy() {18         super.destroy(); // Just puts "destroy" string in log19     }20 21     public void doPost(HttpServletRequest request, HttpServletResponse response)22             throws ServletException, IOException {23         String username = request.getParameter("username");24         String password = request.getParameter("password");25         26         if ("admin".equals(username)&&"admin".equals(password)) {27             // 驗(yàn)證通過28             HttpSession session = request.getSession();29             session.setAttribute("username", username);//把用戶名放入session中30             response.sendRedirect(request.getContextPath()+"/success.jsp");31         }else {32             // 驗(yàn)證失敗33             response.sendRedirect(request.getContextPath()+"/failure.jsp");34         }35     }36 37     public void init() throws ServletException {38 39     }40 41 }
LoginFilter.java
 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5"  3     xmlns="http://java.sun.com/xml/ns/javaee"  4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7   <display-name></display-name> 8   <servlet> 9     <description>This is the description of my J2EE component</description>10     <display-name>This is the display name of my J2EE component</display-name>11     <servlet-name>LoginServlet</servlet-name>12     <servlet-class>servlet.LoginServlet</servlet-class>13   </servlet>14 15   <servlet-mapping>16     <servlet-name>LoginServlet</servlet-name>17     <url-pattern>/servlet/LoginServlet</url-pattern>18   </servlet-mapping>    19   <welcome-file-list>20     <welcome-file>index.jsp</welcome-file>21   </welcome-file-list>22     <filter>23         <filter-name>LoginFilter</filter-name>24         <filter-class>filter.LoginFilter</filter-class>25     </filter>26     <filter-mapping>27         <filter-name>LoginFilter</filter-name>28         <url-pattern>/success.jsp</url-pattern>29     </filter-mapping>30 </web-app>
web.xml

  加入過濾器之后(只有成功登錄的用戶【session中保存了該用戶的用戶名】才可以訪問index.jsp):

 在實(shí)際的開發(fā)中一個(gè)網(wǎng)站的頁面成百上千,這時(shí)我們可以使用通配符"/*"來匹配所有的url。但是這樣帶來一個(gè)問題:

 當(dāng)我們新建立一個(gè)session的時(shí)候,訪問任何頁面都會(huì)被重定向到login.jsp,login.jsp自己也重定向到login.jsp,這樣就形成了重定向循環(huán)

  這時(shí)就需要在過濾器中判斷頁面是否是login.jsp,如果是login.jsp或者請(qǐng)求的是LoginServlet就直接放行。在LoginFilter的doFilter方法中添加這樣幾行代碼:

1 if (req.getRequestURI().indexOf("login.jsp")!=-1||req.getRequestURI().indexOf("LoginServlet")!=-1) {2     filterChain.doFilter(request, response); // 如果用戶請(qǐng)求的是login.jsp直接放行3     return; // 這一行代碼一定要加上啊!4 }

  運(yùn)行結(jié)果:

  上述程序看似已經(jīng)沒有問題,但是還存在一個(gè)小bug,當(dāng)我們?cè)诘顷戫撦斎胍粋€(gè)錯(cuò)誤的用戶名和密碼頁面并不會(huì)重定向到failure.jsp而是重定向到了login.jsp。如下圖所示:

  這是因?yàn)殡m然我們?cè)赟ervlet驗(yàn)證失敗的時(shí)候?qū)㈨撁嬷囟ㄏ虻搅薴ailure.jsp,failure.jsp又被過濾器重定向到了login.jsp【因?yàn)檫^濾規(guī)則為所有的頁面,并且session中沒有用戶名】

  這時(shí)我們就會(huì)發(fā)現(xiàn)我們?cè)赿oFilter中需要例外的頁面越來越多(登陸頁面、成功頁面、失敗頁面、錯(cuò)誤頁面……)。為了減輕工作的復(fù)雜度,我們可以使用過濾器的init方法中的FilterConfig對(duì)象。

 1. 在web.xml中配置不過濾頁面的初始化參數(shù):

  2.  在過濾方法中使用以上初始化參數(shù)。

 1 public class LoginFilter implements Filter{ 2  3     private FilterConfig filterConfig;// 聲明一個(gè)FilterConfig對(duì)象 4  5     public void init(FilterConfig filterConfig) throws ServletException { 6         this.filterConfig = filterConfig; // 初始化方法的時(shí)候給filterConfig賦值 7     } 8      9     public void destroy() {10         11     }12 13     public void doFilter(ServletRequest request, ServletResponse response,14             FilterChain filterChain) throws IOException, ServletException {15         // 代碼省略16     }17 18 }

  3. 在doFilter方法中使用FilterConfig對(duì)象獲得初始化參數(shù)。

 1 public void doFilter(ServletRequest request, ServletResponse response, 2         FilterChain filterChain) throws IOException, ServletException { 3     HttpServletRequest req = (HttpServletRequest) request; 4     HttpServletResponse res = (HttpSer
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 中方县| 潞城市| 昌都县| 遂川县| 奇台县| 洛隆县| 北票市| 嵩明县| 永城市| 三穗县| 阿荣旗| 文登市| 博白县| 宁海县| 故城县| 邵阳县| 栾川县| 卢氏县| 班玛县| 井冈山市| 龙江县| 忻州市| 桂平市| 元氏县| 修水县| 乃东县| 陆丰市| 馆陶县| 四子王旗| 武城县| 曲靖市| 来凤县| 攀枝花市| 绵阳市| 福州市| 宁海县| 防城港市| 奎屯市| 华阴市| 神池县| 柏乡县|