目录:(点击红色方框展开子目录)

  • Filter API

  • Filter详解
    • 过滤器配置
    • 四种拦截方式
  • 经典案例
    • 分IP统计网站的访问次数
    • 粗粒度权限控制
    • 解决全站字符乱码
    • 页面静态化
  • 使用@WebFilter注解取代web.xml进行对filter的配置


Filter API

@过滤器( filter)是JavaWeb三大组件之一 ,作用是拦截请求,在访问指定目标资源(如Servlet、JSP、css、html)之前先执行过滤器中的操作 。

@过滤流程 是服务器启动后,自动创建Filter接口的实例对象,并进行初始化,我们编写一个filter类继承该实例对象,并且重写其doFilter方法,在此方法中添加过滤规则 。 当客户端每次要访问目标资源时,Servlet容器都会调用Filter接口的实例对象的doFilter方法,也就是会调用我们自己重写的doFilter方法,在此方法中,如果符合规则,则调用FilterChain对象的doFilter方法,表示这个过滤器对该请求进行放行,可以去执行下一个过滤器的生命周期方法中的doFilter方法。 如果下一个过滤器也放行的话,就再去执行下下个过滤器,知道通过了所有过滤器的考验,最终访问到目标资源

过滤器的详解

@过滤器的配置在Servet2.5及以前版本都需要在web.xml中进行配置 ,一个目标资源可以添加多个过滤器,也就是多个过滤规则 ,只有全部通过了,请求才能到达目标资源

 1   <filter>
 2     <filter-name>第一个过滤器类名字</filter-name>
 3     <filter-class>包.类</filter-class>
 4   </filter>
 5   <filter-mapping>
 6     <filter-name>第一个过滤器类名字</filter-name>
 7     <url-pattern>要过滤的目标资源A</url-pattern>
 8   </filter-mapping>
 9   <filter>
10     <filter-name>第二个过滤器类名字</filter-name>
11     <filter-class>包.类</filter-class>
12   </filter>
13   <filter-mapping>
14     <filter-name>第二个过滤器类名字</filter-name>
15     <url-pattern>要过滤的目标资源A</url-pattern>
16   </filter-mapping>

@多个过滤器的执行顺序 是按照配置的先后顺序执行的

@四种拦截方式 ,假如: 我们编写一个过滤器用来过滤资源A,当我们直接访问该资源A时就会被过滤,但是当我们间接访问资源A(比如: 在其他页面用转发的形式间接访问资源A)时,过滤器不会执行。 所以有时候我们要定义我拦截方式。

拦截方式 说明
REQUEST 直接访问目标资源时执行过滤器 ,默认
FORWARD 转发访问执行过滤器
INCLUDE 包含访问执行过滤器
ERROR

当目标资源在web.xml中配置为<error-page>中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。

在<filter-mapping>中添加0~n个<dispatcher>子元素,来说明当前访问的拦截方式。

<filter-mapping><filter-name>过滤器名字</filter-name><url-pattern>目标资源路径</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher>
</filter-mapping>

经典案例_分IP统计网站的访问次数

@说明 网站的访问次数绝不可能随着浏览器的关闭而重置为0,因为和服务器的寿命是一样的,所以必须用Application域 。而访问次数与IP有关系,最好放在map中,即map<ip地址,访问次数>,而这个map又必须是在服务器启动时就需要创建并且要保存到Application域中以供使用,所以需要监听器

@注意 类名包名等路径随自己的项目更改

 1 package cn.kmust.web.demo1.filter;
 2
 3 import java.io.IOException;
 4 import java.util.LinkedHashMap;
 5 import java.util.Map;
 6
 7 import javax.servlet.Filter;
 8 import javax.servlet.FilterChain;
 9 import javax.servlet.FilterConfig;
10 import javax.servlet.ServletContext;
11 import javax.servlet.ServletException;
12 import javax.servlet.ServletRequest;
13 import javax.servlet.ServletResponse;
14
15 /**
16  * 过滤器  [分IP统计访问次数案例]
17  * @功能 在访问a.jsp和b.jsp资源之前,进行分ip统计访问次数
18  *    统计功能不需要拦截,所以放行,web.xml中为了不与其他demo项目冲突,
19  *         所以拦截对象只是本例的demo1_show.jsp
20  * @author ZHAOYUQIANG
21  *
22  */
23 public class CountFilter implements Filter {
24     private FilterConfig config ;
25
26     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
27         /*
28          * 1. 得到application对象
29          * 2. 获取application域中的Map
30          * 3. 从request中获取当前客户端的IP地址
31          * 4. 查看Map中是否存在这个IP对应的访问次数,
32          *     如果存在,获取访问次数,+1
33          * 5. 如果不存在ip,说明第一次访问,设置访问次数为1
34          * 6. 操作完成后,再把map放回到application中
35          * 7. 这个过滤器不需要拦截,所以放行
36          */
37         ServletContext app = config.getServletContext();
38         Map<String,Integer> map = (Map<String , Integer>)app.getAttribute("map");
39         String ip  = request.getRemoteAddr();
40         if(map.containsKey(ip)){
41             int cnt = map.get(ip);
42             map.put(ip, cnt+1);
43         }else{
44             map.put(ip, 1);
45         }
46         app.setAttribute("map", map);
47         chain.doFilter(request, response);
48     }
49
50     /**
51      * 在服务器启动时执行
52      *   保存config对象
53      */
54     public void init(FilterConfig fConfig) throws ServletException {
55         this.config = fConfig ;
56
57     }
58     public void destroy() {
59         // TODO Auto-generated method stub
60     }
61
62 }

CountFilter

 1 package cn.kmust.web.demo1.listerner;
 2
 3 import java.util.LinkedHashMap;
 4 import java.util.Map;
 5
 6 import javax.servlet.ServletContext;
 7 import javax.servlet.ServletContextEvent;
 8 import javax.servlet.ServletContextListener;
 9
10 /**
11  * 监听器   [项目统计按IP分类为统计访问人数的辅助类]
12  * @功能 创建Map,保存到application域中
13  *     分IP查询,Map的类型为Map<IP地址,访问次数> ; 因为访问次数是项目整体范围,所以保存到application域中
14  * @author ZHAOYUQIANG
15  *
16  */
17 public class CountListerner implements ServletContextListener {
18     /**
19      * 在服务器启动时创建Map,保存到ServletContext中
20      */
21     public void contextInitialized(ServletContextEvent sce) {
22         /*
23          * 1. 创建Map<IP地址,访问次数>
24          * 2. 通过ServletContextEvent对象获取ServletContext
25          * 3. 把Map保存到application中
26          */
27         Map<String,Integer> map = new LinkedHashMap<String, Integer>();
28         ServletContext application = sce.getServletContext();
29         application.setAttribute("map", map);
30     }
31
32     public void contextDestroyed(ServletContextEvent arg0) {
33         // TODO Auto-generated method stub
34     }
35
36 }

CountListerner

<body><h1><center>显示结果</center></h1><table align="center" width="60%" border="1"><tr><th>IP</th><th>次数</th></tr>
<c:forEach items="${applicationScope.map }" var="entry"><tr><td>${entry.key }</td><td>${entry.value }</td></tr>
</c:forEach></table></body>

测试页面

<filter><display-name>CountFilter</display-name><filter-name>CountFilter</filter-name><filter-class>cn.kmust.web.demo1.filter.CountFilter</filter-class></filter><filter-mapping><filter-name>CountFilter</filter-name><url-pattern>/demo1_show.jsp</url-pattern></filter-mapping><listener><listener-class>cn.kmust.web.demo1.listerner.CountListerner</listener-class></listener>

配置

经典案例_粗粒度权限控制

@说明 防止为登陆的用户访问主页, /user/userindex.jsp是目标资源 ,如果为登陆的用户直接访问该资源,则打回到登陆页面

@注意 类名包名等路径随自己的项目更改

 1 package cn.kmust.webfilter.web.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 /**
13  * 过滤器 用来 ,对/user/userindex.jsp进行过滤
14  * @功能 当有请求访问userindex.jsp时,先检查session域中有没有用户名,如果有则放行,如果没有,则拦截,并且打回
15  * @author ZHAOYUQIANG
16  *
17  */
18 public class LoginFilter implements Filter {
19     public void destroy() {
20     }
21     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
22         //因为用的是Http协议的请求,所以需要把过滤器中的ServletRequest转换成Http协议的
23         HttpServletRequest req = (HttpServletRequest) request;
24         //从session域中获取用户名
25         String name  = (String) req.getSession().getAttribute("session_user");
26         if(name != null ){
27             chain.doFilter(request, response);
28         }else{
29             req.getRequestDispatcher("/user/userlogin.jsp").forward(request, response);
30         }
31         chain.doFilter(request, response);
32     }
33     public void init(FilterConfig fConfig) throws ServletException {
34
35     }
36 }

filter

 1 package cn.kmust.webfilter.web.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 /**
13  * 过滤器 用来 ,对/user/userindex.jsp进行过滤
14  * @功能 当有请求访问userindex.jsp时,先检查session域中有没有用户名,如果有则放行,如果没有,则拦截,并且打回
15  * @author ZHAOYUQIANG
16  *
17  */
18 public class LoginFilter implements Filter {
19     public void destroy() {
20     }
21     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
22         //因为用的是Http协议的请求,所以需要把过滤器中的ServletRequest转换成Http协议的
23         HttpServletRequest req = (HttpServletRequest) request;
24         //从session域中获取用户名
25         String name  = (String) req.getSession().getAttribute("session_user");
26         if(name != null ){
27             chain.doFilter(request, response);
28         }else{
29             req.getRequestDispatcher("/user/userlogin.jsp").forward(request, response);
30         }
31         chain.doFilter(request, response);
32     }
33     public void init(FilterConfig fConfig) throws ServletException {
34
35     }
36 }

servlet

1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2 <body>
3   <h2>用户名字是user,密码是123</h2>
4     <form action ="<c:url value="/LoginServlet"/>" method="post">
5       <input type="text" name="username"/><br>
6       <input type="password" name="password"/><br>
7       <input type="submit" name="登陆"/>
8     </form>
9   </body>

login

<body><h1><center>这是用户主页,没有登陆的用户是不能直接访问该页的</center></h1></body>

userindex

<filter><display-name>LoginFilter</display-name><filter-name>LoginFilter</filter-name><filter-class>cn.kmust.webfilter.web.filter.LoginFilter</filter-class></filter><filter-mapping><filter-name>LoginFilter</filter-name><url-pattern>/LoginFilter</url-pattern></filter-mapping><filter-mapping><filter-name>LoginFilter</filter-name><url-pattern>/user/userindex.jsp</url-pattern></filter-mapping>

配置

经典案例_解决全站字符乱码

@说明 servlet处理post和get请求编码可以写在过滤器中,但是post和get编码的处理方式不是一样的,所以需要对request进行装饰,所以编写了EncodingRequest类来对request进行装饰,来帮助过滤器完成对get请求的编码 。

<%--get请求,传递过去method参数,指明调用TestServlet的fun2方法,并且传递一个参数param--%>
<a href="<c:url value='/GetServlet?param=哈哈'/>"> 这是get请求</a>
<%--post请求--%>
<form action="<c:url value='/PostServlet'/>" method="post"><input type="text" name="param" value="我是表单参数" /><input type="submit" name="提交"/>
</form>

提交页面

 1 package cn.kmust.webfilter.web.servlet;
 2 import java.io.IOException;
 3
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 /**
 9  *  post请求访问的Servlet,在过滤器中会进行编码的处理 
10  *  获取参数,转发到显示页面
11  * @author ZHAOYUQIANG
12  *
13  */
14 public class PostServlet extends HttpServlet {
15
16     public void doPost(HttpServletRequest request, HttpServletResponse response)
17             throws ServletException, IOException {
18          request.setAttribute("param", request.getParameter("param"));
19          request.getRequestDispatcher("/show.jsp").forward(request, response);
20     }
21 }

PostServlet

package cn.kmust.webfilter.web.servlet;
import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/***  get请求访问的Servlet,在过滤器中会进行编码的处理 *  获取参数,转发到显示页面* @author ZHAOYUQIANG**/
public class GetServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String  param = request.getParameter("param");request.setAttribute("param", param);request.getRequestDispatcher("/show.jsp").forward(request, response);}
}

GetServlet

package cn.kmust.webfilter.web.filter;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 cn.kmust.webfilter.utils.EncodingRequest;/*** 解决乱码的过滤器,servlet处理post和get乱码的操作,全都在这儿处理* @author ZHAOYUQIANG**/
public class EncodingFilter implements Filter {public void destroy() {}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {/** 处理post请求乱码问题*/request.setCharacterEncoding("utf-8");/** 处理GET请求编码问题*   String name1 =  request.getParameter("name");*   name2 = new String(name.getBytes("ISO-8859-1"),"utf-8");*    GET不一样,设置编码后,servlet中获取name,获取应该是name2,都是如果如上写的话,*     getParameter("name")获取的是name1 .* 掉包request*    1. 写一个request的装饰类*    2. 放行时,使用我们自己的request*    3. 但是POST方式依然使用request*/HttpServletRequest req = (HttpServletRequest) request ;if(req.getMethod().equals("GET")){EncodingRequest er = new EncodingRequest(req);     chain.doFilter(er, response);}else if(req.getMethod().equals("POST")){chain.doFilter(request, response);}
//        response.setContentType("text/html;charset=UTF-8");
    }public void init(FilterConfig fConfig) throws ServletException {// TODO Auto-generated method stub
    }
}

EncodingFilter

package cn.kmust.webfilter.utils;import java.io.UnsupportedEncodingException;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/*** 辅助过滤器来处理GET编码问题* @author ZHAOYUQIANG**/
public class EncodingRequest extends HttpServletRequestWrapper{
private HttpServletRequest request ;public EncodingRequest(HttpServletRequest request) {super(request);this.request = request ;}/*** 处理编码问题*/public String getParameter(String name) {String value = request.getParameter(name);/** 处理编码问题*/try {value = new String (value.getBytes("ISO-8859-1"),"utf-8");} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blockthrow new RuntimeException(e);}        return value;}}

EncodingRequest

 ${requestScope.param }

显示页面

<filter><display-name>EncodingFilter</display-name><filter-name>EncodingFilter</filter-name><filter-class>cn.kmust.webfilter.web.filter.EncodingFilter</filter-class></filter><filter-mapping><filter-name>EncodingFilter</filter-name><url-pattern>/EncodingFilter</url-pattern></filter-mapping><filter-mapping><filter-name>EncodingFilter</filter-name><url-pattern>/GetServlet</url-pattern></filter-mapping><filter-mapping><filter-name>EncodingFilter</filter-name><url-pattern>/PostServlet</url-pattern></filter-mapping>

过滤器配置

经典案例_页面静态化

@说明 (页面静态化是什么请自行百度,这儿不做累述),我们做一个过滤器,让其访问servlet时判断是否符合静态化页面的要求 。如果是,则让其直接访问静态化的页面,如果不是,则继续访问资源。

CREATE TABLE `t_book` (`bid` char(32) NOT NULL,`bname` varchar(100) DEFAULT NULL,`price` decimal(10,2) DEFAULT NULL,`category` int(11) DEFAULT NULL,PRIMARY KEY (`bid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert  into `t_book`(`bid`,`bname`,`price`,`category`) values ('b1','JavaSE_1','10.00',1),('b2','JavaSE_2','15.00',1),('b3','JavaSE_3','20.00',1),('b4','JavaSE_4','25.00',1),('b5','JavaEE_1','30.00',2),('b6','JavaEE_2','35.00',2),('b7','JavaEE_3','40.00',2),('b8','Java_framework_1','45.00',3),('b9','Java_framework_2','50.00',3);

数据库

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config><default-config><!-- 这是默认的配置信息 --><!-- 连接四大参数配置 --><property name="jdbcUrl">jdbc:mysql://localhost:3306/filtertest</property><property name="driverClass">com.mysql.jdbc.Driver</property><property name="user">root</property><property name="password">123456</property><!-- 池本身的参数配置 --><property name="acquireIncrement">3</property><property name="initialPoolSize">10</property><property name="minPoolSize">2</property><property name="maxPoolSize">10</property></default-config><!-- 专门为oracle准备的配置信息 --><!-- 这也是命名配置信息,在JDBC中创建连接池对象的时候要加 oracle-config这个参数--><named-config name="oracle-config"><property name="jdbcUrl">  oracle的url   </property><property name="driverClass">  oracle的驱动   </property><property name="user">    oracle的用户 </property><property name="password">    密码</property><property name="acquireIncrement">3</property><property name="initialPoolSize">10</property><property name="minPoolSize">2</property><property name="maxPoolSize">10</property></named-config></c3p0-config>

c3p0配置

1 <h1>链接页面</h1>
2 <%--Get方式,向页面传递method参数和方法中的参数 --%>
3 <a href="<c:url value='/BookServlet?method=findAll'/>">查询所有</a><br/>
4 <a href="<c:url value='/BookServlet?method=findByCategory&category=1'/>">查询SE</a><br/>
5 <a href="<c:url value='/BookServlet?method=findByCategory&category=2'/>">查询EE</a><br/>
6 <a href="<c:url value='/BookServlet?method=findByCategory&category=3'/>">查询Framework</a><br/>

提交页面

 1  <h1 align="center">图书列表</h1>
 2   <table border="1" align="center" width="50%">
 3     <tr>
 4         <th>书名</th>
 5         <th>单价</th>
 6         <th>分类</th>
 7     </tr>
 8 <c:forEach items="${bookList }" var="book">
 9     <tr>
10         <td>${book.bname }</td>
11         <td>${book.price }</td>
12         <%--每个分类都是不同的颜色 --%>
13         <c:choose>
14           <c:when test="${book.category eq 1 }"><td style="color:red">JavaSE</td></c:when>
15           <c:when test="${book.category eq 2 }"><td style="color:blue">JavaEE</td></c:when>
16           <c:when test="${book.category eq 3 }"><td style="color:green">JaveFrameWork</td></c:when>
17         </c:choose>
18         <td>${book.category }</td>
19     </tr>
20 </c:forEach>
21   </table>

显示页面

 1 package cn.kmust.book.web.servlet;
 2
 3 import java.io.IOException;
 4
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8
 9 import cn.itcast.servlet.BaseServlet;
10 import cn.kmust.book.dao.BookDao;
11 /**
12  * servlet层
13  * @功能 把查询到的图书放到request域中,转发到list.jsp中显示
14  * @author ZHAOYUQIANG
15  *
16  */
17 public class BookServlet extends BaseServlet {
18     private BookDao bookDao = new BookDao();
19     /**
20      * 查询所有图书
21      * @param request
22      * @param response
23      * @return
24      * @throws ServletException
25      * @throws IOException
26      */
27     public String findAll(HttpServletRequest request,HttpServletResponse response)
28              throws ServletException,IOException{
29         request.setAttribute("bookList", bookDao.findAll());
30         return "/list.jsp" ;
31     }
32     /**
33      * 按分类条件查询图书
34      * @param request
35      * @param response
36      * @return
37      * @throws ServletException
38      * @throws IOException
39      */
40     public String findByCategory(HttpServletRequest request,HttpServletResponse response)
41              throws ServletException,IOException{
42         String value = request.getParameter("category");
43         int category = Integer.parseInt(value);
44         request.setAttribute("bookList", bookDao.findByCategorys(category));
45         return "/list.jsp" ;
46     }
47
48 }

servlet

 1 package cn.kmust.book.web.filter;
 2
 3 import java.io.File;
 4 import java.io.IOException;
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletContext;
 9 import javax.servlet.ServletException;
10 import javax.servlet.ServletRequest;
11 import javax.servlet.ServletResponse;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14
15 import cn.kmust.book.utils.StaticResponse;
16 /**
17  * 过滤器
18  * @功能 /BookServlet, 访问Servlet之前,进行判断,如果静态化页面存在,过滤器直接拦截下来,直接让它访问该静态化页面,避免继续往下访问serlvet去查询数据库。
19  *      如果静态化页面不存在(第一次访问),此时,生成新的静态化页面 ,过滤器放行, 放行之后,servlet会通过访问dao层查询数据库得到查询的数据,这个时候servlet会向list.jsp页面输出数据,但是
20  *        我们不能让list.jsp输出,而是想办法让新的静态化页面做输出。
21  * @解决问题 如何不能让list.jsp输出,而是让新的静态化页面做输出 ?
22  *           jsp的输出实际上是out.write("<html>"),而这个out流底层就是response的getWriter()(注意,区分开Out内置对象)。
23  *             就是因为这个out流,jsp中的out.write()才会输出在jsp页面中 。假如我们改变了out流,让这个流与我们指定静态页面绑定,那么
24  *                jsp中的out流就会向定的静态页面中输出,这个过程就做调包response 。
25  *                   毕竟response在一个请求中是不变的,用的同一个,所以我们用调包后的response来操作就完成了解决了这个问题
26  * @解决问题  新的html页面会产生乱码问题 。 所以需要jsp页面中添加<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
27  *
28  * @author ZHAOYUQIANG
29  *
30  */
31 public class StaticFilter implements Filter {
32     private FilterConfig config ;
33     public void destroy() {}
34     public void init(FilterConfig fConfig) throws ServletException {
35         this.config = fConfig ;
36     }
37     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
38         /*
39          * 把request和response转换成HttpServlet类型的
40          */
41         HttpServletRequest req = (HttpServletRequest) request ;
42         HttpServletResponse res = (HttpServletResponse) response;
43         /*
44          * 1. 获取category参数,变成对应的文件名称
45          *     category有四种值,分别对应四个静态化的页面
46          *       null--> null.html
47          *       1--> 1.html
48          *       2--> 2.html
49          *       3--> 3.html
50          * 2. 获取文件所在目录路径
51          *       FilterConfig对象的getServletContext()能够获取ServletContext对象
52          * 3. 用路径和文件名称 创建一个新的文件
53          * 4. 判断该新文件是否存在,如果文件存在,重定向到这个文件
54          *
55          */
56         String category = request.getParameter("category");
57         String htmlPage = category+".html" ;
58         String htmlPath = config.getServletContext().getRealPath("/htmls");
59         File destFile = new File(htmlPath,htmlPage);
60         if(destFile.exists()){
61             res.sendRedirect(req.getContextPath()+"/htmls/"+htmlPage);
62             return ;
63         }
64         /*
65          * 5. 如果该新文件不存在,调包response
66          *      把新文件的路径传递过去,让out流与其路径绑定
67          * 6. 放行
68          *     在放行后,程序访问servlet,查询到数据,因为sr是调包后的response(response的getWriter()方法产生的out流与指定html绑定的),
69          *        那么,数据都输出到指定的静态页面中了。这个时候浏览器是不显示这个页面的,用户也是看不到的
70          * 7. 来一个重定向,让浏览器去显示这个静态页面
71          */
72         StaticResponse sr = new StaticResponse(res, destFile.getAbsolutePath());
73         chain.doFilter(request, sr);
74         res.sendRedirect(req.getContextPath()+"/htmls/"+htmlPage);
75
76     }
77
78 }

filter

package cn.kmust.book.utils;import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/*** 调包response *    让getWriter()与传递过来的路径绑定* @author ZHAOYUQIANG**/
public class StaticResponse extends HttpServletResponseWrapper {private PrintWriter pw ;/*** 创建一个与html文件路径在一起的流对象* String path表示的是html文件路径* * @param response* @param path* @throws UnsupportedEncodingException * @throws FileNotFoundException */public StaticResponse(HttpServletResponse response,String path) throws FileNotFoundException, UnsupportedEncodingException {super(response);pw = new PrintWriter(path,"utf-8");}/*** 返回一个与html绑定在一起的printWriter对象*  jsp会使用它进行输出,这样数据都输出到了静态html页面中了*/public PrintWriter getWriter(){return pw;}}

调包response,辅助过滤器

关于dao层和servic层页面不再给出源码,大家可以直接下载完整项目源码:

@本项目源码使用说明 本代码第一次访问,查看各种分类 时,会访问数据库,获取资源,并且在htmls文件下建立静态化页面,可以去tomcat目录下的htmls下查看。 当再次访问该页面时候,直接重定向到该静态页面,不需要再去访问数据库了 。

@全部项目源码下载地址  https://files.cnblogs.com/files/zyuqiang/%E9%A1%B9%E7%9B%AE.zip

Servlet3.0新特性 之 使用@WebFilter注解取代web.xml进行对filter的配置

点击这里   请去Servlet3.0新特性中学习

转载于:https://www.cnblogs.com/zyuqiang/p/7411526.html

《JavaWeb从入门到改行》过滤器学习笔记相关推荐

  1. 《Angular4从入门到实战》学习笔记

    <Angular4从入门到实战>学习笔记 腾讯课堂:米斯特吴 视频讲座 二〇一九年二月十三日星期三14时14分 What Is Angular?(简介) 前端最流行的主流JavaScrip ...

  2. 《Java Web开发入门很简单》学习笔记

    <Java Web开发入门很简单>学习笔记 1123 第1章 了解Java Web开发领域 Java Web主要涉及技术包括:HTML.JavaScript.CSS.JSP.Servlet ...

  3. unity3D-游戏/AR/VR在线就业班 C#入门访问修饰符学习笔记

    unity3D-游戏/AR/VR在线就业班 C#入门访问修饰符学习笔记 点击观看视频学习:http://edu.csdn.NET/lecturer/107 访问修饰符 public --公共的,在哪里 ...

  4. 【台大郭彦甫】Matlab入门教程超详细学习笔记二:基本操作与矩阵运算(附PPT链接)

    Matlab入门教程超详细学习笔记二:基本操作与矩阵运算 前言 一.基本操作 1.把matlab当作计算器使用 2.变量 3.控制格式输出 二.矩阵运算 1.矩阵 2.矩阵索引 3.使用:创建向量 4 ...

  5. 阿里云“7天实践训练营”入门班第二期学习笔记 第五天 在线编程挑战

    阿里云"7天实践训练营"入门班第二期学习笔记 第五天 在线编程挑战 吾辈,完全不会编程 以下内容全程来自阿里云社区的大佬分析讲解 原题目 知识点:搜索.字符串.位运算 有一天Jer ...

  6. 《Angular4从入门到实战》学习笔记(图文)

    <Angular4从入门到实战>学习笔记 腾讯课堂:米斯特吴 视频讲座 二〇一九年二月十三日星期三14时14分 What Is Angular?(简介) 前端最流行的主流JavaScrip ...

  7. 深度学习者的入门福利-Keras深度学习笔记

    Keras深度学习笔记 最近本人在github上发现一个不错的资源,是利用keras来学习深度学习的笔记,笔记内容充实,数据完善,本人亲自实操了里面的所有例子,深感收获颇丰,今天特意推荐给大家,希望能 ...

  8. vim从入门到丝滑学习笔记

    vim学习笔记 入门 vim模式:(界面左下角有显示) api帮助文档 Ctrl+S造成vim假卡死 基本指令 operator操作符 motion动作 移动 水平移动(行内) 垂直移动(行间) 编辑 ...

  9. python人工智能入门纳米学位_学习笔记(一) - 机器学习纳米学位

    不久前我在Udacity报名了数据分析和机器学习两门纳米课程.之所以对这个感兴趣是因为关注人工智能方面的资讯有一段时间了,觉得这是未来的趋势,希望今后能够在这方面有所成绩.选择纳米课程是因为我觉得它与 ...

  10. 入门PCB设计AD9学习笔记8-PCB布板规则

    写作前面: 最近在学PCB设计,发现杜洋工作室的入门PCB设计讲的非常详细,适合初学者.由于是视频讲解形式,不利于后期再索引搜索各个知识点细节,所以这里做上笔记方便自己消化和之后内容的索引.惊喜发现已 ...

最新文章

  1. phpexcel导出超过26列解决方案
  2. C语言中冒泡排序及优化
  3. html 查询表单,如何让我的HTML表单查询适用于所有表单元素?
  4. 无法将类型为“System.__ComObject”的 COM 对象强制转换为类类型“mshtml.HTMLInputElementClass...
  5. 递归-递归的特点及基本代码演练
  6. 写出完美CSS代码的5个重要方面
  7. android 自定义透明 等待 dialog,Android自定义Dialog内部透明、外部遮罩效果
  8. 微型计算机方面的论文,微型计算机论文.doc
  9. hdu 1232 畅通工程
  10. 软件测试前景会被ai取代吗_软件测试人员可能很快会被AI程序取代
  11. 高通Android camera驱动框架
  12. POS收单地区代码表(2015年3月版)
  13. Word另存为pdf时提示“由于出现意外错误,导出失败”的解决方案
  14. 利用PPT制作PNG透明图片
  15. 怎样开通gmail邮箱smtp服务
  16. 如何彻底卸载xcode
  17. 独立键盘检测,矩阵键盘检测
  18. 那些SAP项目里的主流外围系统
  19. 问题解决:opencv imwrite图片保存为黑色
  20. Linux文件系统:minix文件系统二进制分析4(rm删除)

热门文章

  1. 适合ipad的python编程软件-iPad编程软件推荐(一) —— Pythonista 3
  2. 【17ce】运维站点监测和测速网站
  3. gta5股票服务器维护,各位大佬问一下GTA5 股票里的BAWSAQ为什么一直维护啊
  4. php table生成图片,php不用GD库生成当前时间的PNG格式图象的程序
  5. Quorum Raft
  6. metricbeat指标简介
  7. Github docker源码之代码文件docker/image的解读
  8. 独热编码python实现_独热编码(one-hot coding)
  9. win10使用easybcd误删引导进不去系统解决办法
  10. 【C++/笔试】传统OJ / ACM模式 读取输入总结