《《Servlet程序设计》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《Servlet程序设计》PPT课件.ppt(92页珍藏版)》请在金锄头文库上搜索。
1、第十一章第十一章 Servlet程序设计程序设计郑莉郑莉JAVA语言程序设计1目录目录l11.1 Java网络程序设计的基本概念网络程序设计的基本概念l11.2 Servlet基础基础l11.3 Servlet的生命周期的生命周期l11.4 与客户端交互与客户端交互l11.5 客户端跟踪客户端跟踪l11.6 协作与通讯协作与通讯l11.7 程序举例程序举例l11.8 本章小结本章小结211.1 Java网络程序设计的基本概念网络程序设计的基本概念l网络将世界联系在一起,使世界变得更加网络将世界联系在一起,使世界变得更加丰富多彩。同时网络互连是一个内容丰富丰富多彩。同时网络互连是一个内容丰富而复
2、杂的主题,所以这方面的程序设计涉而复杂的主题,所以这方面的程序设计涉及面很广且不易掌握及面很广且不易掌握l与其他语言相比,与其他语言相比,Java语言在网络应用程语言在网络应用程序方面具有一定的优势。序方面具有一定的优势。Java提供了很多提供了很多内置的网络功能,使得基于内置的网络功能,使得基于Internet和和Web的应用开发变得更加容易的应用开发变得更加容易311.1.1 协议协议l所有使用或实现某种所有使用或实现某种Internet服务的程序都必须遵从一个或服务的程序都必须遵从一个或多个网络协议,这种协议很多,而多个网络协议,这种协议很多,而IP、TCP、UDP是最为根是最为根本的三
3、种协议,是所有其它协议的基础本的三种协议,是所有其它协议的基础IP(Internet Protocol,Internet协议)l是最底层的协议l定义了数据按照数据报(Datagram,一种自带寻址信息的、独立地从数据源走到终点的数据包)传输的格式和规则TCP(Transport Control Protocol,传输控制协议)l建立在IP之上,定义了网络上程序到程序的数据传输格式和规则,提供了IP数据包的传输确认、丢失数据包的重新请求、将收到的数据包按照它们的发送次序重新装配的机制l是面向连接的协议,在开始数据传输之前,必须先建立明确的连接UDP(User Datagram Protocol,
4、用户数据报协议)l与TCP相似,比TCP具有更好的传输效率。l不可靠的,不保证数据的传输,也不提供重新排列次序或重新请求功能,是一种无连接协议Java网络程序设计的基本概念4lHTTP协议(协议( HyperText Transfer Protocol)是Internet众多协议中的一种,表示超文本传输协议,它构成了WWW的基础具有简单快速、灵活、无状态、无连接等特点基于请求(Request)/响应(Response)模式。其工作过程如下l首先客户端与服务器建立连接l然后客户端发送一个请求给服务器l服务器接到请求后,给予相应的响应信息;最后关闭连接,完成一次操作11.1.1 协议协议(续续)
5、HTTP协议协议Java网络程序设计的基本概念5l客户端发送给服务器的请求客户端发送给服务器的请求有很多类型,被称为方法,其中最常用的是GET、POSTGET方法l用来从服务器读取信息,比如从服务器读取文件、表格、数据库查询结果等POST方法l用来向服务器传送信息,比如把信用卡号、表格、存储于数据库的数据等传送到服务器HEAD方法l用来读取服务器响应头(Response Head);得到诸如文件大小,文件最后修改时间,服务器类型等信息PUT方法l将文件直接传到服务器DELETE方法l将文件直接从服务器删除TRACE方法l用来协助程序调试OPTIONS方法l用来查询服务器所支持的方法11.1.1
6、 协议协议(续续) HTTP协议中客户端发送给服务器的请求协议中客户端发送给服务器的请求Java网络程序设计的基本概念611.1.2 关于关于URIlURI(Uniform Resource Identifier,统一资源标统一资源标志符)志符) HTTP协议用URI标识定位网络上的数据如果知道了公布在网络上的某个HTML文件的URI,不管文件位于什么地方,都可以通过HTTP访问该文档通常所说的URL是URI的一种Java网络程序设计的基本概念7lURL类类Java语言提供了URL类让我们能在源代码层使用URL有六个构造函数,其中最简单的是URL(String url)。每个URL对象都封装了
7、资源的标识符和协议处理程序,可以调用URL的方法来提取URL的组件把URL对象作为AppletContext接口的showDocument方法的参数,就可以使执行applet的浏览器显示URL所指定的资源11.1.2 关于关于URI(续续) URL类类Java网络程序设计的基本概念8lapplet浏览指定URL举例: ShowDocument.javaimport .*;import java.util.*;import java.awt.*;import java.awt.event.*;import java.applet.AppletContext;import javax.swing.
8、*;import javax.swing.event.*;public class ShowDocument extends JApplet public void init() JButton goButton = new JButton(Link to ); Container myContainer = getContentPane(); myContainer.add( new JLabel(Link to SOHU),BorderLayout.NORTH); myContainer.add(goButton,BorderLayout.SOUTH); goButton.addActio
9、nListener(new ButtonListener(); 11.1.2 关于关于URI(续续) 例例11_1Java网络程序设计的基本概念9 class ButtonListener implements ActionListener public void actionPerformed(ActionEvent e) try URL newDocument = new URL(http:/); AppletContext browser = getAppletContext(); browser.showDocument(newDocument); catch(Exception UR
10、LException) 11.1.2 关于关于URI(续续) 例例11_1Java网络程序设计的基本概念1011.1.3 基于套接字的有连接通信基于套接字的有连接通信l基于套接字基于套接字(socket)的有连接通信的有连接通信使用TCP协议一个socket必须在发送数据之前与目的地的socket取得连接一旦连接建立了,sockets就可以使用一个流接口完成打开-读-写-关闭,所有的发送的信息都会在另一端以同样的顺序被接收面向连接的操作比无连接的操作效率低,但是数据的安全性高Java网络程序设计的基本概念11l用用Java建立简单的服务器程序需要五个步骤建立简单的服务器程序需要五个步骤Step
11、1:创建ServerSocket对象ServerSocket myServer = new ServerSocket (int port, int backlog);lPort 指定一个可用的端口号,用来定位服务器上的服务器应用程序lbacklog指定能够连接到服务器的最多客户数。连接客户达到由backlog指定的最大客户数量时,服务器将拒绝客户连接Step 2:通过ServerSocket的accept方法监听客户连接,服务器无限期的监听客户连接Socket connection = myServer.accept();l有一个客户连接时,将产生并返回一个socket11.1.3 基于套接字
12、的有连接通信基于套接字的有连接通信(续续) 服务器端服务器端Java网络程序设计的基本概念12Step 3:通过Socket的方法getInputStream和getOutputStream获取InputStream和OutputStream对象;通常将其他流类型和它们联系起来,如:ObjectInputStream input = new ObjectInputStream( connection.getInputStream( ) );ObjectOutputStream output = new ObjectOutputStream( connection.getOutputStream
13、( ) );Step 4:客户和服务器通过OutputStream和InputStream对象进行通信Step 5:通信传输完毕,服务器通过调用流和套接字的close方法关闭连接11.1.3 基于套接字的有连接通信基于套接字的有连接通信(续续) 服务器端服务器端Java网络程序设计的基本概念13l在客户端建立简单连接的思路类似,可分为四步在客户端建立简单连接的思路类似,可分为四步Step 1:建立一个Socket,实现与服务器的连接Socket connection = new Socket ( InetAddress address, int port);laddress:服务器IP地址。p
14、ort:端口号l连接成功,将返回一个Socket,否则产生异常Step 2:通过getInputStream和getOutputStream分别获取Socket的InputStream和OutputStream的引用。同样,也可以将其他流类型与InputStream和OutputStream联系起来Step 3:客户与服务器通过InputStream和OutputStream进行通信Step 4:传输完毕后,通过调用流和套接字的close方法关闭连接11.1.3 基于套接字的有连接通信基于套接字的有连接通信(续续) 客户端客户端Java网络程序设计的基本概念1411.4 数据报通信数据报通信l
15、数据报通信数据报通信(Datagram Communication)使用用户数据报协议 ( User Datagram Protocol, UDP) l与TCP不同的一种协议l不能保证数据会被成功地送达,也不保证数据抵达的次序与送出的次序相同,所以也被称为“不可靠的通信协议”,虽然可靠性不高,但是它的速度很快,所以有些场合也有很大的用处服务器通过DatagramSocket接收或发送信息,这些信息以DatagramPackets 的形式存在DatagramSocket mySocket = new DatagramSocket ( int port );lport表示端口,上述语句将服务器绑定
16、到一个可以从客户端接收packet的端口上,如果绑定失败,将产生SocketException异常Java网络程序设计的基本概念15l客户端应用程序的工作流程客户端应用程序的工作流程Step1:通过创建一个DatagramSocket对象来建立数据报通讯的Socket。有如下两种构造方法public DatagramSocket() l构造一个数据报socket,并使其与本地主机任一可用的端口连接。若打不开socket则抛出SocketException异常。public DatagramSocket(int port)l 构造一个数据报socket,并使其与本地主机指定的端口连接。若打不开s
17、ocket或socket无法与指定的端口连接则抛出SocketException异常11.1.4 数据报通信数据报通信(续续) 客户端客户端Java网络程序设计的基本概念16Step 2:用DatagramPacket类来创建一个数据报包,用来实现无连接的包传送服务lDatagramPacket对象封装了数据报包的数据(bufferedarray,包长度(length),目标地址(address),目标端口(port);length必须小于等于bufferedarry.length DatagramPacket(byte bufferedarray, int length, InetAddre
18、ss address, int port)lDatagramPacket类提供了四个方法来获取信息public byte getData() 返回一个字节数组,包含收到或要发送的数据报中的数据public int getLength() 返回发送或接收到的数据的长度public InetAddress getAddress() 返回一个发送或接收此数据报包文的机器的IP地址public int getPort() 返回发送或接收数据报的远程主机的端口号11.1.4 数据报通信数据报通信(续续) 客户端客户端Java网络程序设计的基本概念17Step 3:调用DatagramSocket对象的s
19、end(DatagramPacket p)方法发送数据报文包Step 4:调用DatagramSocket对象的receive(DatagramPacket p)方法接收从服务器返回的结果数据报文包l该DatagramPacket对象用到另一种构造方法,只需指明存放接收的数据报的缓冲区和长度 DatagramPacket(byte bufferedarray, int length)lreceive方法会一直阻塞,直到收到一个数据报文包,此时DatagramPacket的缓冲区中包含的就是接收到的数据,也包含发送者的IP地址,发送者机器上的端口号等信息Step 5:处理接收缓冲区内的数据,获取
20、服务结果Step 6:通讯完成后,使用DatagramSocket对象的close()方法来关闭数据报通讯Socket11.1.4 数据报通信数据报通信(续续) 客户端客户端Java网络程序设计的基本概念18l服务器端应用程序的工作流程服务器端应用程序的工作流程 与客户端应用程序的通讯过程使非常相似 l建立数据报通讯DatagramSocketl构建数据报文包DatagramPacketl接收数据报和发送数据报,处理接收缓冲区内的数据l通讯完毕后,关闭数据报通讯Socket不同的是,服务器应用程序要面向网络中的所有计算机,所以服务器应用程序收到一个包文后要分析它,得到数据报的源地址信息,这样才
21、能创建正确的返回结果报文给客户机11.1.4 数据报通信数据报通信(续续) 服务器端服务器端Java网络程序设计的基本概念1911.5 ServletlServlet是用java技术来实现CGI(Common Gateway Interface, 通用网关接口)功能的编程介于浏览器(或其他HTTP客户端)与服务器之间,起到桥梁的作用。具体作用为:l读取客户端发送的数据l获取客户请(request)中所包含的信息l产生响应结果,并将结果包含到一个文件中,比如HTML文件中l设置HTTP响应参数,比如告诉浏览器,文件类型为HTMLl将文件返回给客户端Servlet的应用并不限于处理HTTP请求的网
22、页或者应用程序服务中,还可以置入到邮件或FTP服务程序中Java网络程序设计的基本概念20l与传统的与传统的CGI相比,相比,Servlet具有很多优点具有很多优点高效率l通过Servlet,Java虚拟机用轻量级的Java线程处理每个请求。同时有N个请求的情况下,CGI程序需要被调入到服务器内存N次;对于Servlet将开启N个线程,但仅仅调入一个Servlet实例到内存中应用方便lServlet在解析和译码HTML数据,读取设置HTML标题,操作Cookie等很多方面,应用更加方便。继承自java的特点,其可靠性与复用性好功能强大lServlet可以直接与Web服务程序对话;多个Servl
23、et可以共享数据;Servlet与数据库的连接也比较简单等11.1.5 Servlet(续续) 优点优点Java网络程序设计的基本概念21便携性好lServlet用Java语言编写,遵循标准的API。因此Servlet编写的程序可以无任何修改的在Apache,Microsoft Internet Information Server(IIS),IBM WebSphere,或者StarNine WebStar 上运行。同样具有一次编译,到处运行移植性好的特点安全l基于Java语言的安全特性,Servlet的安全性也比较可靠成本低l有很多免费或相对比较便宜的Web服务器,适合做个人的或者小容量的网
24、站。而且很多商业级的Web服务器相对也比较便宜。而且使一个服务器支持Servlet所需的额外花费也很少11.1.5 Servlet(续续) 优点优点Java网络程序设计的基本概念2211.2 Servlet基础基础l本节内容包括本节内容包括Servlet容器、web服务器、应用服务器Web应用程序Servlet APIServlet的基本结构Servlet编译和安装2311.2.1 Servlet容器、容器、Web服务器和应用服务器服务器和应用服务器lServlet容器容器也称为Servlet引擎是一个编译好的可执行程序,它是web服务器与servlet间的的媒介负责将请求翻译成Servlet
25、能够理解的形式传递给servlet,同时传给servlet一个对象使之可以送回响应负责管理servlet的生命周期Servlet 基础24lweb服务器服务器能够处理Http请求的服务器可以提供静态页面、图像等有的web服务器也支持动态页面的生成,支持JSP、Servlet等,具有JVMl应用服务器应用服务器可以处理基于多种协议的请求,当然也包括Http协议可以支持servlets和JSP,以及所有其他J2EE服务,包括JNDI、EJBs、JMS等 11.2.1 Servlet容器、容器、Web服务器和应用服务器服务器和应用服务器(续续)Servlet 基础25lservlet容器可以与容器可
26、以与web服务器协作提供对服务器协作提供对servlet的支持的支持l一些一些servlet容器(如容器(如Apache Tomcat)自己也可以作为独)自己也可以作为独立的立的web服务器运行服务器运行l随着随着servlet和和JSP的流行,一些主要的的流行,一些主要的Web服务器和应用程服务器和应用程序服务器都直接或者通过插件支持序服务器都直接或者通过插件支持servlet和和JSP。如:。如:Sun ONE Application ServerLotus Domino Go WebServerBEA weblogic Tengah ServerWebSphere应用服务器JigsawN
27、etForgeAcmeServerMot Bays Jetty 11.2.1 Servlet容器、容器、Web服务器和应用服务器服务器和应用服务器(续续)Servlet 基础26lApache Tomcat 5 是servlet2.4和JSP2.0规范的官方参考实现完全免费,并且提供完整的源代码可以到http:/jakarta.apache.org/tomcat/ 下载最新版本l初始设置初始设置设置JAVA_HOME。假设JDK安装在C: j2sdk1.4.2,可以仿照path和classpath的设置方法,新建一个环境变量:JAVA_HOMEC: j2sdk1.4.211.2.1 Servl
28、et容器、容器、Web服务器和应用服务器服务器和应用服务器(续续) Apache Tomcat 5服务器及其初始设置服务器及其初始设置Servlet 基础27l为方便调试,还可进行如下设置为方便调试,还可进行如下设置启动servlet重新载入功能(所请求servlet类文件发生变化后,自动重新载入到服务器内存)。打开install_dir/conf/server.xml,在注释 后插入语句 开启servlet调用器invoker servlet(可以不修改Web应用的web.xml文件即可运行servlet)。打开install_dir/conf/web.xml,将servlet-mappin
29、g元素取消注释 invoker /servlet/*11.2.1 Servlet容器、容器、Web服务器和应用服务器服务器和应用服务器(续续) Apache Tomcat 5服务器及其初始设置服务器及其初始设置Servlet 基础2811.2.2 Web应用程序应用程序lWeb应用程序应用程序组成部分包括servlet、JSP及其支持文件这些组成部分需要进行部署通常部署在Tomcat的webapps子目录中。一般其目录结构包括根目录(context root)和几个子目录,也可以把子目录捆绑到一个类型为war的存档文件中Servlet 基础2911.2.2 Web应用程序应用程序(续续)lwe
30、bapps子目录一般包括,子目录一般包括,WEB-INFl包含Web应用程序的部署描述文件(web.xml)l在web.xml文件中配置Web应用程序。可以制订各种配置参数:调用servlet的名称、servlet的描述、servlet的完全的类名和servlet容器调用servlet的路径l修改web.xml的部署描述符后,需要重新启动Tomcat服务器WEB-INF/classesl包括Web应用程序中所使用的servlet和实用工具类文件。如果类文件是包的组成部分,则包的目录结构从该目录开始WEB-INF/libl包含Java存档文件(JAR文件),是servlet和实用工具类文件Ser
31、vlet 基础3011.2.2 Web应用程序应用程序(续续)Servlet 基础3111.2.3 Servlet APIlServlet API开发servlet和JSP程序,需要参考Servlet API文档包含javax.servlet和javax.servlet.http两个包中所有servlet须实现javax.servlet.Servlet接口,通常继承如下两个类中的一个lGenericServletlHttpServletServlet 基础ServletGeneric servlet Http servlet My servlet32lServlet接口接口所有servlets
32、 必须实现这一接口Servlet接口的所有方法都是被自动调用的lHttpServlet类类覆盖了javax.servlet.Servlet接口的service方法lservice方法由方法由servlet容器调用,对客户端的请求作出响应。容器调用,对客户端的请求作出响应。它会根据请求类型的不同自动调用它会根据请求类型的不同自动调用doGet或或doPost等方法等方法能够处理两个最普通的 HTTP 请求类型ldoGet方法 响应 get 请求ldoPost 方法响应 post 请求Servlet 基础11.2.3 Servlet API(续续)3311.2.3 Servlet API(续续)l
33、HttpServletRequest接口接口由Web服务器创建该接口的一个对象,并将其传递给servlet的 service 方法该类对象含有来自于客户端的请求lHttpServletResponse接口接口由Web服务器创建该接口的一个 对象,并将其传送给servlet的 service 方法通过该类对象服务器端可以对客户端发出响应信息Servlet 基础3411.2.3 Servlet API(续续) HttpServletRequest接口接口Servlet 基础3511.2.3 Servlet API(续续) HttpServletResponse接口接口Servlet 基础3611.
34、2.4 Servlet的基本结构的基本结构lServlet的基本结构的基本结构一般扩展自HttpServlet复写doGet或者doPost方法ldoGet或doPost都接收两个类型的参数:HttpServletRequest和HttpServletResponsel通过HttpServletRequest,可以得到所有的输入数据,比如表单数据、HTTP请求报头等客户信息l通过HttpServletResponse可以指定输出信息l由于doGet和doPost方法可能生成异常,必须在方法名称后声明抛出异常或者用try-catch语句处理异常Servlet 基础37lGET请求是请求是WEB浏
35、览器请求的常见类型,用来请求浏览器请求的常见类型,用来请求Web页面。页面。 本例中通过本例中通过doGet方法处理方法处理GET请求。在请求。在doGet方法中通过方法中通过HttpServletResponse对象得到对象得到PrintWriter,然后将一个文档,然后将一个文档发给客户。最终在客户端生成一个网页发给客户。最终在客户端生成一个网页import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class MyServlet extends HttpServlet public void d
36、oGet( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException res.setContentType(text/html); PrintWriter out = res. getWriter(); out.println(); out.println(My First Servlet ); out.println(); out.println( First Servlet ); out.println();11.2.4 Servlet的基本结构的基本结构(续续) 例例11_2
37、Servlet 基础3811.2.5 Servlet编译和安装编译和安装l编译编译在设置好在设置好path和和classpath的前提下,的前提下,servlet的编的编译和普通的译和普通的java程序完全相同程序完全相同可以通过javac.exe编译,比如可以在Dos环境下输入:javac MyServlet.java也可以通过集成开发环境(IDE)编译l复制复制编译成功之后,将生成的类文件复制到相应的目录编译成功之后,将生成的类文件复制到相应的目录下即可。在下即可。在Tomcat服务器上,此目录可能是服务器上,此目录可能是 install_dirwebappsROOTWEB-INFclas
38、sesl运行运行启动启动Tomcat服务器,在地址栏输入服务器,在地址栏输入 http:/localhost:8080/servlet/MyServletServlet 基础3911.3 Servlet的生命周期的生命周期l首先服务器仅创建首先服务器仅创建servlet的一个实例的一个实例创建servlet实例时,它的init方法都会被调用l针对每个客户端的每个请求,都会创建一个线程针对每个客户端的每个请求,都会创建一个线程该线程调用servlet实例的service方法Service方法根据收到HTTP请求得类型,调用doGet,doPost或者其他方法多个并发请求,一般会导致多个线程同时调
39、用service方法,通过单线程模式(SingleThreadModel)也可以规定任何时间仅允许一个线程运行l最后,卸载最后,卸载servlet服务器调用servlet的destroy方法4011.3 Servlet的生命周期的生命周期(续续) Servlet生命周期示意图生命周期示意图服务器服务器服务器服务器Servlet代代码码服务器服务器客户端客户端客户端客户端装载Servlet代代码码卸载Servlet代代码码处理处理客户端请求客户端请求Servlet 的生命周期4111.3.1 初始化初始化lservlet的初始化的初始化服务器启动,servlet被用户首次调用,服务器构造serv
40、let实例之后,即立刻调用init(ServletConfig)方法,执行servlet实例的初始化工作ServeletConfig对象包含servlet初始化所需的很多参数,比如计数器、默认值等init方法都会在servlet处理客户请求(request)之前被调用一旦init方法被调用,只有服务器通过destroy方法销毁servlet之后,init方法才能再次被调用Servlet 的生命周期4211.3.1 初始化初始化(续续)linit方法的定义方法的定义public void init(ServletConfig config) throws ServletExceptionsupe
41、r.init(config);String greeting = getInitParameter(greeting);/ Initialization codeServlet 的生命周期4311.3.2 销毁销毁lservlet的销毁的销毁服务器卸载servlet实例之前,需要先调用servlet的destroy方法l释放servlet所获得的资源l使servlet有机会关闭数据库连接、停止后台运行的线程、将cookie列表和点击数写入到磁盘l执行其他清理活动Servlet 的生命周期4411.4 与客户端交互与客户端交互lHTTP servlet与客户端的交互与客户端的交互通过servic
42、e方法处理客户端的请求service方法根据请求(request)类型的不同,调用不同的方法l对于GET请求,调用doGet( )方法进行处理l对于POST请求,调用doPost( )方法进行处理4511.4.1 提取提取Servlet信息信息l注册的注册的servlet都有相关的很多初始化参数都有相关的很多初始化参数这些初始化参数写在web.xml中,具体语法格式请参阅Tomcat文档getInitParameter()方法l可以得到servlet初始化的一些参数l返回一个指定参数的值(String类型)l如果指定参数不存在,则返回nullgetInitParameterNames()方法l
43、可以得到初始化参数名称l返回String类型的Enumeration类型数据l如果不存在初始化参数,则返回一个null的Enumeration与客户端交互46l通过通过servlet初始化参数建立一个数据库连接的程序段如下初始化参数建立一个数据库连接的程序段如下java.sql.Connection con = null;public void init(ServletConfig config) throws ServletException super.init(config);String host = getInitParameter(host);int port = Integer.
44、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.1 提取提取Servlet信息信息(续续) 通过初始化建立数据库连接通过初始化建立数据库
45、连接与客户端交互47l输出全部初始化参数名称输出全部初始化参数名称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.ge
46、tWriter(); out.println(Init Parameters As Following:); Enumeration enum = getInitParameterNames(); while (enum.hasMoreElements() String name = (String) enum.nextElement(); out.println(name : + getInitParameter(name); 11.4.1 提取提取Servlet信息信息(续续) PrintInitParaNames.java与客户端交互4811.4.2 提取服务器信息提取服务器信息lser
47、vlet可以得到很多服务器相关的信息,同时可可以得到很多服务器相关的信息,同时可以将这些信息发送到客户端以将这些信息发送到客户端getServerName()返回服务器名称getServerPort()返回服务器监听端口getServerInfo()输出服务器程序和版本,之间用“/”分开getAttribute()返回服务程序的属性得到路径相关的信息lpublic String HttpServletRequest.getPathInfo()lpublic String HttpServletRequest.getPathTranslated()与客户端交互49l提取服务器信息举例提取服务器信
48、息举例 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.getServe
49、rName() 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(at
50、tribute) ); 11.4.2 提取提取服务器服务器信息信息(续续) 例例11_3与客户端交互5011.4.3 提取客户端信息提取客户端信息l服务器可以从服务器可以从request得到很多客户端的信息得到很多客户端的信息getRemoteAddr():得到IP地址getRemoteHost():得到客户端机器的名称利用InetAddress.getByName()方法可以将IP地址或客户端机器名称转换成一个.InetAddress类型的对象InetAddress remoteInetAddress = InetAddress.getByName(req.getRemoteAddr();l
51、通过获取客户端的地址,并判断是否隶属某个范围,可以限制某个地区的用户访问你的网站与客户端交互5111.4.3 提取客户端信息提取客户端信息(续续)l服务器可以得到客户想做的事情服务器可以得到客户想做的事情客户请求表现为表单数据,由“名/值”对组成。当提交某一个网页的时候常常在浏览器地址栏中看到类似格式的数据格式name/value,每对之间用&隔开,表达式为param1=value1¶m2=value2¶m3=value3request.getParameter:得到表单参数的值request.getParameterValues:得到多次出现的参数值reques.getPar
52、ameterNames:得到当前请求中所有参数的完整列表,调用形式如下lpublic String ServletRequest.getParameter(String name)lpublic String ServletRequest.getParameterValues(String name)与客户端交互52l书本查询的一个书本查询的一个HTML网页网页!DOCTYPE HTML PUBLIC -/W3C/DTD HTML 4.01 Transitional/EN A Sample Form for Query a Book Book to look up: 11.4.3 提取提取客户
53、端客户端信息信息(续续) Query.html与客户端交互53l获取客户端信息的获取客户端信息的servletimport java.io.*;import .*;import javax.servlet.*;import javax.servlet.http.*;public class QueryServlet extends HttpServlet public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException res.setContentTyp
54、e(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.3 提取提取客户端客户端信息信息(续续) QueryServlet.java与客户端交互5411.4.3 提取提取客户端客户端信息信息(续续) query.html与与QueryServlet运行结果运行结果与客户端交互5511.4.4 发
55、送发送HTML信息信息lWeb服务器响应服务器响应(response)的构成的构成状态行l由http版本(HTTP/1.1),一个状态代码(200)和一段对应状态代码的简短消息(OK)组成一些响应报头、lContent-Type: text/html 指定后面文档MIME类型,后面的其他报头可选。常用MIME类型有: text/html : HTML文档 text/plain: 纯文本 text/xml: XML image/jpeg:JEPG图像 application/msword: Microsoft Word文档 application/pdf:crobat文件 application
56、/zip:Zip档案一个空行和响应的文档与客户端交互56HTTP/1.1 200 OK /状态行Content-Type: text/html /报头Header2: HeaderN: /空行/文档 head code 11.4.4 发送发送HTML信息信息(续续)与客户端交互57l向客户端输出一个简单网页,显示向客户端输出一个简单网页,显示“Hello World!” import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class HelloWorld extends HttpServlet p
57、ublic void doGet( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException res.setContentType(text/html); PrintWriter out = res.getWriter(); out.println(); out.println(Hello World); out.println(); out.println(Hello World!); out.println(); 11.4.4 发送发送HTML信息信息(续续) 例例11_4与
58、客户端交互58l程序说明程序说明HelloWorld继承了HttpServlet,然后重写doGet方法在doGet方法中,首先将HTTP Content-Type响应报头设置为text/html,即指定响应的类型为HTML文档;然后通过getWriter()得到PrintWriter类型的一个对象out,按照HTML格式输出一个简单网页l运行结果运行结果11.4.4 发送发送HTML信息信息(续续) 例例11_4运行结果运行结果与客户端交互5911.5 客户端跟踪客户端跟踪l客户端跟踪客户端跟踪HTTP是无状态协议,服务器不能自动维护客户连接的上下文信息许多情况下,Web服务器必须要能够跟踪
59、用户的状态l比如购物网站和电子邮件网站,当用户登录以后,其身份和一系列的操作状态都需要被跟踪并保持servlet API提供了两种可以跟踪客户端状态的方法lCookielSession6011.5.1 使用使用CookielCookie是Web服务器保存在用户硬盘上的一段文本,Web服务器将它发送到浏览器之后,当再次访问同一网络时,浏览器将它原封不动的返回其中的信息片断以名/值对(name-value pairs)的形式储存使用这种方法,网站可以维护客户的连接。这种用途可以体现在如下几点l在电子商务中标识用户,实现短期跟踪用户l记录用户名和用户密码,允许用户下次自动登陆l定制站点,记录用户的偏
60、好l定向广告,记录用户感兴趣的主题,并显示与之相关的广告客户端跟踪61l调用调用Cookie的构造函数可创建一个的构造函数可创建一个cookie构造方法接受两个字符串参数lcookie名称lcookie的值例如创建一个名为CookieName,值为John的cookie,可以使用下面的语句Cookie login = new Cookie(“CookieName”, ”John”);客户端跟踪11.5.1 使用使用Cookie(续续) 创建创建Cookie对象对象62l创建了一个名为创建了一个名为login的的cookie之后,可通过很多之后,可通过很多现有的方法设置现有的方法设置cookie
61、的值和属性的值和属性可通过如下语句设置cookie的注释:login.setComent(“You can get UserName form this cookie”);创建cookie并将它发送到浏览器后,默认情况下,它是会话级的cookie,仅仅存储在浏览器内存中,用户退出浏览器后,cookie将被删除;如果希望将cookie存储在磁盘上,则需要设定MaxAge,给出一个以秒为单位的生命周期,如下可以将生命设置为一天login.setMaxAge(60*60*24)/ one daysetPath(),setValue(),setVersion(),setDomain(),setSecu
62、re()等,相关的具体用法请查看servlet API11.5.1 使用使用Cookie(续续) 设置设置Cookie属性属性客户端跟踪63l刚创建的刚创建的cookie存在于服务器内存中。必须将它发送到客户存在于服务器内存中。必须将它发送到客户端,端,cookie才能真正的发挥作用。发送才能真正的发挥作用。发送cookie需要使用需要使用HttpServletResponse的的addCookie方法,将方法,将cookie插入到插入到一个一个HTTP响应报头。发送的语句如下响应报头。发送的语句如下public void doGet (HttpServletRequest req, Http
63、ServletResponse res) throws ServletException, IOException Cookie login = new Cookie(“UserName”, ”John”); login.setComent(“You can get UserName form this cookie”); res.addCookie(login); /.客户端跟踪11.5.1 使用使用Cookie(续续) 发送发送Cookie到客户端到客户端64l从客户端读取你感兴趣的从客户端读取你感兴趣的cookie,需要两个步骤,需要两个步骤首先调用request.getCookies得
64、到一个Cookie对象的数组然后调用每个cookie的getName方法,从数组中寻找所需的cookieString nameString = “UserName”Cookie cookies = request.getCookies();for ( int i=0; icookies.length; i+) Cookie cookie = cookiesi;if (nameString.equals( cookie.getName() ) / do something / cookies.setMaxAge(0);l找到感兴趣的找到感兴趣的cookie之后,便可以操作此之后,便可以操作此co
65、okie, 如通过如通过getValue方法得到相关方法得到相关cookie的值,设置的值,设置MaxAge等等客户端跟踪11.5.1 使用使用Cookie(续续) 从客户读取从客户读取Cookie6511.5.2 使用使用SessionlSession一段时间内,单个客户与web服务器的一连串的交互过程在一个Session中客户可能会多次请求访问同一个网页,也有可能请求访问各种不同的服务器资源,其间用户的状态需要跟踪并保持存在于服务器端,不在网络上传送它的好处是可以用来记录客户端私有的信息,并且在时间范围内不会消失客户端跟踪6611.5.2 使用使用Session(续续)lSession的使
66、用可以分为三个步骤的使用可以分为三个步骤获得一个session存储数据到session或从session读取数据销毁session客户端跟踪67l通过调用通过调用httpServletRequest的的getSession方法可以得到一方法可以得到一个个sessionHttpSession session = request.getSession();l为了保持正确的会话,必须在发送任何文档到客户程序之前获为了保持正确的会话,必须在发送任何文档到客户程序之前获得一个得一个sessionpublic class SessionServlet extends HttpServlet public
67、void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException / Get the users session HttpSession session = request.getSession(true); /. out = response.getWriter(); / . 客户端跟踪11.5.2 使用使用Session(续续) 获得一个获得一个Session68lSession IDServlet容器为HttpSession分配的一个唯一标识
68、符作为Cookie保存在客户的浏览器中lsession cookie每次客户发出HTTP请求时,Servlet容器可以从HttpRequest对象中读取Session ID,然后根据Session ID在服务器端找到相应的HttpSession对象,从而获取客户的状态信息,这样的cookie叫做session cookie存储于浏览器内存中的,并不写到硬盘上的针对某一次会话而言,会话结束也就随着消失了客户端跟踪11.5.2 使用使用Session(续续) 存储或读取数据存储或读取数据69lURL 重写重写浏览器不支持 Cookie,或者将浏览器设置为不接受 Cookie的情况,可通过 URL
69、重写来实现会话管理向 URL 连接添加参数,并把 session ID 作为值包含在连接中。为 servlet 响应部分的每个连接添加 session ID ,可以使用一对方法lresponse.encodeURL() :使 URL 包含session IDlresponse.encodeRedirectURL():使用重定向客户端跟踪11.5.2 使用使用Session(续续) 存储或读取数据存储或读取数据70l从从Session中读取数据中读取数据session.getAttribute(“name”)l查找以前存储的值l如果不存在则返回nulll在调用此方法返回的对象前,一定要检查它是否
70、为nulll向向session中设置相关信息中设置相关信息setAttributel替换掉此前设定的任何值removeAttributel移除而不是替换某个值客户端跟踪11.5.2 使用使用Session(续续) 存储或读取数据存储或读取数据71public class SessionServlet extends HttpServlet public void doGet (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException / Get the users
71、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.2 使用使用Session(续续) SessionServlet.java客户端跟踪72l销
72、毁销毁Session意味着从系统删除session对象及其值自动销毁l在一段时间(时间长短依赖与Web服务器的设定)没有request的情况下,Web服务器会自动销毁session手动销毁l通过调用session的invalidate方法可以手动的销毁sessionlogoutl在支持servlet2.4的服务器中,可调用logout将客户从Web服务器中注销,同时废弃所有与该用户相关联的会话l需要注意的是,这个动作会影响到此servlet之外的其他servlet,因此一定要与网站的其他开发人员协调使用11.5.2 使用使用Session(续续) 销毁销毁Session客户端跟踪7311.6
73、协作与通信协作与通信l协作与通信协作与通信为了更好的响应客户端的请求,servlet有时需要和网络上的其他资源进行通讯,比如lHTML网页l其他servletlJSP网页Servlet协作通讯的第一步是获得分发器(dispatcher),即RequestDispatcher接口的一个对象74lRequestDispatcher接口接口产生一个RequestDispatcher接口的对象lRequestDispatcher dispatcher = getServletContext().getRequestDispatcher( /SomePath/SomeString);l通过设置字符串参数
74、,可以获得servlet,HTML网页,JSP网页等“资源”forward方法l将本servlet的request请求传递给“其他资源”响应l通过利用此方法可实现:servlet先预处理request,然后将处理后的request传递给“其他资源”处理include方法l引入“其他资源”来响应客户端的请求11.6. 协作与通信协作与通信(续续) RequestDispatcher接口接口协作与通信75lMyServlet1获取另外一个获取另外一个servlet(MyServlet2),并用它来),并用它来响应用户的请求响应用户的请求import java.io.*;import javax.s
75、ervlet.*;import javax.servlet.http.*;public class MyServlet1 extends HttpServlet public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException res.setContentType(text/html); RequestDispatcher summary= getServletContext().getRequestDispatcher( /servlet/MyServ
76、let2); 协作与通信11.6. 协作与通信协作与通信(续续) MyServlet1.java76 if (summary != null) try summary.include(req, res); catch (IOException e) catch (ServletException e) else if (summary = null) PrintWriter out = res.getWriter(); out.println(); out.println(Error); out.println(); out.println(Summary is Null); out.prin
77、tln(); 协作与通信11.6. 协作与通信协作与通信(续续) MyServlet1.java77import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class MyServlet2 extends HttpServlet public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException res.setContentType(text/html); Pri
78、ntWriter out = res.getWriter(); out.println(); out.println( MY second Servlet ); out.println(); out.println( name Bush ); out.println( Sex Male City); out.println(NewYork CountryU. S. A ); out.println(); 协作与通信11.6. 协作与通信协作与通信(续续) MyServlet2.java7811.6.1 Applet与与Servlet的通信的通信lApplet与与Servlet的通讯的通讯用户用
79、Applet发送消息到服务器对于动态网页,Applet与Servlet的通讯尤为重要比如在一个聊天系统中,当一个用户输入了某些语句时,聊天室内的所有其他用户都可以看到。此功能可能的实现步骤是l用户先把消息发给服务器l然后服务器发送给聊天室内的所有用户lApplet和和Servlet通讯的方式有多种通讯的方式有多种通过socket直接建立网络连接通过远程方法调用(Remote Method Inovation)通讯通过CORBA通讯协作与通信79lSocket通讯通讯服务器端的操作l首先创建一个ServerSocket对象,在指定端口监听客户端的requestl在接收到request后,acce
80、pt()方法返回一个Socket对象l通过socket对象创建输入输出流对象,并实现与客户端的交互l交互完毕后,关闭输入输出流和socket,最后关闭ServerSocker客户端的操作l首先创建socket对象,建立与服务器的连接l然后通过socket对象创建输入输出流,实现与服务器的交互l最后关闭输入输出流和socket协作与通信11.6.1 Applet与与Servlet的通信的通信(续续) Socket通讯通讯80l RMI通讯通讯Remote Method Invocation的简写,即远程方法调用通过存在于远程机器上的对象,可以发消息给远程的机器,且可以取得远程机器程序执行的结果。
81、整个调用过程类似于此对象存在于本地机器,无疑这大大简化了通讯过程当大量的数据是由服务器端的对象动态提供时使用RMI通讯是非常合适的如何使用RMIl先定义一个继承自java.rmi.Remote的公用接口。在该接口中定义要求在服务器上运行的方法l接下来是实现远程接口,远程接口的实现类应该实现:定义远程对象的构造方法,创建和安装安全管理器,创建一个或多个远程对象实例,并注册至少一个远程对象协作与通信11.6.1 Applet与与Servlet的通信的通信(续续) RMI通讯通讯81l通过通过CORBA通讯通讯即公用对象请求代理体系(Common Object Request Broker Arch
82、itecture),是OMA定义的一套和语言无关的分布式对象交换标准框架(Standard framework of object interoperability)CORBA的主要功能是RPC(Remote Procedure Call)式的支持,它使得本机对象可以调用远端对象的函数使用方法类似于RMIl定义接口l创建类实现接口l在服务器上注册后客户就可以像本地对象一样访问远程对象了11.6.1 Applet与与Servlet的通信的通信(续续) 通过通过CORBA通讯通讯协作与通信82lCORBA和和RMI的主要区别的主要区别CORBA使用一种语言中立的接口定义语言(IDL)来定义接口,I
83、DL是一种可用于混合语言环境的更为广泛的协议集RMI让Java对象之间可以进行RPCCORBA则让任何语言实现出来的对象之间进行RPC11.6.1 Applet与与Servlet的通信的通信(续续) CORBA和和RMI的主要区别的主要区别协作与通信8311.6.2 Servlet间的信息共享间的信息共享lservlet间的信息共享间的信息共享通过方法调用通过共享类对象利用java语言的Properties列表lProperties列表包含系统的很多信息,比如java.version,path,separater,应用程序相关的很多属性等l可通过如下的方法添加一个属性到此列表 System.g
84、etProperties().put(key, value);l运行在同一个JVM上的其他servlet可调用属性 String value = System.getProperty(key);l也可以通过如下语句删除列表中的某项属性: System.getProperties().remove(key);协作与通信8411.7 程序举例程序举例例例11_7l通过会话跟踪,实现对客户访问次数记数的功能通过会话跟踪,实现对客户访问次数记数的功能import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import
85、 .*; import java.util.*;public class TrackSession extends HttpServlet public void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException String heading; Integer count; response.setContentType(text/html); HttpSession session = request.getSession(true); c
86、ount =(Integer)session.getAttribute(count);85 if (count = null) count = new Integer(0); heading = First visiting; else heading = Welcome Back; count = new Integer(count.intValue() + 1);session.setAttribute(count, count);PrintWriter out = response.getWriter();String docType = n;out.println( docType +
87、n + + heading + n +n +n + NAMEVALUEn +n + ID:n + + session.getId() + n +n + Creation Time:n + +new Date(session.getCreationTime() + n +n +Last Access Time:n + +new Date(session.getLastAccessedTime() + n +n + Count:n + + count + n +n +“ ); public void doPost( HttpServletRequest request,HttpServletRes
88、ponse response) throws ServletException, IOException doGet(request, response); / doPost方法直接调用doGet 11.7 程序举例程序举例例例11_7程序举例8611.7 程序举例程序举例 例例11_7运行结果运行结果程序举例点击刷新按钮2次后关闭浏览器再次打开后87l利用利用cookie的的servlet同样也可以实现记录用户访问次数的功能同样也可以实现记录用户访问次数的功能import java.io.*;import javax.servlet.*;import javax.servlet.http.*
89、;import .*;public class AccessCounts extends HttpServlet public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException String cookieName, numString; cookieName = numString; numString = 1; Cookie cks = req.getCookies(); if (cks != null) for (int i=0; icks.leng
90、th; i+) Cookie tempCk = cksi; if(cookieName.equals(tempCk.getName() numString = tempCk.getValue(); 11.7 程序举例程序举例例例11_8程序举例88 int num = 0; try num = Integer.parseInt(numString); catch(NumberFormatException e) Cookie myCookie = new Cookie( numString,String.valueOf(num+1) ); myCookie.setMaxAge(60*60*24
91、); res.addCookie(myCookie); res.setContentType(text/html); PrintWriter out = res.getWriter(); String title = User Access Count ; String docType = n; out.println( docType+ n+ + title + + n+ Access Count is: + num + + ); 11.7 程序举例程序举例例例11_8程序举例89程序举例11.7 程序举例程序举例 例例11_8运行结果运行结果点击刷新按钮6次后关闭浏览器再次打开后90l例例
92、11_7使用使用Session的的servlet重启Web服务器后,计数将要重新从0开始;这是因为session存在服务器内存中关闭浏览器再次打开后,上一次会话已经结束,技术重新从0开始l例例11_8使用使用cookie的的servlet重启Web服务器或关闭浏览器再次打开后,都可以正确计数,因为Cookie存在与客户端,且在程序中设计其生命为1天当客户端删除存在的cookie后,计数才会从0开始。对IE浏览器来说,可以在菜单“工具”下调出“Internet选项”,然后选择“删除Cookie(I)”,从而方便实现含有Cookie的servlet的调试程序举例11.7 程序举例程序举例 例例11_7和例和例11_8结果分析结果分析9111.8 本章小结本章小结l本章内容本章内容Java网络程序设计的基本概念servlet的基础知识,包括servlet的基本结构和生命周期servlet与客户端交互的技术以及客户端跟踪技术servlet与其它网络资源的交互l本章要求本章要求了解基于TCP协议的有连接通讯和基于UDP协议的数据报通讯的含义熟悉servlet的常用API以及servlet的编程方法92