Servlet Listener Filter 为web项目的三大组件!!!
Listener Filter 和Servlet一样,都是一样套路的配置与使用!!!
注意:配置文件标签往往有顺序要求 (程序执行的顺序)
web.xml文件中的配置顺序必须是:Filter ⇒ Listener ⇒ Servlet
【且连过滤相同路径的Filter执行顺序都是按web.xml中配置的顺序执行的!!!】
Servlet
注意:servlet中/表示 http://ip:端口号/工程名/ (所以servlet路径要使用 / )
ServletContext对象只有一个,始于web项目启动、终于web项目停止🛑
ServletContext对象还能获取项目地址
监听器Listener
public class AdminListener implements ServletContextListener,
HttpSessionListener, HttpSessionAttributeListener {
// Public constructor is required by servlet spec
public AdminListener() {
System.out.println("start listening");
}
// -------------------------------------------------------
// ServletContextListener implementation
// -------------------------------------------------------
public void contextInitialized(ServletContextEvent sce) {
/* This method is called when the servlet context is
initialized(when the Web application is deployed).
You can initialize servlet context related data here.
*/
}
public void contextDestroyed(ServletContextEvent sce) {
/* This method is invoked when the Servlet Context
(the Web application) is undeployed or
Application Server shuts down.
*/
}
// -------------------------------------------------------
// HttpSessionListener implementation
// -------------------------------------------------------
public void sessionCreated(HttpSessionEvent se) {
/* Session is created. */
}
public void sessionDestroyed(HttpSessionEvent se) {
/* Session is destroyed. */
}
// -------------------------------------------------------
// HttpSessionAttributeListener implementation
// -------------------------------------------------------
public void attributeAdded(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute
is added to a session.
*/
Object user = sbe.getSession().getAttribute("user");
if (user != null && ((User)user).getUsername().equalsIgnoreCase("admin")){
System.out.println("welcome admin");
}
}
public void attributeRemoved(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute
is removed from a session.
*/
}
public void attributeReplaced(HttpSessionBindingEvent sbe) {
/* This method is invoked when an attribute
is replaced in a session.
*/
}
}
<!--listener-->
<listener>
<listener-class>com.neuq.Listener.AdminListener</listener-class>
</listener>
过滤器Filter
FilterConfig 和 ServletConfig 一个道理使用
public class LoginFilter implements javax.servlet.Filter {
public void init(FilterConfig config) throws ServletException {
System.out.println("program enter Filter");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpSession session = ((HttpServletRequest ) req).getSession();
if (session.getAttribute("user") == null){
//If the user has not logged in
((HttpServletResponse) resp).sendRedirect("/bookstore/pages/user/login.html");
}else {
//has logged in , program continue
System.out.println("pass through filter");
//必须要有doFilter,保证程序继续运行!!!
chain.doFilter(req, resp);
}
}
public void destroy() {
System.out.println("Filter has finished");
}
}
<!--filter-->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.neuq.Filter.LoginFilter</filter-class>
</filter>
<!--filter has not only one url-pattern-->
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/pages/cart/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/pages/manager/*</url-pattern>
</filter-mapping>
Filter简化事务操作:
/**
* 由于事务问题 每个操作方法都需要try catch
* 利用Filter将是事务操作的servlet中的异常全部抛给Filter做事务的统一处理
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain){
try {
chain.doFilter(req, resp);
MyBatisUtils.commitAndClose();
} catch (Exception e) {
MyBatisUtils.rollbackAndClose();
e.printStackTrace();
//注意 必须是运行时异常才能抛出 (子类不能抛出比父类多的编译时异常)
throw new RuntimeException(e);//把异常抛给Tomcat服务器 统一展示错误页面
}
}