Filter基本使用
過濾器Filter作為Web的組件,能對所有Web資源(Jsp,Servlet,,靜態(tài)圖片或靜態(tài)HTML文件等),進行過濾攔截。
1.編寫java類實現(xiàn)Filter接口,并實現(xiàn)其doFilter方法。
class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//過濾器初始化
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
//讓過濾器放行
//過濾器相互之間是不清楚它的上一個或下一個是誰,所有的調(diào)用都是服務器在處理
//Filter執(zhí)行順序可以由<filter_mapping>的順序決定
filterChain.doFilter(req, resp);
}
@Override
public void destroy() {
//過濾器銷毀
}
}
2.web.xml中配置Filter
<?xml version="1.0" encoding="UTF-8"?>
<web-app >
<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>com.filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<!-- 指過濾哪些資源 /*攔截所有 -->
<url-pattern>/hello</url-pattern>
<!-- 如果請求轉(zhuǎn)發(fā)需要如下配置 -->
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
</web-app>
Filter配置細節(jié)
1.一個Filter可以有多個<url-pattern>,可以對多個資源進行過濾。
2.Filter默認只是對一次正常的請求(在地址欄中請求一次)做攔截。
3.File可以用反射配置
Filter配置細節(jié)
REQUEST
默認配置,如果目標資源是通過RequestDispatcher的include()或forward()訪問時,那么該過濾器就不會被調(diào)用。INCLUDE
如果目標資源是通過RequestDispatcher的include()訪問時,那么該過濾器將被調(diào)用。除此之外,該過濾器不會被調(diào)用。FORWARD
如果目標資源是通過RequestDispatcher的forward()訪問時,那么該過濾器將被調(diào)用,除此之外,該過濾器不會被調(diào)用。ERROR
如果目標資源是通過聲明式異常處理機制調(diào)用時,那么該過濾器將被調(diào)用。除此之外,過濾器不會被調(diào)用。
Filter鏈
在web應用中,可以存在多個Filter,這些Filter組合起來即為一個Filter鏈。
web服務器根據(jù)Filter在web.xml文件中的注冊順序,決定先調(diào)用哪個Filter。
當?shù)谝粋€Filter的doFilter()被調(diào)用時,web服務器會創(chuàng)建一個代表Filter鏈的FilterChain對象傳遞給該方法,web服務器會檢查FilterChain對象中是否還有Filter,如果有,則調(diào)用第2個Filter,如果沒有,則調(diào)用目標資源。
Listener
Listener用于監(jiān)聽Web應用中的某些信息(對象或信息的增刪改),然后作出相應的響應處理。
1.ServletContextListener
用于監(jiān)聽Web應用的啟動與關閉
@WebListener
public class MyContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//應用開啟時調(diào)用
String switchUserName = sce.getServletContext()
.getInitParameter("switch_user_name");
System.out.println("打開應用的用戶:" + switchUserName);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//應用關閉時調(diào)用
sce.getServletContext().getRealPath("img");
}
}
在web.xml中配置Listerner
<web-app>
<listener>
<listener-class>com.listener.MyContextListener</listener-class>
</listener>
</web-app>
在Servlet3.0中,Listener可以直接在代碼中通過注解來完成,無需在web.xml中配置。
@WebListener //表明以下是個監(jiān)聽器
public class MyContextListener implements ServletContextListener {
}
2.ServletContextAttributeListener
用于監(jiān)聽ServletContext范圍(application)內(nèi)屬性的改變。
@WebListener
public class MyListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
String name = scae.getName();
Object value = scae.getValue();
System.out.println("屬性名:" + name + "," + "屬性值為:" + value);
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
//替換時觸發(fā)
}
}
public class ReviewServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String user = req.getParameter("user");
//向Application添加屬性,即觸發(fā)Listener
getServletContext().setAttribute("Demo", new User(user, 1));
}
}
輸出結(jié)果
屬性名:Demo,屬性值為:User{name='Test', age=1}
3.ServletRequestListener,ServletRequestAttributeListener
ServletRequestListener:用于監(jiān)聽用戶請求
ServletRequestAttributeListener:用于監(jiān)聽request范圍內(nèi)屬性的變化
@WebListener
public class MyListener implements ServletRequestListener,
ServletRequestAttributeListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
//用戶請求到達時觸發(fā)
HttpServletRequest servletRequest =
(HttpServletRequest) sre.getServletRequest();
String ip = servletRequest.getRemoteAddr();
String requestURI = servletRequest.getRequestURI();;
System.out.println("IP:" + ip + "請求的資源:" + requestURI);
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
//用戶請求結(jié)束后觸發(fā)
}
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
String name = srae.getName();
Object value = srae.getValue();
System.out.println("Name:" + name + "," + value.toString());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
}
}
public class ReviewServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String user = req.getParameter("user");
req.setAttribute("Demo",user);
}
}
4.HttpSessionListener,HttpSessionAttributeListener
HttpSessionListener:用于監(jiān)聽用戶session開始與結(jié)束
HttpSessionAttributeListener:用于監(jiān)聽HttpSession屬性的增刪改
@WebListener
public class MyListener implements HttpSessionListener,
HttpSessionAttributeListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
String userName = se.getSession().getAttribute("user").toString();
String id = se.getSession().getId();
System.out.println("數(shù)據(jù):" + userName + ",會話ID:" + id);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
}
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
String name = se.getName();
String value = se.getValue().toString();
System.out.println("Name:" + name + ",Value:" + value);
}
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
}
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
}
}
public class ReviewServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String user = req.getParameter("user");
req.getSession().setAttribute("user",user);
}
}