1、第 9 章 WEB09-Servlet 篇1.1案例一:使用 Servlet 完成一个用户登录的案例.1.1.1 需求:在网站的首页上,登录的链接,点击登录的链接,可以跳转到登录的页面.在登录的页面中输入用户名和密码点击登录的案例.完成登录的功能.1.1.2 分析:1.1.2.1 技术分析:【HTTP 的协议的概述】 协议:* 什么是协议: 规定双方需要遵守的规则. HTTP 协议:* 什么是 HTTP 协议 :用来规定浏览器与服务器之前需要遵守的规则. HTTP 协议的作用:规范浏览器和服务器之间的数据传递. HTTP 协议的特点:* 基于请求和响应的模型.* 必须先有请求后有响应.* 请求
2、和响应必须成对出现.* 默认的端口号是 80. HTTP 协议的版本 :* 1.0 :每次响应后即刻关闭了连接.* 1.1 :现在使用.不是每次响应后挂断,等待长时间以后没有请求会挂断.【HTTP 协议的演示】抓包分析:GET 方式:* 请求部分:GET /day09/demo1-http/demo2.html?name=aaa WOW64; Trident/7.0; rv:11.0) like GeckoAccept-Encoding: gzip, deflateHost: localhost:8080DNT: 1Connection: Keep-Alive抓包分析:POST 方式:POST
3、 /day09/demo1-http/demo2.html HTTP/1.1Accept: text/html, application/xhtml+xml, */*X-HttpWatch-RID: 59176-10031Referer: http:/localhost:8080/day09/demo1-http/demo1.htmlAccept-Language: zh-CNUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like GeckoContent-Type: application/x-ww
4、w-form-urlencodedAccept-Encoding: gzip, deflateHost: localhost:8080Content-Length: 15DNT: 1Connection: Keep-AliveCache-Control: no-cachename=bbb.* 配置 :test1com.itheima.a_servlet.ServletDemo1test1/ServletDemo1* 访问 :http:/localhost:8080/day09/ServletDemo1【使用 ServletRequest 接收参数】* String getParameter(S
5、tring name); -用于接收一个名称对应一个值的数据.* String getParameterValues(String name);-用于接收一个名称对应多个值的数据 .* Map getParameterMap(); -用于接收表单中的所有的数据,Map 的 key 是表单提交的参数名称,Map 的 value 是提交参数的值.* Enumeration getParameterNames() -用于获取表单中提交的所有的参数的名称.【Servlet 的访问流程】【Servlet 的实现的关系】Servlet :接口|GenericServlet :通用的 Servlet|Htt
6、pServlet :HttpServlet* 编写一个类继承 HttpServlet,重写 doGet 和 doPost 方法.* 配置1.1.3 代码实现1.1.3.1 步骤一:创建数据库和表:create database day09;use day09;create table user(id int primary key auto_increment,username varchar(20),password varchar(20),nickname varchar(20);insert into user values (null,aaa,111,小凤);insert into u
7、ser values (null,bbb,111,小童童);1.1.3.2 步骤二:创建包和类:1.1.3.3 步骤三:引入 jar 包* mysql 的数据库的驱动包* c3p0 连接池的 jar 包* dbutils 的包1.1.3.4 引入 login 的页面1.1.3.5 编写 ServletServiceDAO1.1.4 总结:1.1.4.1 Servlet 的生命周期:(*) 生命周期:就是一个对象从创建到销毁的过程. Servlet 生命周期:Servlet 从创建到销毁的过程.* 何时创建: 用户第一次访问 Servlet 创建 Servlet 的实例* 何时销毁: 当项目从服
8、务器中移除的时候,或者关闭服务器的时候. 用户第一次访问 Servlet 的时候,服务器会创建一个 Servlet 的实例,那么 Servlet 中 init 方法就会执行.任何一次请求服务器都会创建一个新的线程访问 Servlet 中的 service 的方法.在 service 方法内部根据请求的方式的不同调用 doXXX 的方法.(get 请求调用 doGet,post 请求调用 doPost).当 Servlet 中服务器中移除掉,或者关闭服务器,Servlet 的实例就会被销毁,那么 destroy 方法就会执行.1.1.4.2 Servlet 的相关的配置:【启动时创建 Servl
9、et】Servlet 默认是在第一次访问的时候创建的.现在让 Servlet 在服务器启动的时候创建好.进行对 Servlet的配置:在 web.xml 中在标签中配置:* 2 - 传入正整数,整数越小,被创建的优先级就越高.【url-pattern 的配置】url-pattern 配置方式共有三种:1.完全路径匹配 :以 / 开始 例如: /ServletDemo4 , /aaa/ServletDemo5 , /aaa/bbb/ServletDemo62.目录匹配 :以 / 开始 需要以 * 结束. 例如: /* ,/aaa/* ,/aaa/bbb/*3.扩展名匹配 :不能以 / 开始 以
10、* 开始的. 例如: *.do , *.action * 错误的写法 : /*.do有如下的配置:ServletDemo4com.itheima.a_servlet.ServletDemo4ServletDemo4/ServletDemo4ServletDemo5com.itheima.a_servlet.ServletDemo5ServletDemo5/*ServletDemo6com.itheima.a_servlet.ServletDemo6ServletDemo6*.do如果访问地址:http:/localhost:8080/day09/ServletDemo4 :第一个http:/l
11、ocalhost:8080/day09/aaa.do :第二个* 完全路径匹配 目录匹配 扩展名匹配1.1.4.3 开发中的路径的编写: 相对路径:都是需要找位置相对关系.不能以 / 开始的.* ./ 当前路径 /上一级目录* 使用相对路径访问:* http:/localhost:8080/day09/demo4-url/demo1.html* http:/localhost:8080/day09/ServletDemo6 绝对路径:不需要找位置相对关系. 以 / 开始的.* 绝对路径中分为客户端路径和服务器端路径:* 客户端路径一定要加工程名. /day09/ServletDemo6* 服务
12、器端路径不需要加工程名. /ServletDemo61.2案例二:登录成功以后 5 秒钟跳转到另一个页面.1.2.1 需求:在登录成功后,页面 5 秒钟跳转到其他的一个页面.1.2.2 分析:1.2.2.1 技术分析:【使用 Http 协议中的 Refresh 头信息】Refresh 之前已经介绍可以定时页面跳转.需要使用程序设置头信息才可以.【response 中设置响应头 】* addHeader(String name,String value); - 针对一个 key 对应多个 value 的响应头.* addDateHeader(String name,long date);* ad
13、dIntHeader(String name,int value);* setHeader(String name,String value); - 针对一个 key 对应一个 value 的响应头.* setDateHeader(String name,long date);* setIntHeader(String name,int value);例如: 头信息: xxx:aaa* addHeader(“xxx”,”bbb”); xxx:aaa,bbb* setHeader(“xxx”,”bbb”); xxx:bbb1.2.3 代码实现:在登录成功后的代码上,定时的跳转.public cl
14、ass UserRefreshServlet extends HttpServlet private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException try / 解决向页面输出中文的乱码问题!response.setContentType(“text/html;charset=UTF-8“);/ 1.接收表单提交的参数.String
15、username = request.getParameter(“username“);String password = request.getParameter(“password“);/ 2.封装到实体对象中.User user = new User();user.setUsername(username);user.setPassword(password);/ 3.调用业务层处理数据.UserService userService = new UserService();User existUser = userService.login(user);/ 4.根据处理结果显示信息(页
16、面跳转).if(existUser = null)/ 登录失败response.getWriter().println(“登录失败:用户名或密码错误!“);else/ 登录成功/ response.getWriter().println(“Login Success.“);response.getWriter().println(“登录成功!您好:“+existUser.getNickname()+“);response.getWriter().println(“页面将在 5 秒后跳转!“);response.setHeader(“Refresh“, “5;url=/day09/demo5-r
17、efresh/index.html“); catch (Exception e) e.printStackTrace();protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException doGet(request, response);1.2.4 总结:1.2.4.1 使用 JS 控制读秒的效果 .var time = 5;window.onload = function()setInterval(changeTime(),1
18、000);function changeTime()time-;document.getElementById(“s1“).innerHTML = time;1.3案例三:记录网站的登录成功的人数.1.3.1 需求:登录成功后,5 秒后跳转到某个页面,在页面中显示您是第 x 位登录成功的用户.1.3.2 分析:1.3.2.1 技术分析:【ServletContext 对象】* ServletContext 对象存取数据,存的数据都是有一定的作用的范围的.这种对象称为是域对象.* 用来存取数据:setAttribute(String name,Object object)* 用来向 Servle
19、tContext 中存入数据.* 用来从 ServletContext 中获取数据.getAttribute(String name)* 用来从 ServletContext 中移除数据.removeAttribute(String name)1.3.3 代码实现:/* 登录代码的 Servlet*/public class UserCountServlet extends HttpServlet private static final long serialVersionUID = 1L;Overridepublic void init() throws ServletException
20、/ 初始化一个变量 count 的值为 0.int count = 0;/ 将这个值存入到 ServletContext 中.this.getServletContext().setAttribute(“count“, count);protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException try response.setContentType(“text/html;charset=UTF-8“);/ 1.接收表单提交的参
21、数.String username = request.getParameter(“username“);String password = request.getParameter(“password“);/ 2.封装到实体对象中.User user = new User();user.setUsername(username);user.setPassword(password);/ 3.调用业务层处理数据.UserService userService = new UserService();User existUser = userService.login(user);/ 4.根据处
22、理结果显示信息(页面跳转).if(existUser = null)/ 登录失败response.getWriter().println(“登录失败:用户名或密码错误!“);else/ 登录成功/ 记录次数:int count = (int) this.getServletContext().getAttribute(“count“);count+;this.getServletContext().setAttribute(“count“, count);response.getWriter().println(“登录成功:您好:“+existUser.getNickname()+“);res
23、ponse.getWriter().println(“页面将在 5 秒后跳转!“);response.setHeader(“Refresh“, “5;url=/day09/CountServlet“); catch (Exception e) e.printStackTrace();protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException doGet(request, response);public class Cou
24、ntServlet extends HttpServlet private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException / 获得 Count 的值。response.setContentType(“text/html;charset=UTF-8“);int count = (int) this.getServletContext(
25、).getAttribute(“count“);response.getWriter().println(“您是第“+count+“位登录成功的用户!“);protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException doGet(request, response);1.3.4 总结:1.3.4.1 ServletConfig:了解.获得 Servlet 的配置信息.* String getServletName(); -获
26、得 Servlet 在 web.xml 中配置的 name 的值.* String getInitParameter(String name); -获得 Servlet 的初始化参数的.* Enumeration getInitParameterNames(); -获得所有 Servlet 的初始化参数的名称.1.3.4.2 ServletContext:重要ServletContext 的作用:* 1.用来获得全局初始化参数 .* 2.用来获得文件的 MIME 的类型 .* 3.作为域对象存取数据 .ServletContext 是一个域对象.* 作用范围:整个 web 工程.* 创建: 服务器启动的时候,tomcat 服务器为每个 web 项目创建一个单独 ServletContext 对象.* 销毁: 服务器关闭的时候,或者项目从服务器中移除的时候.* 4.用来读取 web 项目下的文件.