目录
四、回到IDEA之前打开的项目,修改和补充各个目录下对应的代码。
(1)src目录下MyServlet.java。(书P186)
(2)第一次修改,src目录下MyFilter.java。(书P186~P187)
(3)第二次修改,src目录下MyFilter.java。(书P187~P188)
(4)src目录下ForwardServlet.java。(书P188)
(5)web目录下first.jsp。(书P188~P189)
(6)第一次修改,src目录下ForwardFilter.java。(书P189)
(7)第二次修改,src目录下ForwardFilter.java。(书P189)
(9)src目录下MyFilter01.java。(书P190)
(10)src目录下MyFilter02.java。(书P190~P191)
(13)src目录下LoginServlet.java。(书P193~P194)
(14)src目录下LogoutServlet.java。(书P194)
(15)src目录下AutoLoginFilter.java。(书P194~P195)
(16)MyListener.java类已经写好。做测试的时候只需要启动tomcat即可。书P197~P198。
(22)src目录下UploadServlet.java已经写好。(书P205~P206)
(23)web目录下download.jsp。(书P207~P208)
(24)src目录下DownloadServlet.java已经写好。(书P208)
(1)访问浏览器地址:"http://localhost:8080/chapter09/MyServlet"
(2)修改后,再次访问浏览器地址:"http://localhost:8080/chapter09/MyServlet"
(4)访问浏览器地址:"http://localhost:8080/chapter09/ForwardServlet"
(5)修改后,再次访问浏览器地址:"http://localhost:8080/chapter09/ForwardServlet"
(6)访问浏览器地址:"http://localhost:8080/chapter09/MyServlet"
(7)访问浏览器地址:"http://localhost:8080/chapter09/login.jsp"
(8)登录表单输入用户名:“itcast”,密码:"123456"登录后。
(10)MyListener.java类已经写好。启动tomcat服务器。
(11)MyListener.java类已经写好。终止tomcat服务器。
(12)访问浏览器地址:"http://localhost:8080/chapter09/myjsp.jsp"。查看控制台窗口的输出。
(13)访问浏览器地址:"http://localhost:8080/chapter09/form.jsp"。
(15)访问浏览器地址:"http://localhost:8080/chapter09/download.jsp"
(使用IDEA旗舰版(2024)完成)
一、IDEA中打开实训所需项目(chapter09)。
(1)学习通下载部分源代码(需修改)
(第九章——>拿到项目"chapter09")
(2)在IDEA中打开该项目(选择chapter09目录)
(3)点击信任项目(chapter09),即可打开
(4)查看整体的项目(chapter09)结构
二、初步了解本章需要学习的东西。(会的可跳过)
(1)Servlet高级特性。
- Servlet规范有三个高级特性,分别是Filter(过滤器)、Listener(监听器)及文件的上传和下载。
- 其中Filter用于修改request、response对象。用于Listener监听context、session、request事件。
(1)Filter。
- Filter被称为过滤器,它位于客户端和处理程序之间。能够对请求和响应进行检查和修改。
- 通常将请求拦截后进行一些通用的操作。(如过滤敏感词汇、统一字符编码和实施安全控制等等)
- Filter在Web应用中的拦截过程。当客户端对服务器资源发送请求时,服务器会根据过滤规则进行检查。如果客户的请求满足过滤规则,则客户请求进行拦截,对请求头和请求数据进行检查或者修改,并依次通过Filter链,最后把过滤之后的请求交给处理程序。
(2)Filter的生命周期。
- Filter的生命周期可分为创建、执行、销毁3个阶段。
- Web服务器启动时会创建Filter实例对象,并调用init()方法。注意:在一次完整的请求中,Filter对象只会被创建一次,init()方法也只被执行一次。
- 当客户端请求目标资源时,服务器会筛选出符合映射条件的Filter,并按照类名的先后顺序依次执行doFilter()方法。
- 服务器关闭时,Web服务器调用destory()方法销毁Filter对象。
(3)Filter映射。
- Filter拦截的资源需要在Filter实现类中使用注解@WebFilter进行配置。这些配置信息就是Filter映射。
(I)使用通配符"*"拦截用户所有请求。
(II)拦截不同访问方式的请求。
- @WebFilter注解有一个特殊的属性:“dispatcherTypes”,它可以指定过滤器的转发模式。其中它有四个常用值。
- REQUEST。如果用户通过RequestDispatcher对象的include()方法或forward()方法访问目标资源,那么过滤器将不会被调用。
- INCLUDE。如果通过RequestDispatcher对象的include()方法访问目标资源,那么过滤器将被调用。
- FORWARD。如果通过RequestDispatcher对象的forward()方法访问目标资源,那么过滤器将被调用。
- ERROR。如果通过声明式异常处理机制调用目标资源,过滤器会被调用。反之。
(4)Filter链。
- 在一个Web应用程序中可以注册多个Filter。每一个Filter都可以对某一个URL的请求进行拦截。
- 当多个Filter对同一个URL的请求进行拦截,那么它们组成一个Filter链。
- Filter链使用FilterChain对象表示。也就是FilterChain对象提供一个doFilter()方法。该方法的作用就是让Filter链上的当前过滤器放行,使请求进入到下一个Filter。
(5)Filter对Cookie进行拦截并实现自动登录。
(6)Listener
- Web程序开发,经常需要对某些事件进行监听,以便及时做出处理。(监听鼠标单击事件、监听键盘按下事件等等)
- Servlet提供了监听器(Listener),专门用于监听Servlet事件。事件、事件源、事件监听器、事件处理器。
- 将监听器绑定到事件源,就是注册监听器。
- Listener的API。Listener有8个不同的监听器接口,分别监听不同的对象。
- 监听域对象的生命周期。
- web容器会为每次请求创建一个新的ServletRequest对象,但对于同一个浏览器在会话期间只会创建一个HttpSession对象。
(7)Servlet3.0新特性。
- 注解。(如WebServlet、WebFilter、WebListener等等)
- 异步处理支持。
(8)文件的上传和下载。
三、配置实训项目(chapter09)的所需环境。
四、回到IDEA之前打开的项目,修改和补充各个目录下对应的代码。
(1)src目录下MyServlet.java。(书P186)
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); } }
(2)第一次修改,src目录下MyFilter.java。(书P186~P187)
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.write("Hello MyFilter"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
(3)第二次修改,src目录下MyFilter.java。(书P187~P188)
(写完记得注释掉"拦截所有用户请求"这段代码,并且复原。因为会拦截项目chapter09的所有请求)
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.write("Hello MyFilter"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
(4)src目录下ForwardServlet.java。(书P188)
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); } }
(5)web目录下first.jsp。(书P188~P189)
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <html> <head></head> <body> first.jsp </body> </html>
(6)第一次修改,src目录下ForwardFilter.java。(书P189)
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.println("Hello FilterTest"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
(7)第二次修改,src目录下ForwardFilter.java。(书P189)
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.println("Hello FilterTest"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
(8)在开始下方代码的测试之前,需要完成下方操作!
(注释MyFilter.java里面的拦截器代码)(否则无法得出想要的结果!)
(9)src目录下MyFilter01.java。(书P190)
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() { // 过滤器对象在销毁时自动调用,释放资源 } }
(10)src目录下MyFilter02.java。(书P190~P191)
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() { // 过滤器对象在销毁时自动调用,释放资源 } }
(11)web目录下login.jsp。(书P192)
<%@ 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"/></td> </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>
(12)web目录下index.jsp。(书P193)
<%@ 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>
(13)src目录下LoginServlet.java。(书P193~P194)
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); } }
(14)src目录下LogoutServlet.java。(书P194)
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.setPath("request.getContextPath()"); 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); } }
(15)src目录下AutoLoginFilter.java。(书P194~P195)
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() { } }
(16)MyListener.java类已经写好。做测试的时候只需要启动tomcat即可。书P197~P198。
(17)web目录下的myjsp.jsp。(书P198)
<%@ 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>
(18)web目录下的web.xml文件已经写好。
(19)所需jar包项目已导入。(书P204)
(20)去库、模块配置jar包。(这个也许都已经自动配好)
(21)web目录下form.jsp。(书P204)
<%@ 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>
(22)src目录下UploadServlet.java已经写好。(书P205~P206)
注意修改文件上传的缓存路径。因为作者本人没有F盘。
(23)web目录下download.jsp。(书P207~P208)
<%@ 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>
(24)src目录下DownloadServlet.java已经写好。(书P208)
五、实训要求,所需的各个截图。
(请勿直接复制拿去提交!)
(1)访问浏览器地址:"http://localhost:8080/chapter09/MyServlet"
(2)修改后,再次访问浏览器地址:"http://localhost:8080/chapter09/MyServlet"
(3)使用通配符"*"拦截所有请求。
(4)访问浏览器地址:"http://localhost:8080/chapter09/ForwardServlet"
(5)修改后,再次访问浏览器地址:"http://localhost:8080/chapter09/ForwardServlet"
(6)访问浏览器地址:"http://localhost:8080/chapter09/MyServlet"
(前提已经注释掉MyFilter.java代码中的关于拦截器的代码)
(7)访问浏览器地址:"http://localhost:8080/chapter09/login.jsp"
(8)登录表单输入用户名:“itcast”,密码:"123456"登录后。
(9)登录成功后进入界面,点击“注销”。
(10)MyListener.java类已经写好。启动tomcat服务器。
(11)MyListener.java类已经写好。终止tomcat服务器。
(12)访问浏览器地址:"http://localhost:8080/chapter09/myjsp.jsp"。查看控制台窗口的输出。
(13)访问浏览器地址:"http://localhost:8080/chapter09/form.jsp"。
(14)选择文件上传,并点击上传。
(15)访问浏览器地址:"http://localhost:8080/chapter09/download.jsp"
(16)单击下载,浏览器显示结果。