第三章补充案例 案例 3-1 HttpServlet 一 案例描述 1 考核知识点名称 :HttpServlet 编号 : 2 练习目标 掌握 HttpServlet 的 doget() 方法和 dopost() 方法 3 需求分析由于大多数 Web 应用都是通过 HTTP 协议和客户端进行交互, 因此, 在 Servlet 接口中, 提供了 一个抽象类 javax.servlet.http.httpservlet, 它是 GenericServlet 的子类, 专门用于创建应用于 HTTP 协 议的 Servlet 为了读者可以更好地了解 HttpServlet, 本案例将演示重写 HttpServlet 中的 doget() 方法 和 dopost() 方法打印出九九乘法表 4 设计思路 ( 实现原理 ) 查看 HttpServlet 源代码的 service () 方法, 在方法中可以看到 get 请求调用 doget() 方法,post 请求 调用 dopost() 方法, 那么就可以直接重写 doget () 和 dopost () 不需要重写 service () 方法了 1) 编写 ServletDemo1 类, 在 doget () 方法和 dopost() 方法中用双重 for 循环打印九九乘法表 2) 配置 web.xml 文件 3) 编写 get.html 页面, 设置表单提交方式为 get, 表单页面使用 input 标签配置一个按钮, 单击 按钮可以 get 方式访问 ServletDemo1 类 4) 编写 post.html 页面, 设置表单提交方式为 post, 表单页面使用 input 标签配置一个按钮, 单 击按钮可以 post 方式访问到 ServletDemo1 类 5) 通过浏览器分别访问 get.html 和 post.html 页面, 单击其页面上的按钮, 对 ServletDemo1 进 行访问 二 案例实现 编写 ServletDemo1, 其代码如下 : public class ServletDemo1 extends HttpServlet { protected void doget(httpservletrequest req, HttpServletResponse resp) resp.setcontenttype("text/html;charset=utf-8"); resp.getwriter().print("get 提交方式 <br/>"); for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { 1
resp.getwriter().print(j + "*" + i + "=" + j * i+" "); resp.getwriter().print("<br/>"); protected void dopost(httpservletrequest req, HttpServletResponse resp) resp.setcontenttype("text/html;charset=utf-8"); resp.getwriter().print("post 提交方式 <br/>"); for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { resp.getwriter().print(j + "*" + i + "=" + j * i+" "); resp.getwriter().print("<br/>"); 配置 web.xml 文件 : <servlet> <description></description> <display-name>servletdemo1</display-name> <servlet-name>servletdemo1</servlet-name> <servlet-class>cn.itcast.chapter03.servlet.servletdemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletdemo1</servlet-name> <url-pattern>/servletdemo1</url-pattern> </servlet-mapping> 编写 get.html 文件 : <form action="/chapter03/servletdemo1" method="get"> <input type="submit" value=" 提交 "> </form> 编写 post.html 文件 : <form action="/chapter03/servletdemo1" method="post"> 图所示 : <input type="submit" value=" 提交 "> </form> 启动 Tomcat 服务器, 在地址栏中输入 http://localhost:8080/chapter03/get.html, 浏览器显示的结果如下 2
单击提交按钮, 显示的结果如下图所示 : 在地址栏中输入 http://localhost:8080/chapter03/post.html, 浏览器显示的结果如下图所示 : 单击提交按钮, 显示的结果如下图所示 : 3
三 案例总结 1. 创建 HttpServlet 的步骤 1) 扩展 HttpServlet 抽象类 ; 2) 覆盖 HttpServlet 的部分方法, 例如, 覆盖 doget() 或 dopost() 方法 ; 3) 获取 HTTP 请求信息 通过 HttpServletRequest 对象来检索 HTML 表单所提交的数据或 URL 上的查询字符串 ; 4) 生成 HTTP 响应结果 通过 HttpServletResponse 对象生成响应结果, 它有一个 getwriter() 方法, 该方法返回一个 PrintWriter 对象 2. HttpServlet 主要有两大功能, 第一是根据用户请求方式的不同, 定义相应的 doxxx() 方法处理用户请求, 例如, 与 GET 请求方式对应的 doget() 方法, 与 POST 请求方式对应的 dopost() 方法 第二是通过 service() 方法将 HTTP 请求和响应分别转为 HttpServletRequest 和 HttpServletResponse 类型的对象 需要注意的是, 由于 HttpServlet 类在重写的 service() 方法中, 为每一种 HTTP 请求方式都定义了对应的 doxxx() 方法, 因此, 当定义的类继承 HttpServlet 后, 只需根据请求方式, 重写对应的 doxxx() 方法即可, 而不需要重写 service() 方法 案例 3-2 用 ServletConfig 对象读取配置文件 一 案例描述 1 考核知识点名称 :ServletConfig 接口 编号 : 2 练习目标 掌握 ServletConfig 对象的使用 3 需求分析在 Servlet 运行期间, 经常需要一些辅助信息, 这些信息可以在 web.xml 文件中使用一个或多 个 <init-param> 元素进行配置 当 Tomcat 初始化一个 Servlet 时, 会将该 Servlet 的配置信息封装到 一个 ServletConfig 对象中 为了让初学者熟悉 ServletConfig 对象, 本案例将使用 ServletConfig 对 象读取配置文件中的参数 4 设计思路 ( 实现原理 ) 1) 创建 ServletDemo2 类, 2) 在 ServletDemo2 中, 用 getinitparameternames() 方法获得所有参数 3) 在 web.xml 中配置初始化参数和类的映射 4) 通过浏览器访问 ServletDemo2, 展现控制台输出的读取 web.xml 中的初始化参数 二 案例实现 创建 ServletDemo2 类, 代码如下 : public class ServletDemo2 extends HttpServlet { private ServletConfig config; 4
@Override // config 实例由容器提供 public void init(servletconfig config) throws ServletException { this.config = config; public void doget(httpservletrequest request, HttpServletResponse response) test(response); // 获取所有的参数及参数值 private void test(httpservletresponse response) throws IOException { Enumeration e = config.getinitparameternames(); while (e.hasmoreelements()) { String paramname = (String) e.nextelement(); String paramvalue = config.getinitparameter(paramname); response.getwriter().write(paramname + ":" + paramvalue + "<br/>"); 在 web.xml 中配置 ServletDemo2 类及初始化数据 : <servlet> <servlet-name>servletdemo2</servlet-name> <servlet-class>cn.itcast.chapter03.servlet.servletdemo2</servlet-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>servletdemo2</servlet-name> <url-pattern>/servletdemo2</url-pattern> </servlet-mapping> 启动 Tomcat 服务器, 在浏览器的地址栏中输入 URL 地址 http://localhost:8080/chapter03/servletdemo2, 显示的结果如下图所示 : 5
三 案例总结 在本案例中, 要访问 ServletConfig 对象的参数, 首先要取得 ServletConfig 对象, 然后调用它的 getinitparameter(); 方法即可 在后面的学习中可以学到, 要访问 ServletConfig 对象,JSP 中直接使用 config 内置对象, 但因为 JSP 编译后的 servlet 一般不会被加到 web.xml 中的, 所以一般不会通过 JSP 来获取对本 JSP 编译后的 servlet 的配置参数 案例 3-3 ServletContext 接口实现数据共享 一 案例描述 1 考核知识点名称 :ServletContext 接口 编号 : 2 练习目标 掌握用 ServletContext 对象实现多个 Servlet 对象数据共享 3 需求分析由于一个 Web 应用中的所有 Servlet 共享同一个 ServletContext 对象, 因此 ServletContext 对象的 域属性可以被该 Web 应用中的所有 Servlet 访问 为了让初学者熟悉 ServletContext 对象, 本案例将演 示用 ServletContext 对象实现多个 Servlet 对象的数据共享 4 设计思路 ( 实现原理 ) 统计网站的访问次数 : 1) 创建两个 Servlet,ServletDemo3 用于存储,ServletDemo4 用于显示 2) 在类 ServletDemo3 中给次数 (count) 设置一个初始值 0 存入到 ServletContext 中 3) 每次访问 doget() 方法就会执行 count + 1, 并将 count 值存入到 ServletContext 中 4) 在类 ServletDemo4 中用 getattribute ("count") 方法获取到 count 值 二 案例实现 创建类 ServletDemo3, 代码如下 : public class ServletDemo3 extends HttpServlet { @Override public void init() throws ServletException { // 给次数设置一个初始值 0 int count = 0; // 将 0 存入到 ServletContext 中 getservletcontext().setattribute("count", count); public void doget(httpservletrequest request, HttpServletResponse response) // 将原来的次数取出来 6
int count = (Integer) getservletcontext().getattribute("count"); count += 1; // 存入到 SErvletContext 中 getservletcontext().setattribute("count", count); // 向页面输出欢迎光临! response.setcontenttype("text/html;charset=utf-8"); response.getwriter().println("<h1> 欢迎光临本网站! 这是您第 "+count+" 次访问 </h1>"); public void dopost(httpservletrequest request, HttpServletResponse response) doget(request, response); 创建类 ServletDemo4, 代码如下 : 显示的 Servlet 的代码 public class ServletDemo4 extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) // 取出 ServletContext 中存的次数 int count = (Integer) getservletcontext().getattribute("count"); // 显示到页面 response.setcontenttype("text/html;charset=utf-8"); response.getwriter().println("<h1> 网站被访问了 "+count+" 次!</h1>"); public void dopost(httpservletrequest request, HttpServletResponse response) doget(request, response); 修改 web.xml 中配置 : <servlet> <description></description> <display-name>servletdemo3</display-name> <servlet-name>servletdemo3</servlet-name> <servlet-class>cn.itcast.chapter03.servlet.servletdemo3</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletdemo3</servlet-name> <url-pattern>/servletdemo3</url-pattern> </servlet-mapping> <servlet> <description></description> <display-name>servletdemo4</display-name> 7
<servlet-name>servletdemo4</servlet-name> <servlet-class>cn.itcast.chapter03.servlet.servletdemo4</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletdemo4</servlet-name> <url-pattern>/servletdemo4</url-pattern> </servlet-mapping> 启动服务, 访问 http://localhost:8080/chapter03/servletdemo3 可看到浏览器显示如下图 : 刷新多次此页面后可看到浏览器显示如下图 : 访问 http://localhost:8080/chapter03/servletdemo4 可看到浏览器显示如下图 : 三 案例总结 1 本案例中, 先访问了 ServletDemo3, 显示 欢迎光临本网站! 这是您第 1 次访问 访问多次 ServletDemo3 后访问 ServletDemo4, 由于 ServletContext 对象实现多个 Servlet 对象数据共享, 所以虽然第一次访问 ServletDemo4, 却在浏览器中显示了 网站被访问了 9 次! 2 在 ServletContext 接口中定义了分别用于增加 删除 设置 ServletContext 属性的四个方法, 如下表所示 方法说明功能描述 8
Enumeration getattributenames() Object getattibute(string name) void removeattribute(string name) void setattribute(string name,object obj) 返回一个 Enumeration 对象, 该对象包含了所有存放在 ServletContext 中的所有属性名根据参数指定的属性名返回一个与之匹配的属性值根据参数指定的属性名, 从 ServletContext 中删除匹配的属性设置 ServletContext 的属性, 其中 name 是属性名,obj 是属性值 9