目录
[1.2Filter 相关API](#1.2Filter 相关API)
[1. 2.1Filter 接口](#1. 2.1Filter 接口)
[1.2.2 FilterConfig 接口](#1.2.2 FilterConfig 接口)
[1.2.3 FilterChain 接口](#1.2.3 FilterChain 接口)
[1.3Filter 的生命周期](#1.3Filter 的生命周期)
[1.5Filter 映射](#1.5Filter 映射)
[1.5.1 使用通配符"*"拦截用户所有请求](#1.5.1 使用通配符“*”拦截用户所有请求)
[1.5.2 拦截不同访问方式的请求](#1.5.2 拦截不同访问方式的请求)
[1.6Filter 链](#1.6Filter 链)
[编辑1.7任务:Filter 在Cookie自动登录中的使用](#编辑1.7任务:Filter 在Cookie自动登录中的使用)
[1. 编写User类](#1. 编写User类)
[2. 实现登录页面和首页](#2. 实现登录页面和首页)
[3. 创建Servlet](#3. 创建Servlet)
[4. 创建过滤器](#4. 创建过滤器)
[5. 运行项目,查看结果](#5. 运行项目,查看结果)
[2.1 Listener 概述](#2.1 Listener 概述)
[2.2 Listener 的API](#2.2 Listener 的API)
[1. 创建监听器](#1. 创建监听器)
[package cn.itcast.chapter09.listener;import javax.servlet.*;import javax.servlet.annotation.WebListener;import javax.servlet.http.*;@WebListenerpublic class MyListener implements ServletContextListener, HttpSessionListener,ServletRequestListener { public void contextInitialized(ServletContextEvent arg0) { System.out.println("ServletContext对象被创建了"); } public void contextDestroyed(ServletContextEvent arg0) { System.out.println("ServletContext对象被销毁了"); } public void requestInitialized(ServletRequestEvent arg0) { System.out.println("ServletRequest对象被创建了"); } public void requestDestroyed(ServletRequestEvent arg0) { System.out.println("ServletRequest对象被销毁了"); } public void sessionCreated(HttpSessionEvent arg0) { System.out.println("HttpSession对象被创建了"); } public void sessionDestroyed(HttpSessionEvent arg0) { System.out.println("HttpSession对象被销毁了"); }}](#package cn.itcast.chapter09.listener;import javax.servlet.;import javax.servlet.annotation.WebListener;import javax.servlet.http.;@WebListenerpublic class MyListener implements ServletContextListener, HttpSessionListener,ServletRequestListener { public void contextInitialized(ServletContextEvent arg0) { System.out.println("ServletContext对象被创建了"); } public void contextDestroyed(ServletContextEvent arg0) { System.out.println("ServletContext对象被销毁了"); } public void requestInitialized(ServletRequestEvent arg0) { System.out.println("ServletRequest对象被创建了"); } public void requestDestroyed(ServletRequestEvent arg0) { System.out.println("ServletRequest对象被销毁了"); } public void sessionCreated(HttpSessionEvent arg0) { System.out.println("HttpSession对象被创建了"); } public void sessionDestroyed(HttpSessionEvent arg0) { System.out.println("HttpSession对象被销毁了"); }})
[2. 启动项目,查看ServletContext对象创建信息](#2. 启动项目,查看ServletContext对象创建信息)
[3. 关闭项目,查看ServletContext对象销毁信息](#3. 关闭项目,查看ServletContext对象销毁信息)
[4. 创建测试页面](#4. 创建测试页面)
[5. 设置监听超时信息](#5. 设置监听超时信息)
[6. 重启项目,查看结果](#6. 重启项目,查看结果)
[1. 创建项目,导入JAR包](#1. 创建项目,导入JAR包)
[2. 创建上传页面](#2. 创建上传页面)
[3. 创建Servlet](#3. 创建Servlet)
[4. 启动项目,查看运行结果](#4. 启动项目,查看运行结果)
[1. 创建下载页面](#1. 创建下载页面)
[2. 创建Servlet](#2. 创建Servlet)
[3. 创建下载目录及文件](#3. 创建下载目录及文件)
[4. 启动项目,查看结果](#4. 启动项目,查看结果)
1.Filter
1.1什么是Filter
在Servlet 高级特性中,Filter 被称为过滤器,它位于客户端和处理程序之间,能够对请求和响应进行检 查和修改,通常将请求拦截后进行一些通用的操作,例如,过滤敏感词汇、统一字符编码和实施安全控制等。 Filter 好比现实中的污水净化设备,专门用于过滤污水杂质。
当客户端对服务器资源发送请求时,服务器会根据过滤 规则进行检查,如果客户的请求满足过滤规则,则对客户请求进行拦截,对请求头和请求数据进行检查或修 改,并依次通过Filter 链,最后把过滤之后的请求交给处理程序。请求信息在过滤器链中可以被修改,也可 以根据客户端的请求条件不将请求发往处理程序。
Filter 除了可以实现拦截功能外,还可以提高程序的性能,在Web开发时,不同的Web资源中的过滤操 作可以放在同一个Filter中完成,这样可以不用多次编写重复的代码,从而提高了程序的性能。
1.2Filter 相关API
1. 2.1Filter 接口
1.2.2 FilterConfig 接口
1.2.3 FilterChain 接口
1.3Filter 的生命周期
- 创建阶段
2.执行阶段
3.销毁阶段
1.4实现Filter
(1)首先在IDEA中创建一个名为chapter09的Web项目,然后在该项目的src目录下创建一个名为 cn.itcast.chapter09.filter的包,最后在该包下创建一个名为MyServlet的Servlet类,用于在浏览器中输出"Hello MyServlet"。
package cn.itcast.chapter09.filter; import java.io.*; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; @WebServlet(name="MyServlet",urlPatterns = "/MyServlet") public class MyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("Hello MyServlet"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
在IDEA中使用Tomcat启动chapter09项目,在浏览器的地址栏中访问http://localhost:8080/chapter09 /MyServlet,可以看 到浏览器成功访问到了MyServlet程序,运行效果如图:
(2)在cn.itcast.chapter09.filter包中创建一个名为MyFilter 的Filter类,用于拦截MyServlet程序。
package cn.itcast.chapter09.filter; import java.io.*; import javax.servlet.Filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; @WebFilter(filterName = "MyFilter",urlPatterns = "/MyServlet") //@WebFilter(filterName = "MyFilter",urlPatterns = "/*")//拦截用户所以请求 public class MyFilter implements Filter { public void init(FilterConfig fConfig) throws ServletException { // 过滤器对象在初始化时调用,可以配置一些初始化参数 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用 PrintWriter out=response.getWriter(); out.println("Hello MyFilter"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
第6行代码使用@WebFilter注解配置需要拦截的资源,@WebFilter注解的属性filterName 用于设置Filter 的名称,urlPatterns 属性用于匹配用户请求的 URL。例如"/MyServlet"表示过滤器 MyFilter 会拦截发送到"/MyServlet"资源的请求。这个URL还可 以使用通配符"*"表示。例如,"*.do"匹配所有以".do" 结尾的Servlet 路径。 在IDEA 中重新启动Tomcat 服务器,在浏览器的地 址栏中访问http://localhost:8080/chapter09/MyServlet,浏览 器窗口显示的结果如图所示:
1.5Filter 映射
1.5.1 使用通配符"*"拦截用户所有请求
如果想让过滤器拦截用户所有请求,可以使用通配符"*"实现。下面修改文件MyFilter的代码以实现拦截 用户所有请求的功能,修改后的代码如下所示:
package cn.itcast.chapter09.filter; import java.io.*; import javax.servlet.Filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; //@WebFilter(filterName = "MyFilter",urlPatterns = "/MyServlet") @WebFilter(filterName = "MyFilter",urlPatterns = "/*")//拦截用户所以请求 public class MyFilter implements Filter { public void init(FilterConfig fConfig) throws ServletException { // 过滤器对象在初始化时调用,可以配置一些初始化参数 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用 PrintWriter out=response.getWriter(); out.println("Hello MyFilter"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
1.5.2 拦截不同访问方式的请求
(1)在chapter09 项目的cn.itcast.chapter09.filter 包中,创建一个名为 ForwardServlet 的 Servlet 类,用于将 请求转发给first.jsp 页面。
package cn.itcast.chapter09.filter; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.WebServlet; @WebServlet(name = "ForwardServlet",urlPatterns = "/ForwardServlet") public class ForwardServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/first.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
(2)在chapter09 项目的 web目录下创建名称为first的JSP 页面,用于输出内容。
<html> <head></head> <body> first.jsp </body> </html>
(3)在cn.itcast.chapter09.filter 包中,创建一个过滤器 ForwardFilter.java,专门用于对 first.jsp 页面的请求 进行拦截。
package cn.itcast.chapter09.filter; import java.io.*; import javax.servlet.*; import javax.servlet.annotation.WebFilter; @WebFilter(filterName = "ForwardFilter",urlPatterns = "/first.jsp") //@WebFilter(filterName = "ForwardFilter",urlPatterns = "/first.jsp", dispatcherTypes = DispatcherType.FORWARD) public class ForwardFilter implements Filter { public void init(FilterConfig fConfig) throws ServletException { // 过滤器对象在初始化时调用,可以配置一些初始化参数 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用 PrintWriter out=response.getWriter(); out.write("Hello FilterTest"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
(4)在IDEA中启动Tomcat服务器,在浏览器中输入地址http://localhost:8080/chapter09/ForwardServlet 访 问ForwardServlet,浏览器显示的结果如图9-4 所示:
(5)如果要拦截ForwardServlet 类通过forward( )方法转发到first.jsp 页面的请求,可以在@WebFilter 注解 中设置 dispatcherTypes 属性值为 FORWARD。修改文件 9-6 中第 5 行代码,在@WebFilter 注解中设置 dispatcherTypes 属性值为 FORWARD,具体代码如下:
package cn.itcast.chapter09.filter; import java.io.*; import javax.servlet.*; import javax.servlet.annotation.WebFilter; //@WebFilter(filterName = "ForwardFilter",urlPatterns = "/first.jsp") @WebFilter(filterName = "ForwardFilter",urlPatterns = "/first.jsp", dispatcherTypes = DispatcherType.FORWARD) public class ForwardFilter implements Filter { public void init(FilterConfig fConfig) throws ServletException { // 过滤器对象在初始化时调用,可以配置一些初始化参数 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用 PrintWriter out=response.getWriter(); out.write("Hello FilterTest"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
(6)在 IDEA 中重新启动 Tomcat 服务器,在浏览器的地址栏中再次输入地址 http://localhost:8080/ chapter09/ForwardServlet 访问 ForwardServlet,浏览器显示的结果如图 9-5 所示:
1.6Filter 链
(1)在chapter09项目的cn.itcast.chapter09.filter包中新建两个过滤器MyFilter01和MyFilter02,这两个过 滤器的实现分别如文件9-7和文件9-8所示:
MyFilter01.java
package cn.itcast.chapter09.filter; import java.io.*; import javax.servlet.*; import javax.servlet.annotation.WebFilter; @WebFilter(filterName = "MyFilter01",urlPatterns = "/MyServlet") public class MyFilter01 implements Filter { public void init(FilterConfig fConfig) throws ServletException { // 过滤器对象在初始化时调用,可以配置一些初始化参数 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用 PrintWriter out=response.getWriter(); out.println("Hello MyFilter01"); chain.doFilter(request, response); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
MyFilter02.java
package cn.itcast.chapter09.filter; import java.io.*; import javax.servlet.Filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; @WebFilter(filterName = "MyFilter02",urlPatterns = "/MyServlet") public class MyFilter02 implements Filter { public void init(FilterConfig fConfig) throws ServletException { // 过滤器对象在初始化时调用,可以配置一些初始化参数 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用 PrintWriter out = response.getWriter(); out.println("MyFilter02 Before"); chain.doFilter(request, response); out.println("MyFilter02 After"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
(2)在IDEA中重新启动Tomcat服务器,在浏览器地址栏 中输入 http://localhost:8080/chapter09/MyServlet 访问 MyServlet 类,浏览器窗口中显示的结果如图所示:
1.7任务:Filter 在Cookie自动登录中的使用
1. 编写User类
在chapter09 项目的src 目录下创建cn.itcast.chapter09.entity 包,在该包中新建 User 类,用于封装用户的 信息。User类的实现如文件9-9所示:
User.java
package cn.itcast.chapter09.entity; public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
2. 实现登录页面和首页
(1)在chapter09项目的web目录中创建名称为login的JSP文件,在该文件中编写一个用户登录表单。 用户登录表单需要填写用户名和密码,以及用户自动登录的时间。login.jsp页面的实现如文件9-10所示:
login.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" import="java.util.*"%> <html> <head></head> <center><h3>用户登录</h3></center> <body style="text-align: center;"> <form action="${pageContext.request.contextPath }/LoginServlet" method="post"> <table border="1" width="600px" cellpadding="0" cellspacing="0" align="center" > <tr> <td height="30" align="center">用户名:</td> <td> <input type="text" name="username" />${errerMsg }</td> </tr> <tr> <td height="30" align="center">密 码:</td> <td> <input type="password" name="password"> </tr> <tr> <td height="35" align="center">自动登录时间</td> <td><input type="radio" name="autologin" value="${60*60*24*31}"/>一个月 <input type="radio" name="autologin" value="${60*60*24*31*3}"/>三个月 <input type="radio" name="autologin" value="${60*60*24*31*6}"/>半年 <input type="radio" name="autologin" value="${60*60*24*31*12}"/>一年 </td> </tr> <tr> <td height="30" colspan="2" align="center"> <input type="submit" value="登录" /> <input type="reset" value="重置" /> </td> </tr> </table> </form> </body> <html>
(2)在chapter09项目的web根目录中创建名称为index的JSP文件用于显示登录的用户信息,如果没有 用户登录,在index.jsp页面中显示一个用户登录的超链接,如果用户已经登录,在index.jsp页面中显示登录 的用户名,以及一个注销的超链接。index.jsp页面的实现如文件9-11所示:
index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" import="java.util.*" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> <title>显示登录的用户信息</title> </head> <body> <br /> <center> <h3>欢迎光临</h3> </center> <br /> <br /> <c:choose> <c:when test="${sessionScope.user==null }"> <a href="${pageContext.request.contextPath}/login.jsp">用户登录</a> </c:when> <c:otherwise> 欢迎你,${sessionScope.user.username }! <a href="${pageContext.request.contextPath}/LogoutServlet">注销</a> </c:otherwise> </c:choose> <hr /> </body> </html>
3. 创建Servlet
(1)编写LoginServlet类
在chapter09项目的cn.itcast.chapter09.filter包中,编写LoginServlet类,用于处理用户的登录请求,如果 输入的用户名和密码正确,则发送一个用户自动登录的Cookie,并跳转到首页,否则提示输入的用户名或密 码错误,并跳转至登录页面(login.jsp),让用户重新登录。LoginServlet类的实现如文件9-12所示:
LoginServlet.java
package cn.itcast.chapter09.filter; import java.io.IOException; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import cn.itcast.chapter09.entity.User; @WebServlet(name = "LoginServlet",urlPatterns = "/LoginServlet") public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获得用户名和密码 String username = request.getParameter("username"); String password = request.getParameter("password"); // 检查用户名和密码 if ("itcast".equals(username) && "123456".equals(password)) { // 登录成功 // 将用户状态 user 对象存入 session域 User user = new User(); user.setUsername(username); user.setPassword(password); request.getSession().setAttribute("user", user); // 发送自动登录的cookie String autoLogin = request.getParameter("autologin"); if (autoLogin != null) { // 注意 cookie 中的密码要加密 Cookie cookie = new Cookie("autoLogin",username+"-"+password); cookie.setMaxAge(Integer.parseInt(autoLogin)); cookie.setPath(request.getContextPath()); response.addCookie(cookie); } // 跳转至首页 response.sendRedirect(request.getContextPath()+"/index.jsp"); } else { request.setAttribute("errerMsg", "用户名或密码错误"); request.getRequestDispatcher("/login.jsp") .forward(request,response); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
(2)编写LogoutServlet类
LogoutServlet.java
package cn.itcast.chapter09.filter; import java.io.IOException; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; @WebServlet(name = "LogoutServlet",urlPatterns = "/LogoutServlet") public class LogoutServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 用户注销 request.getSession().removeAttribute("user"); // 从客户端删除自动登录的cookie Cookie cookie = new Cookie("autoLogin", "msg"); cookie.setMaxAge(0); response.addCookie(cookie); response.sendRedirect(request.getContextPath()+"/index.jsp"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
4. 创建过滤器
AutoLoginFilter.java
package cn.itcast.chapter09.filter; import java.io.IOException; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.*; import cn.itcast.chapter09.entity.User; @WebFilter(filterName = "AutoLoginFilter",urlPatterns = "/*") public class AutoLoginFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; // 获得一个名为 autologin 的cookie Cookie[] cookies=request.getCookies(); String autologin = null; for (int i = 0;cookies != null && i < cookies.length; i++) { if ("autologin".equals(cookies[i].getName())) { // 找到了指定的cookie autologin = cookies[i].getValue(); break; } } if (autologin != null) { // 做自动登录 String[] parts = autologin.split("-"); String username = parts[0]; String password = parts[1]; // 检查用户名和密码 if ("itcast".equals(username)&& ("123456").equals(password)) { // 登录成功,将用户状态 user 对象存入 session域 User user = new User(); user.setUsername(username); user.setPassword(password); request.getSession().setAttribute("user", user); } } // 放行 chain.doFilter(request, response); } public void destroy() { } }
5. 运行项目,查看结果
(1)访问login.jsp页面 重启服务器,打开浏览器,在地址栏中输入http://localhost:8080/chapter09/login.jsp,浏览器窗口中会显示 一个用户登录的表单,如图所示:
(2)实现用户登录 在图9-8所示的登录表单中输入用户名"itcast"、密码"123456",并选择用户自动登录的时间,单击"登 录"按钮,便可完成用户自动登录。单击"登录"按钮之后,浏览器窗口会显示登录的用户名,如图所示:
(3)注销用户
单击图中的"注销"超链接,就可以注销当前的用户,注销之后浏览器显示的页面如图所示。
2.Listener
2.1 Listener 概述
在 Web 程序开发中,经常需要对某些事件进行监听,以便及时做出处理,例如监听鼠标单击事件、监 听键盘按下事件等。为此,Servlet 提供了监听器(Listener),专门用于监听 Servlet 事件。Listener 在监听过 程中会涉及几个重要的组成部分,具体如下:
(1)事件:用户的一个操作,例如单击一个按钮、调用一个方法、创建一个对象等。
(2)事件源:产生事件的对象。
(3)事件监听器:负责监听发生在事件源上的事件。
(4)事件处理器:监听器的成员方法,当事件发生的时候会触发对应的处理器(成员方法)
当用户执行一个操作触发事件源上的事件时,该事件会被事件监听器监听到,当监听器监听到事件发生 时,相应的事件处理器就会对发生的事件进行处理。
事件监听器的工作过程可分为以下几个步骤:
(1)将监听器绑定到事件源,也就是注册监听器。
(2)监听器监听到事件发生时,会调用监听器的成员方法,将事件对象传递给事件处理器,即触发事件 处理器。
(3)事件处理器通过事件对象获得事件源,并对事件源进行处理。
2.2 Listener 的API
2.3任务:监听域对象的生命周期
1. 创建监听器
在chapter09 项目的src 目录下创建一个cn.itcast.chapter09.listener 包,在该包中新建一个 MyListener 类, 用于实现ServletContextListener、HttpSessionListener和ServletRequestListener 三个监听器接口,并实现这些接 口中的所有方法:
MyListener.java
package cn.itcast.chapter09.listener;
import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
@WebListener
public class MyListener implements
ServletContextListener, HttpSessionListener,ServletRequestListener {
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContext对象被创建了");
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContext对象被销毁了");
}
public void requestInitialized(ServletRequestEvent arg0) {
System.out.println("ServletRequest对象被创建了");
}
public void requestDestroyed(ServletRequestEvent arg0) {
System.out.println("ServletRequest对象被销毁了");
}
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("HttpSession对象被创建了");
}
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("HttpSession对象被销毁了");
}
}
2. 启动项目,查看ServletContext对象创建信息
3. 关闭项目,查看ServletContext对象销毁信息
4. 创建测试页面
为了查看HttpSessionListener 和 ServletRequestListener 的运行效果,在 chapter09 项目的 web 目录中编写 一个名称为myjsp的JSP文件,具体代码如文件所示:
myjsp.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <html> <head> <title>this is MyJsp.jsp page</title> </head> <body> 这是一个测试监听器的页面 </body> </html>
5. 设置监听超时信息
6. 重启项目,查看结果
重新启动项目chapter09,再打开浏览器,在地址栏中输入 http://localhost:8080/chapter09/myjsp.jsp,访问 myjsp.jsp 页面,控制台窗口中显示的结果如图所示:
关闭访问myjsp.jsp 页面的浏览器窗口或保持浏览器窗口不刷新,与之对应的HttpSession 对象将在2 分 钟之后被销毁,控制台窗口显示的结果如图所示:
动手实践:实现文件上传
1. 创建项目,导入JAR包
2. 创建上传页面
form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>文件上传</title> </head> <body> <form action="UploadServlet" method="post" enctype="multipart/form-data"> <table width="600px"> <tr> <td>上传者</td> <td><input type="text" name="name" /></td> </tr> <tr> <td>上传文件</td> <td><input type="file" name="myfile" /></td> </tr> <tr> <td colspan="2"><input type="submit" value="上传" /></td> </tr> </table> </form> </body> </html>
3. 创建Servlet
UploadServlet.java
package cn.itcast.fileupload; import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import org.apache.commons.fileupload.*; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; //上传文件的Servlet类 @WebServlet(name = "UploadServlet",urlPatterns = "/UploadServlet") //该注解用于标注文件上传的Servlet @MultipartConfig public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { try { //设置ContentType字段值 response.setContentType("text/html;charset=utf-8"); // 创建DiskFileItemFactory工厂对象 DiskFileItemFactory factory = new DiskFileItemFactory(); //设置文件缓存目录,如果该目录不存在则新创建一个 File f = new File("D:\\TempFolder"); if (!f.exists()) { f.mkdirs(); } // 设置文件的缓存路径 factory.setRepository(f); // 创建 ServletFileUpload对象 ServletFileUpload fileupload = new ServletFileUpload(factory); //设置字符编码 fileupload.setHeaderEncoding("utf-8"); // 解析 request,得到上传文件的FileItem对象 List<FileItem> fileitems = fileupload.parseRequest(request); //获取字符流 PrintWriter writer = response.getWriter(); // 遍历集合 for (FileItem fileitem : fileitems) { // 判断是否为普通字段 if (fileitem.isFormField()) { // 获得字段名和字段值 String name = fileitem.getFieldName(); if(name.equals("name")){ //如果文件不为空,将其保存在value中 if(!fileitem.getString().equals("")){ String value = fileitem.getString("utf-8"); writer.print("上传者:" + value + "<br />"); } } } else { // 获取上传的文件名 String filename = fileitem.getName(); //处理上传文件 if(filename != null && !filename.equals("")){ writer.print("上传的文件名称是:" + filename + "<br />"); // 截取出文件名 filename = filename.substring(filename.lastIndexOf("\\") + 1); // 文件名需要唯一 filename = UUID.randomUUID().toString() + "_" + filename; // 在服务器创建同名文件 String webPath = "/upload/"; //将服务器中文件夹路径与文件名组合成完整的服务器端路径 String filepath = getServletContext() .getRealPath(webPath + filename); // 创建文件 File file = new File(filepath); file.getParentFile().mkdirs(); file.createNewFile(); // 获得上传文件流 InputStream in = fileitem.getInputStream(); // 使用FileOutputStream打开服务器端的上传文件 FileOutputStream out = new FileOutputStream(file); // 流的拷贝 byte[] buffer = new byte[1024];//每次读取1个字节 int len; //开始读取上传文件的字节,并将其输出到服务端的上传文件输出流中 while ((len = in.read(buffer)) > 0) out.write(buffer, 0, len); // 关闭流 in.close(); out.close(); // 删除临时文件 fileitem.delete(); writer.print("上传文件成功!<br />"); } } } } catch (Exception e) { throw new RuntimeException(e); } } public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { doGet(request, response); } }
4. 启动项目,查看运行结果
在IDEA中启动Tomcat服务器,通过浏览器访问地址http://localhost:8080/chapter09/form.jsp,浏览器显示 的结果如图所示:
填写上传者信息"itcast",并选择需要上传的文件,如图所示:
单击"上传"按钮上传文件,文件成功上传后,浏览器的界面如图所示:
至此,将文件上传到服务器的功能已经实现。进入项目发布目录,可以看到刚才上传的文件,如图所示:
动手实践:实现文件下载
1. 创建下载页面
download.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>文件下载</title> </head> <body> <a href= "http://localhost:8080/chapter09/DownloadServlet?filename=1.png">文件下载</a> </body> </html>
2. 创建Servlet
DownloadServlet.java
package cn.itcast.fileupload; import java.io.*; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; @WebServlet(name = "DownloadServlet",urlPatterns = "/DownloadServlet") public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置ContentType字段值 response.setContentType("text/html;charset=utf-8"); //获取所要下载的文件名称 String filename = request.getParameter("filename"); //下载文件所在目录 String folder = "/download/"; // 通知浏览器以下载的方式打开 response.addHeader("Content-Type", "application/octet-stream"); response.addHeader("Content-Disposition", "attachment;filename="+filename); folder=folder+filename; // 通过文件流读取文件 InputStream in = getServletContext().getResourceAsStream(folder); // 获取response对象的输出流 OutputStream out = response.getOutputStream(); byte[] buffer = new byte[1024]; int len; //循环取出流中的数据 while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
3. 创建下载目录及文件
在chapter09项目的web目录下创建一个名称为download的文件夹,在该文件夹中放置一个名称为"1.png" 的图片文件。
4. 启动项目,查看结果
在IDEA中启动Tomcat服务器,通过浏览器访问地址http://localhost:8080/chapter09/download.jsp,浏览器 显示的界面如图所示:
在图中单击"文件下载"链接,浏览器显示的结果如图所示: