一直不太明白过滤器和监听器是干嘛用的,今天终于明白了,于是就想把自己写的监听器和过滤器给保存下来,以备后面查阅
在我的博客里所写的,除了注明外都是我个人的理解,有不明白的希望批评指正,那么下面我就说下我对监听器和过滤器的定义的理解。
监听器,在服务器启动的时候对项目进行的工作,比如连接数据库,我们查询的信息都放在数据库里面,那么与数据库的连接是在服务启动的时候就连好还是查询的时候再连好呢,我个人觉得可以先连接好,这样我们就可以用地址池了,那么这个工作就可以由监听器来做,或者说,可以在服务启动的时候测试一下数据库有没有问题。
写监听器必须实现ServletContextListener这个接口,这个接口有两个方法,分别为contextInitialized和contextDestroyed方法,当服务起来的时候,服务器会自己调用contextInitialized方法,服务器关闭的时候会调用contextDestroyed方法,所以,要把这个类的主要代码放在contextInitialized中,下面是我写的代码
package com.bjsxt.webservice; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Properties; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class DatabaseListener implements ServletContextListener{ @Override public void contextDestroyed(ServletContextEvent event) { } @Override public void contextInitialized(ServletContextEvent event) { System.out.println("tomcat开始启动,即将连接数据库"); String path="WEB-INF/classes/config.properties"; String realPath = event.getServletContext().getRealPath(path); Properties pro = new Properties(); String sql = event.getServletContext().getInitParameter("sql"); File file = new File(realPath); String url = null; String user = null; String driver = null; String pwd = null; try { pro.load(new FileInputStream(file)); } catch (IOException e) { e.printStackTrace(); } String dataType = pro.getProperty("dataType"); url = pro.getProperty(dataType + "Url"); user = pro.getProperty(dataType + "User"); pwd = pro.getProperty(dataType + "Pwd"); driver = pro.getProperty(dataType + "Driver"); // System.out.println(driver); try { Class.forName(driver); Connection conn = DriverManager.getConnection(url,user,pwd); PreparedStatement pStmt = conn.prepareStatement(sql); pStmt.execute(); System.out.println("数据库连接没有问题"); } catch (ClassNotFoundException e) { System.out.println("数据库连接出现问题"); e.printStackTrace(); } catch (SQLException e) { System.out.println("数据库连接出现问题"); e.printStackTrace(); } } }
web.xml中的代码如下:
<listener> <listener-class>com.bjsxt.webservice.DatabaseListener</listener-class> </listener> <context-param> <param-name>sql</param-name> <param-value>select * from Photo where 1=2</param-value> </context-param>
config.properties代码如下:
dataType=mysql
##oracle
oracleDriver=oracle.jdbc.driver.OracleDriver
oracleUrl=jdbc:oracle:thin:@localhost:1521:orcl
oracleUser=scott
oraclePwd=tiger
##mysql
mysqlDriver=com.mysql.jdbc.Driver
mysqlUrl=jdbc:mysql://localhost/test?characterEncoding=utf8
mysqlUser=root
mysqlPwd=root
监听器的代码一定要放在web.xml的最上面,这样才安全,不能放在Servlet标签的下面,这样就不对了。
运行后部分截图如下:
接下来要说的是过滤器,我觉得这个名字起的让我这种初学者很难理解,不过,现在理解了就觉得这个名字起的还蛮不错的啦,现在假如用户刚刚登录一个网站就突然有事出去了,两个小时以后回来了,回来了以后点击网页上的一个超链接,发现又跳转到了登录页面,这个可以用过滤器来做,这个例子举的不是很好,再举另外一个,那就是servlet 中的request,response中文乱码的问题,如果没有过滤器,那么我们要在每个servlet中都要写上request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");...,有了过滤器以后,我们就可以把检查和设置编码方式的问题放在过滤器中,这样就不用每个Servlet里面都要写上面两行代码啦,每次有request请求过来都会经过过滤器,如果满足要求,就会放行,如果不满足要求,就会返回给客户端相应的信息,这个过程是可以控制的,我们也可以对request做一些调整,比如调整编码方式。不知道对过滤器不明白的听了我自己的理解以后对它有没有理解,如果还没有的话,那么就看看下面的代码吧!
要写自己的过滤器必须要实现Filter接口,实现它的方法:init,doFilter和destroy三个方法,与上面的监听器的加载类似,服务启动的时候调用init方法,我们把主要代码放在doFilter方法中,destroy方法服务器关闭的时候调用。代码如下:
package com.bjsxt.webservice; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.bjsxt.javabean.User; public class ServletFilter implements Filter { @Override public void destroy() { System.out.println("过滤器关闭中。。。"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; // System.out.println(req.getRequestURI());
//只对servlet进行过滤,对.js,.jsp文件不过滤,直接放行 if(!req.getRequestURI().contains(".")){ req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8");
//下面这句话可以加,可以不加,主要看具体返回的格式是否统一,如果不统一,就不用加,比如,用到jQuery时,可能会返回application/json格式,也可能会返回text/html格式, //就会用加了
// resp.setContentType("text/html;charset=utf-8"); User u = (User) req.getAttribute("user"); if(u==null){ req.getRequestDispatcher("login.jsp").forward(req, resp); return; } }
//有这句话才会经过过滤器往下执行,没有就不会往下执行了 chain.doFilter(req, resp); } @Override public void init(FilterConfig config) throws ServletException { System.out.println("过滤器开始启动"); } }
web.xml代码如下:
<filter> <filter-name>encode</filter-name> <filter-class>com.bjsxt.webservice.ServletFilter</filter-class> </filter> <filter-mapping> <filter-name>encode</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
这个配置要放在监听器配置下面,Servlet配置上面,这样不会出错。
运行结果是页面跳转,用户没有登录的话就会跳转到登录页面,不过这个过滤器有一个Bug,就是如果用户没有登录,则跳转到登录页面以后也有可能会登录不了,因为没有设置这个servlet除外,不过在这里只是用来说明和备忘的,不加也没有关系啦,嘻嘻。
除了上面说的监听器和过滤器可以在服务启动的时候加载外,servlet也可以设置在服务启动的时候就加载,这要对web.xml中的Servlet标签设置<load-on-startup>100</load-on-startup> ,设置的值只要大于等于0就好,小于0则不会被加载,大于0时,如果值越小,则加载的优先级越高,所以通常设置在100左右,这样可以在前后都留点空间。