1 / 70

第十一章 Servlet 程序设计

第十一章 Servlet 程序设计. 郑莉. 目录. 11.1 Java 网络程序设计的基本概念 11.2 Servlet 基础 11.3 Servlet 的生命周期 11.4 与客户端交互 11.5 客户端跟踪 11.6 协作与通讯 11.7 程序举例 11.8 本章小结. 网络将世界联系在一起,使世界变得更加丰富多彩。同时网络互连是一个内容丰富而复杂的主题,所以这方面的程序设计涉及面很广且不易掌握

Download Presentation

第十一章 Servlet 程序设计

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第十一章 Servlet程序设计 郑莉

  2. 目录 11.1 Java网络程序设计的基本概念 11.2 Servlet基础 11.3 Servlet的生命周期 11.4 与客户端交互 11.5 客户端跟踪 11.6 协作与通讯 11.7 程序举例 11.8 本章小结

  3. 网络将世界联系在一起,使世界变得更加丰富多彩。同时网络互连是一个内容丰富而复杂的主题,所以这方面的程序设计涉及面很广且不易掌握网络将世界联系在一起,使世界变得更加丰富多彩。同时网络互连是一个内容丰富而复杂的主题,所以这方面的程序设计涉及面很广且不易掌握 与其他语言相比,Java语言在网络应用程序方面具有一定的优势。Java提供了很多内置的网络功能,使得基于Internet和Web的应用开发变得更加容易 11.1 Java网络程序设计的基本概念

  4. 11.1.5 Servlet Servlet 是用java技术来实现CGI(Common Gateway Interface, 通用网关接口)功能的编程 介于浏览器(或其他HTTP客户端)与服务器之间,起到桥梁的作用。具体作用为: 读取客户端发送的数据 获取客户请求(request)中所包含的信息 产生响应结果,并将结果包含到一个文件中,比如HTML文件中 设置HTTP响应参数,比如告诉浏览器,文件类型为HTML 将文件返回给客户端 11.1 Java网络程序设计的基本概念

  5. Servlet具有很多优点 高效率 通过Servlet,Java虚拟机用轻量级的Java线程处理每个请求。同时有N个请求的情况下,CGI程序需要被调入到服务器内存N次;对于Servlet将开启N个线程,但仅仅调入一个Servlet实例到内存中 应用方便 Servlet在解析和译码HTML数据,读取设置HTML标题,操作Cookie等很多方面,应用更加方便。继承自java的特点,其可靠性与复用性好 功能强大 Servlet可以直接与Web服务程序对话;多个Servlet可以共享数据;Servlet与数据库的连接也比较简单等 11.1 Java网络程序设计的基本概念 11.1.5 Servlet(续)——优点

  6. 便携性好 Servlet用Java语言编写,遵循标准的API。因此Servlet编写的程序可以无任何修改的在Apache,Microsoft Internet Information Server(IIS),IBM WebSphere,或者StarNine WebStar 上运行。同样具有一次编译,到处运行移植性好的特点 安全 基于Java语言的安全特性,Servlet的安全性也比较可靠 成本低 有很多免费或相对比较便宜的Web服务器,适合做个人的或者小容量的网站。而且很多商业级的Web服务器相对也比较便宜。而且使一个服务器支持Servlet所需的额外花费也很少 11.1 Java网络程序设计的基本概念 11.1.5 Servlet(续)——优点

  7. 11.2 Servlet基础 本节内容包括 Servlet容器、web服务器、应用服务器 Web应用程序 Servlet API Servlet的基本结构 Servlet编译和安装

  8. Servlet容器 也称为Servlet引擎 是一个编译好的可执行程序,它是web服务器与servlet间的媒介 负责将请求翻译成Servlet能够理解的形式传递给servlet,同时传给servlet一个对象使之可以送回响应 负责管理servlet的生命周期 11.2 Servlet基础 11.2.1 Servlet容器、Web服务器和应用服务器

  9. web服务器 能够处理Http请求的服务器 可以提供静态页面、图像等 有的web服务器也支持动态页面的生成,支持JSP、Servlet等,具有JVM 应用服务器 可以处理基于多种协议的请求,当然也包括Http协议 可以支持servlets和JSP,以及所有其他J2EE服务,包括JNDI、EJBs、JMS等 11.2 Servlet基础 11.2.1 Servlet容器、Web服务器和应用服务器

  10. servlet容器可以与web服务器协作提供对servlet的支持servlet容器可以与web服务器协作提供对servlet的支持 一些servlet容器(如Apache Tomcat)自己也可以作为独立的web服务器运行 随着servlet和JSP的流行,一些主要的Web服务器和应用程序服务器都直接或者通过插件支持servlet和JSP。如: Sun ONE Application Server Lotus Domino Go WebServer BEA weblogic Tengah Server WebSphere应用服务器 Jigsaw NetForge AcmeServer Mot Bays Jetty 11.2 Servlet基础 11.2.1 Servlet容器、Web服务器和应用服务器

  11. 11.2.2 Web应用程序 Web应用程序 组成部分包括servlet、JSP及其支持文件 这些组成部分需要进行部署 通常部署在Tomcat的webapps子目录中。一般其目录结构包括根目录(context root)和几个子目录,也可以把子目录捆绑到一个类型为war的存档文件中 11.2 Servlet基础

  12. 11.2.3 Servlet API Servlet API 开发servlet和JSP程序,需要参考Servlet API文档 包含javax.servlet和javax.servlet.http两个包中 所有servlet须实现javax.servlet.Servlet接口,通常继承如下两个类中的一个 GenericServlet HttpServlet 11.2 Servlet基础 Servlet Generic servlet Http servlet My servlet

  13. Servlet接口 所有servlets 必须实现这一接口 Servlet接口的所有方法都是被自动调用的 HttpServlet类 覆盖了javax.servlet.Servlet接口的service方法 service方法由servlet容器调用,对客户端的请求作出响应。它会根据请求类型的不同自动调用doGet或doPost等方法 能够处理两个最普通的 HTTP 请求类型 doGet方法 响应 get 请求 doPost 方法响应 post 请求 11.2.3 Servlet API(续) 11.2 Servlet基础

  14. 11.2.3 Servlet API(续) HttpServletRequest接口 由Web服务器创建该接口的一个对象,并将其传递给servlet的 service 方法 该类对象含有来自于客户端的请求 HttpServletResponse接口 由Web服务器创建该接口的一个对象,并将其传送给servlet的 service 方法 通过该类对象服务器端可以对客户端发出响应信息 11.2 Servlet基础

  15. 11.2.4 Servlet的基本结构 Servlet的基本结构 一般扩展自HttpServlet 复写doGet或者doPost方法 doGet或doPost都接收两个类型的参数:HttpServletRequest和HttpServletResponse 通过HttpServletRequest,可以得到所有的输入数据,比如表单数据、HTTP请求报头等客户信息 通过HttpServletResponse可以指定输出信息 由于doGet和doPost方法可能生成异常,必须在方法名称后声明抛出异常或者用try-catch语句处理异常 11.2 Servlet基础

  16. GET请求是WEB浏览器请求的常见类型,用来请求Web页面。 本例中通过doGet方法处理GET请求。在doGet方法中通过HttpServletResponse对象得到PrintWriter,然后将一个文档发给客户。最终在客户端生成一个网页 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet { public void doGet( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res. getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE>My First Servlet </TITLE></HEAD>"); out.println("<BODY>"); out.println("<B> First Servlet </B>"); out.println("</BODY></HTML>"); } } 11.2.4 Servlet的基本结构(续)——例11-2 11.2 Servlet基础

  17. 11.2.5 Servlet编译和安装 编译——在设置好path和classpath的前提下,servlet的编译和普通的java程序完全相同 可以通过javac.exe编译,比如可以在Dos环境下输入: javac MyServlet.java 也可以通过集成开发环境(IDE)编译 复制——编译成功之后,将生成的类文件复制到相应的目录下即可。在Tomcat服务器上,此目录可能是 install_dir\webapps\ROOT\WEB-INF\classes\ 运行——启动Tomcat服务器,在地址栏输入 http://localhost:8080/servlet/MyServlet 11.2 Servlet基础

  18. 11.3 Servlet的生命周期 首先服务器仅创建servlet的一个实例 创建servlet实例时,它的init方法都会被调用 针对每个客户端的每个请求,都会创建一个线程 该线程调用servlet实例的service方法 Service方法根据收到HTTP请求得类型,调用doGet,doPost或者其他方法 多个并发请求,一般会导致多个线程同时调用service方法,通过单线程模式(SingleThreadModel)也可以规定任何时间仅允许一个线程运行 最后,卸载servlet 服务器调用servlet的destroy方法

  19. 11.3 Servlet的生命周期(续)——Servlet生命周期示意图

  20. 11.3.1 初始化 servlet的初始化 服务器启动,servlet被用户首次调用,服务器构造servlet实例之后,即立刻调用init(ServletConfig)方法,执行servlet实例的初始化工作 ServeletConfig对象包含servlet初始化所需的很多参数,比如计数器、默认值等 init方法都会在servlet处理客户请求(request)之前被调用 一旦init方法被调用,只有服务器通过destroy方法销毁servlet之后,init方法才能再次被调用 11.3 Servlet的生命周期

  21. 11.3.1 初始化(续) init方法的定义 public void init(ServletConfig config) throws ServletException { super.init(config); String greeting = getInitParameter("greeting"); // Initialization code… } 11.3 Servlet的生命周期

  22. 11.3.2 销毁 servlet的销毁 服务器卸载servlet实例之前,需要先调用servlet的destroy方法 释放servlet所获得的资源 使servlet有机会关闭数据库连接、停止后台运行的线程、将cookie列表和点击数写入到磁盘 执行其他清理活动 11.3 Servlet的生命周期

  23. 11.4 与客户端交互 HTTP servlet与客户端的交互 通过service方法处理客户端的请求 service方法根据请求(request)类型的不同,调用不同的方法 对于GET请求,调用doGet( )方法进行处理 对于POST请求,调用doPost( )方法进行处理

  24. 11.4.1 提取Servlet信息 注册的servlet都有相关的很多初始化参数 这些初始化参数写在web.xml中,具体语法格式请参阅Tomcat文档 getInitParameter()方法 可以得到servlet初始化的一些参数 返回一个指定参数的值(String类型) 如果指定参数不存在,则返回null getInitParameterNames()方法 可以得到初始化参数名称 返回String类型的Enumeration类型数据 如果不存在初始化参数,则返回一个null的Enumeration 11.4 与客户端交互

  25. 通过servlet初始化参数建立一个数据库连接的程序段如下通过servlet初始化参数建立一个数据库连接的程序段如下 java.sql.Connection con = null; public void init(ServletConfig config) throws ServletException { super.init(config); String host = getInitParameter("host"); int port = Integer.parseInt(getInitParameter("port")); String db = getInitParameter("db"); String user = getInitParameter("user"); String password = getInitParameter("password"); String proxy = getInitParameter("proxy"); con = establishConnection(host, port, db, user, password, proxy); } 11.4 与客户端交互 11.4.1 提取Servlet信息(续)——通过初始化建立数据库连接

  26. 输出全部初始化参数名称 import java.io.*; import java.util.*; import javax.servlet.*; public class PrintInitParaNames extends GenericServlet { public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); out.println("Init Parameters As Following:"); Enumeration enum = getInitParameterNames(); while (enum.hasMoreElements()) { String name = (String) enum.nextElement(); out.println(name ": " + getInitParameter(name)); } } } 11.4 与客户端交互 11.4.1 提取Servlet信息(续)——PrintInitParaNames.java

  27. 11.4.2 提取服务器信息 servlet可以得到很多服务器相关的信息,同时可以将这些信息发送到客户端 getServerName()返回服务器名称 getServerPort()返回服务器监听端口 getServerInfo()输出服务器程序和版本,之间用“/”分开 getAttribute()返回服务程序的属性 得到路径相关的信息 public String HttpServletRequest.getPathInfo() public String HttpServletRequest.getPathTranslated() 11.4 与客户端交互

  28. 提取服务器信息举例 import java.io.*; import java.util.*; import javax.servlet.*; public class ServerSnoop extends GenericServlet { public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); out.println("req.getServerName() output: " + req.getServerName()); out.println("req.getServerPort() output: " + req.getServerPort()); out.println("getServletContext().getServerInfo() output: " + getServletContext().getServerInfo() ); out.println("getServletContext().getAttribute(\"attribute\") output: " + getServletContext().getAttribute("attribute") ); } } 11.4 与客户端交互 11.4.2 提取服务器信息(续)——例11-3

  29. 11.4.3 提取客户端信息 服务器可以从request得到很多客户端的信息 getRemoteAddr():得到IP地址 getRemoteHost():得到客户端机器的名称 利用InetAddress.getByName()方法可以将IP地址或客户端机器名称转换成一个java.net.InetAddress类型的对象 InetAddress remoteInetAddress = InetAddress.getByName(req.getRemoteAddr()); 通过获取客户端的地址,并判断是否隶属某个范围,可以限制某个地区的用户访问你的网站 11.4 与客户端交互

  30. 11.4.3 提取客户端信息(续) 服务器可以得到客户想做的事情 客户请求表现为表单数据,由“名/值”对组成。当提交某一个网页的时候常常在浏览器地址栏中看到类似格式的数据格式 name/value,每对之间用&隔开,表达式为 param1=value1&param2=value2&param3=value3… request.getParameter:得到表单参数的值 request.getParameterValues:得到多次出现的参数值 reques.getParameterNames:得到当前请求中所有参数的完整列表,调用形式如下 public String ServletRequest.getParameter(String name) public String[] ServletRequest.getParameterValues(String name) 11.4 与客户端交互

  31. 书本查询的一个HTML网页 !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE> A Sample Form for Query a Book </TITLE> </HEAD> <BODY BGCOLOR="#FDF5E6"> <FORM METHOD=GET ACTION="/Chapter11/QueryServlet"> Book to look up: <INPUT TYPE="TEXT" NAME="Book" VALUE="Java Servlet Programming"> <!-- The default book to be looked up is: 《Java Servlet Programming》. --> <INPUT TYPE=SUBMIT> </FORM> </BODY> </HTML> 11.4 与客户端交互 11.4.3 提取客户端信息(续)——Query.html

  32. 获取客户端信息的servlet import java.io.*; import java.net.*; import javax.servlet.*; import javax.servlet.http.*; public class QueryServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html;charset=UTF-8"); String queryBookValue=req.getParameter("Book"); PrintWriter out = res.getWriter(); out.println("The book you wanted is:"+queryBookValue); out.close(); } } 11.4 与客户端交互 11.4.3 提取客户端信息(续)——QueryServlet.java

  33. 11.4 与客户端交互 11.4.3 提取客户端信息(续)——Query.html与QueryServlet运行结果

  34. 11.4.4 发送HTML信息 Web服务器响应(response)的构成 状态行 由http版本(HTTP/1.1),一个状态代码(200)和一段对应状态代码的简短消息(OK)组成 一些响应报头、 Content-Type: text/html 指定后面文档MIME类型,后面的其他报头可选。常用MIME类型有: text/html : HTML文档 text/plain: 纯文本 text/xml: XML image/jpeg:JEPG图像 application/msword: Microsoft Word文档 application/pdf:crobat文件 application/zip:Zip档案 一个空行和响应的文档 11.4 与客户端交互

  35. HTTP/1.1 200 OK //状态行 Content-Type: text/html //报头 Header2: … … HeaderN: … //空行 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> //文档 <HTML> <HEAD> head code </HEAD> <BODY> … </BODY></HTML> 11.4.4 发送HTML信息(续) 11.4 与客户端交互

  36. 向客户端输出一个简单网页,显示“Hello World!” import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void doGet( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE>Hello World</TITLE></HEAD>"); out.println("<BODY>"); out.println("<BIG>Hello World!</BIG>"); out.println("</BODY></HTML>"); } } 11.4 与客户端交互 11.4.4 发送HTML信息(续)——例11-4

  37. 程序说明 HelloWorld继承了HttpServlet,然后重写doGet方法 在doGet方法中,首先将HTTP Content-Type响应报头设置为text/html,即指定响应的类型为HTML文档;然后通过getWriter()得到PrintWriter类型的一个对象out,按照HTML格式输出一个简单网页 运行结果 11.4 与客户端交互客户端跟踪 11.4.4 发送HTML信息(续)——例11-4运行结果

  38. 11.5 客户端跟踪 客户端跟踪 HTTP是无状态协议,服务器不能自动维护客户连接的上下文信息 许多情况下,Web服务器必须要能够跟踪用户的状态 比如购物网站和电子邮件网站,当用户登录以后,其身份和一系列的操作状态都需要被跟踪并保持 servlet API提供了两种可以跟踪客户端状态的方法 Cookie Session

  39. 11.5.1 使用Cookie Cookie 是Web服务器保存在用户硬盘上的一段文本,Web服务器将它发送到浏览器 之后,当再次访问同一网络时,浏览器将它原封不动的返回 其中的信息片断以‘名/值’对(name-value pairs)的形式储存 使用这种方法,网站可以维护客户的连接。这种用途可以体现在如下几点 在电子商务中标识用户,实现短期跟踪用户 记录用户名和用户密码,允许用户下次自动登陆 定制站点,记录用户的偏好 定向广告,记录用户感兴趣的主题,并显示与之相关的广告 11.5 客户端跟踪

  40. 调用Cookie的构造方法可创建一个cookie 构造方法接受两个字符串参数 cookie名称 cookie的值 例如创建一个名为CookieName,值为John的cookie,可以使用下面的语句 Cookie login = new Cookie(“CookieName”, ”John”); 11.5 客户端跟踪 11.5.1 使用Cookie(续)——创建Cookie对象

  41. 创建了一个名为login的cookie之后,可通过很多现有的方法设置cookie的值和属性创建了一个名为login的cookie之后,可通过很多现有的方法设置cookie的值和属性 可通过如下语句设置cookie的注释: login.setComent(“You can get UserName form this cookie”); 创建cookie并将它发送到浏览器后,默认情况下,它是会话级的cookie,仅仅存储在浏览器内存中,用户退出浏览器后,cookie将被删除;如果希望将cookie存储在磁盘上,则需要设定MaxAge,给出一个以秒为单位的生命周期,如下可以将生命设置为一天 login.setMaxAge(60*60*24) // one day setPath(),setValue(),setVersion(),setDomain(),setSecure()等,相关的具体用法请查看servlet API 11.5 客户端跟踪 11.5.1 使用Cookie(续)——设置Cookie属性

  42. 刚创建的cookie存在于服务器内存中。必须将它发送到客户端,cookie才能真正的发挥作用。发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个HTTP响应报头。发送的语句如下刚创建的cookie存在于服务器内存中。必须将它发送到客户端,cookie才能真正的发挥作用。发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个HTTP响应报头。发送的语句如下 public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Cookie login = new Cookie(“UserName”, ”John”); login.setComent(“You can get UserName form this cookie”); res.addCookie(login); //... } 11.5 客户端跟踪 11.5.1 使用Cookie(续)——发送Cookie到客户端

  43. 从客户端读取你感兴趣的cookie,需要两个步骤 首先调用request.getCookies得到一个Cookie对象的数组 然后调用每个cookie的getName方法,从数组中寻找所需的cookie String nameString = “UserName” Cookie[] cookies = request.getCookies(); for ( int i=0; i<cookies.length; i++) { Cookie cookie = cookies[i]; if (nameString.equals( cookie.getName()) ) { // do something … // cookies.setMaxAge(0); } } 找到感兴趣的cookie之后,便可以操作此cookie, 如通过getValue方法得到相关cookie的值,设置MaxAge等 11.5 客户端跟踪 11.5.1 使用Cookie(续)——从客户端读取Cookie

  44. 11.5.2 使用Session Session 一段时间内,单个客户与web服务器的一连串的交互过程 在一个Session中客户可能会多次请求访问同一个网页,也有可能请求访问各种不同的服务器资源,其间用户的状态需要跟踪并保持 存在于服务器端,不在网络上传送 它的好处是可以用来记录客户端私有的信息,并且在时间范围内不会消失 11.5 客户端跟踪

  45. 11.5.2 使用Session(续) Session的使用可以分为三个步骤 获得一个session 存储数据到session或从session读取数据 销毁session 11.5 客户端跟踪

  46. 通过调用httpServletRequest的getSession方法可以得到一个session通过调用httpServletRequest的getSession方法可以得到一个session HttpSession session = request.getSession(); 为了保持正确的会话,必须在发送任何文档到客户程序之前获得一个session public class SessionServlet extends HttpServlet { public void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get the user's session HttpSession session = request.getSession(true); //... out = response.getWriter(); // ... } } 11.5 客户端跟踪 11.5.2 使用Session(续)——获得一个Session

  47. Session ID Servlet容器为HttpSession分配的一个唯一标识符 作为Cookie保存在客户的浏览器中 session cookie 每次客户发出HTTP请求时,Servlet容器可以从HttpRequest对象中读取Session ID,然后根据Session ID在服务器端找到相应的HttpSession对象,从而获取客户的状态信息,这样的cookie叫做session cookie 存储于浏览器内存中的,并不写到硬盘上的 针对某一次会话而言,会话结束也就随着消失了 11.5 客户端跟踪 11.5.2 使用Session(续)——存储或读取数据

  48. URL 重写 浏览器不支持 Cookie,或者将浏览器设置为不接受 Cookie的情况,可通过 URL 重写来实现会话管理 向 URL 连接添加参数,并把 session ID 作为值包含在连接中。为 servlet 响应部分的每个连接添加 session ID ,可以使用一对方法 response.encodeURL() :使 URL 包含session ID response.encodeRedirectURL():使用重定向 11.5 客户端跟踪 11.5.2 使用Session(续)——存储或读取数据

  49. 从Session中读取数据 session.getAttribute(“name”) 查找以前存储的值 如果不存在则返回null 在调用此方法返回的对象前,一定要检查它是否为null 向session中设置相关信息 setAttribute 替换掉此前设定的任何值 removeAttribute 移除而不是替换某个值 11.5 客户端跟踪 11.5.2 使用Session(续)——存储或读取数据

  50. public class SessionServlet extends HttpServlet { public void doGet (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { // Get the user's session HttpSession session = request.getSession(true); SomeClass scl = (SomeClass)session.getAttribute( "name1“ ); // If the user has no SomeClass object, create a new one if (scl == null) { scl = new SomeClass(); session.putAttribute( "name1", scl ); } //... } } 11.5 客户端跟踪 11.5.2 使用Session(续)——SessionServlet.java

More Related