Servlet中的過濾器和監(jiān)聽器詳解
過濾器
Filter 并不是一個標準的Servlet ,它不能處理用戶請求,也不能對客戶端生成響應。主要用于對HttpServletRequest 進行預處理,也可以對HttpServletResponse 進行后處理,是個典型的處理鏈。
Servlet中的過濾器Filter是實現(xiàn)了javax.servlet.Filter接口的服務器端程序,主要的用途是過濾字符編碼、做一些業(yè)務邏輯判斷等。其工作原理是,只要你在web.xml文件配置好要攔截的客戶端請求,它都會幫你攔截到請求,此時你就可以對請求或響應(Request、Response)統(tǒng)一設置編碼,簡化操作;同時還可進行邏輯判斷,如用戶是否已經登陸、有沒有權限訪問該頁面等等工作。它是隨你的web應用啟動而啟動的,只初始化一次,以后就可以攔截相關請求,只有當你的web應用停止或重新部署的時候才銷毀,以下通過過濾編碼的代碼示例來了解它的使用:
過濾器類:
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
}
public void init(FilterConfig config) throws ServletException {
}
}
配置文件
<filter>
<filter-name>encodingFilter</filter-name>
<<filter-name>com.briup.filter.EncodingFilter</filter-name>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Filter的執(zhí)行順序與在web.xml配置文件中的配置順序一致,一般把Filter配置在所有的Servlet之前。
/表示過濾所有的servlet。/manager/表示過濾項目目錄下的所有/manager的servlet
eg:當我們訪問的時候通過了/manager時就必須會執(zhí)行doFilter()這個方法。這個方法是判斷顧客有沒有登陸(如果顧客登陸過session中會有數據)。沒有登陸會提示沒有登陸并且進行登陸。代碼如下:
/*
* 這是一個過濾器:身份證過濾器
*/
@WebFilter("/manager/*")
public class AuthFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 將ServletRequset轉換為HttpServletRequset;
if (request instanceof HttpServletRequest) {
HttpServletRequest req = (HttpServletRequest) request;
// 獲取Session
HttpSession session = req.getSession();
// 判斷session中有沒有customer
Customer customer = (Customer) session.getAttribute("customer");
if (customer != null) {
chain.doFilter(request, response);
} else {
request.setAttribute("msg", "你還沒有登陸");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(
request, response);
}
} else {
request.setAttribute("msg", "你還沒有登陸");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(
request, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
監(jiān)聽器
現(xiàn)在來說說Servlet的監(jiān)聽器Listener,它是實現(xiàn)了javax.servlet.ServletContextListener 接口的服務器端程序,它也是隨web應用的啟動而啟動,只初始化一次,隨web應用的停止而銷毀。主要作用是: 做一些初始化的內容添加工作、設置一些基本的內容、比如一些參數或者是一些固定的對象等等。下面利用監(jiān)聽器對數據庫連接池DataSource的初始化演示它的使用
Listener是Servlet的監(jiān)聽器,它可以監(jiān)聽客戶端的請求、服務端的操作等。通過監(jiān)聽器,可以自動激發(fā)一些操作,比如監(jiān)聽在線的用戶的數量。當 增加一個HttpSession時,就激發(fā)sessionCreated(HttpSessionEvent se)方法,這樣就可以給在線人數加1。常用的監(jiān)聽接口有以下幾個:
ServletContextListener
ServletContextAttributeListener
SessionListener
SessionAttributeListener
SessionBindingListener
ServletRequestListener
ServletRequestAttributeListener
以下是模擬一個當顧客登陸之后給他分配一個購物車情景。由于顧客登陸之后會用session儲存信息。所以我們將購物車維護在session。具體代碼如下:
public class MySessionListener implements HttpSessionListener {
public MySessionListener() {
super();
System.out.println("Listener創(chuàng)建了");
}
@Override
public void sessionCreated(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("Session 創(chuàng)建sessionCreated");
//當Session創(chuàng)建,在session中添加一個購物車
se.getSession().setAttribute("shopcar", "購物車");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("Session 銷毀sessionDestroyed");
}
}
配置文件中web.xml
<listener>
<listener-class>com.briup.day03.MySessionListener
</listener-class>
</listener>