




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1第十讲Servlet程序设计郑莉2目录10.1Java网络程序设计的根本概念——看MOOC:Java程序设计进阶第四~五章10.2Servlet根底10.3Servlet的生命周期10.4与客户端交互10.5客户端跟踪10.6协作与通讯10.7程序举例10.8本章小结34网络将世界联系在一起,使世界变得更加丰富多彩。同时网络互连是一个内容丰富而复杂的主题,所以这方面的程序设计涉及面很广且不易掌握与其他语言相比,Java语言在网络应用程序方面具有一定的优势。Java提供了很多内置的网络功能,使得基于Internet和Web的应用开发变得更加容易10.1Java网络程序设计的根本概念510.1.1协议所有使用或实现某种Internet效劳的程序都必须遵从一个或多个网络协议,这种协议很多,而IP、TCP、UDP是最为根本的三种协议,是所有其它协议的根底IP〔InternetProtocol,Internet协议〕是最底层的协议定义了数据按照数据报〔Datagram,一种自带寻址信息的、独立地从数据源走到终点的数据包〕传输的格式和规那么TCP〔TransportControlProtocol,传输控制协议〕建立在IP之上,定义了网络上程序到程序的数据传输格式和规那么,提供了IP数据包的传输确认、丧失数据包的重新请求、将收到的数据包按照它们的发送次序重新装配的机制是面向连接的协议,在开始数据传输之前,必须先建立明确的连接UDP〔UserDatagramProtocol,用户数据报协议〕与TCP相似,比TCP具有更好的传输效率。不可靠的,不保证数据的传输,也不提供重新排列次序或重新请求功能,是一种无连接协议10.1Java网络程序设计的根本概念6HTTP协议〔HyperTextTransferProtocol〕是Internet众多协议中的一种,表示超文本传输协议,它构成了WWW的根底具有简单快速、灵活、无状态、无连接等特点基于请求〔Request〕/响应〔Response〕模式。其工作过程如下首先客户端与效劳器建立连接然后客户端发送一个请求给效劳器效劳器接到请求后,给予相应的响应信息;最后关闭连接,完成一次操作10.1.1协议(续)
——HTTP协议10.1Java网络程序设计的根本概念7客户端发送给效劳器的请求有很多类型,被称为方法,其中最常用的是GET、POSTGET方法用来从效劳器读取信息,比方从效劳器读取文件、表格、数据库查询结果等POST方法用来向效劳器传送信息,比方把信用卡号、表格、存储于数据库的数据等传送到效劳器HEAD方法用来读取效劳器响应头〔ResponseHead〕;得到诸如文件大小,文件最后修改时间,效劳器类型等信息PUT方法将文件直接传到效劳器DELETE方法将文件直接从效劳器删除TRACE方法用来协助程序调试OPTIONS方法用来查询效劳器所支持的方法10.1Java网络程序设计的根本概念10.1.1协议(续)
——HTTP协议中客户端发送给效劳器的请求810.1.2关于URIURI〔UniformResourceIdentifier,统一资源标识符〕HTTP协议用URI标识定位网络上的数据如果知道了公布在网络上的某个HTML文件的URI,不管文件位于什么地方,都可以通过HTTP访问该文档通常所说的URL是URI的一种10.1Java网络程序设计的根本概念9URL类Java语言提供了URL类让我们能在源代码层使用URL有六个构造方法,其中最简单的是URL(Stringurl)。每个URL对象都封装了资源的标识符和协议处理程序,可以调用URL的方法来提取URL的组件把URL对象作为AppletContext接口的showDocument方法的参数,就可以使执行applet的浏览器显示URL所指定的资源10.1.2关于URI(续)
——URL类10.1Java网络程序设计的根本概念10applet浏览指定URL举例:ShowDocument.javaimport.*;importjava.util.*;importjava.awt.*;importjava.awt.event.*;importjava.applet.AppletContext;importjavax.swing.*;importjavax.swing.event.*;publicclassShowDocumentextendsJApplet{ publicvoidinit(){ JButtongoButton=newJButton("Linktosohu"); ContainermyContainer=getContentPane(); myContainer.add(newJLabel("LinktoSOHU"),BorderLayout.NORTH); myContainer.add(goButton,BorderLayout.SOUTH); goButton.addActionListener(newButtonListener()); }
10.1Java网络程序设计的根本概念10.1.2关于URI(续)
——例10-111classButtonListenerimplementsActionListener{ publicvoidactionPerformed(ActionEvente){ try{ URLnewDocument=newURL("://sohu"); AppletContextbrowser=getAppletContext(); browser.showDocument(newDocument); } catch(ExceptionURLException){} } }}10.1Java网络程序设计的根本概念10.1.2关于URI(续)
——例10-11210.1.3基于套接字的有连接通信基于套接字(socket)的有连接通信使用TCP协议一个socket必须在发送数据之前与目的地的socket取得连接一旦连接建立了,sockets就可以使用一个流接口完成翻开-读-写-关闭,所有的发送的信息都会在另一端以同样的顺序被接收面向连接的操作比无连接的操作效率低,但是数据的平安性高10.1Java网络程序设计的根本概念13用Java建立简单的效劳器程序需要五个步骤Step1:创立ServerSocket对象ServerSocketmyServer=newServerSocket(intport,intbacklog);Port指定一个可用的端口号,用来定位效劳器上的效劳器应用程序backlog指定能够连接到效劳器的最多客户数。连接客户到达由backlog指定的最大客户数量时,效劳器将拒绝客户连接Step2:通过ServerSocket的accept方法监听客户连接,效劳器无限期的监听客户连接Socketconnection=myServer.accept();有一个客户连接时,将产生并返回一个socket10.1Java网络程序设计的根本概念10.1.3基于套接字的有连接通信(续)
——效劳器端14Step3:通过Socket的方法getInputStream和getOutputStream获取InputStream和OutputStream对象;通常将其他流类型和它们联系起来,如:ObjectInputStreaminput=newObjectInputStream(connection.getInputStream());ObjectOutputStreamoutput=newObjectOutputStream(connection.getOutputStream());Step4:客户和效劳器通过OutputStream和InputStream对象进行通信Step5:通信传输完毕,效劳器通过调用流和套接字的close方法关闭连接10.1Java网络程序设计的根本概念10.1.3基于套接字的有连接通信(续)
——效劳器端15在客户端建立简单连接的思路类似,可分为四步Step1:建立一个Socket,实现与效劳器的连接Socketconnection=newSocket(InetAddressaddress,intport);address:效劳器IP地址。port:端口号连接成功,将返回一个Socket,否那么产生异常Step2:通过getInputStream和getOutputStream分别获取Socket的InputStream和OutputStream的引用。同样,也可以将其他流类型与InputStream和OutputStream联系起来Step3:客户与效劳器通过InputStream和OutputStream进行通信Step4:传输完毕后,通过调用流和套接字的close方法关闭连接10.1Java网络程序设计的根本概念10.1.3基于套接字的有连接通信(续)
——客户端16数据报通信(DatagramCommunication)使用用户数据报协议(UserDatagramProtocol,UDP)与TCP不同的一种协议不能保证数据会被成功地送达,也不保证数据抵达的次序与送出的次序相同,所以也被称为“不可靠的通信协议”,虽然可靠性不高,但是它的速度很快,所以有些场合也有很大的用处效劳器通过DatagramSocket接收或发送信息,这些信息以DatagramPackets的形式存在DatagramSocketmySocket=newDatagramSocket(intport);port表示端口,上述语句将效劳器绑定到一个可以从客户端接收packet的端口上,如果绑定失败,将产生SocketException异常10.1Java网络程序设计的根本概念10.1.4数据报通信17客户端应用程序的工作流程Step1:通过创立一个DatagramSocket对象来建立数据报通讯的Socket。有如下两种构造方法publicDatagramSocket()构造一个数据报socket,并使其与本地主机任一可用的端口连接。假设打不开socket那么抛出SocketException异常。publicDatagramSocket(intport)构造一个数据报socket,并使其与本地主机指定的端口连接。假设打不开socket或socket无法与指定的端口连接那么抛出SocketException异常10.1Java网络程序设计的根本概念10.1.4数据报通信(续)
——客户端18Step2:用DatagramPacket类来创立一个数据报包,用来实现无连接的包传送效劳DatagramPacket对象封装了数据报包的数据(bufferedarray[],包长度(length),目标地址(address),目标端口(port);length必须小于等于bufferedarry.lengthDatagramPacket〔bytebufferedarray[],intlength,InetAddressaddress,intport〕DatagramPacket类提供了四个方法来获取信息publicbyte[]getData()返回一个字节数组,包含收到或要发送的数据报中的数据publicintgetLength()返回发送或接收到的数据的长度publicInetAddressgetAddress()返回一个发送或接收此数据报包文的机器的IP地址publicintgetPort()返回发送或接收数据报的远程主机的端口号10.1Java网络程序设计的根本概念10.1.4数据报通信(续)
——客户端19Step3:调用DatagramSocket对象的send(DatagramPacketp)方法发送数据报文包Step4:调用DatagramSocket对象的receive(DatagramPacketp)方法接收从效劳器返回的结果数据报文包该DatagramPacket对象用到另一种构造方法,只需指明存放接收的数据报的缓冲区和长度DatagramPacket〔bytebufferedarray[],intlength〕receive方法会一直阻塞,直到收到一个数据报文包,此时DatagramPacket的缓冲区中包含的就是接收到的数据,也包含发送者的IP地址,发送者机器上的端口号等信息Step5:处理接收缓冲区内的数据,获取效劳结果Step6:通讯完成后,使用DatagramSocket对象的close()方法来关闭数据报通讯Socket10.1Java网络程序设计的根本概念10.1.4数据报通信(续)
——客户端20效劳器端应用程序的工作流程与客户端应用程序的通讯过程非常相似建立数据报通讯DatagramSocket构建数据报文包DatagramPacket接收数据报和发送数据报,处理接收缓冲区内的数据通讯完毕后,关闭数据报通讯Socket不同的是,效劳器应用程序要面向网络中的所有计算机,所以效劳器应用程序收到一个包文后要分析它,得到数据报的源地址信息,这样才能创立正确的返回结果报文给客户机10.1Java网络程序设计的根本概念10.1.4数据报通信(续)
——效劳器端2110.1.5ServletServlet是用java技术来实现CGI〔CommonGatewayInterface,通用网关接口〕功能的编程介于浏览器〔或其他HTTP客户端〕与效劳器之间,起到桥梁的作用。具体作用为:读取客户端发送的数据获取客户请求〔request〕中所包含的信息产生响应结果,并将结果包含到一个文件中,比方HTML文件中设置HTTP响应参数,比方告诉浏览器,文件类型为HTML将文件返回给客户端10.1Java网络程序设计的根本概念22Servlet具有很多优点高效率通过Servlet,Java虚拟机用轻量级的Java线程处理每个请求。同时有N个请求的情况下,CGI程序需要被调入到效劳器内存N次;对于Servlet将开启N个线程,但仅仅调入一个Servlet实例到内存中应用方便Servlet在解析和译码HTML数据,读取设置HTML标题,操作Cookie等很多方面,应用更加方便。继承自java的特点,其可靠性与复用性好功能强大Servlet可以直接与Web效劳程序对话;多个Servlet可以共享数据;Servlet与数据库的连接也比较简单等10.1Java网络程序设计的根本概念10.1.5Servlet(续)
——优点23便携性好Servlet用Java语言编写,遵循标准的API。因此Servlet编写的程序可以无任何修改的在Apache,MicrosoftInternetInformationServer(IIS),IBMWebSphere,或者StarNineWebStar上运行。同样具有一次编译,到处运行移植性好的特点平安基于Java语言的平安特性,Servlet的平安性也比较可靠本钱低有很多免费或相比照较廉价的Web效劳器,适合做个人的或者小容量的网站。而且很多商业级的Web效劳器相对也比较廉价。而且使一个效劳器支持Servlet所需的额外花费也很少10.1Java网络程序设计的根本概念10.1.5Servlet(续)
——优点2410.2Servlet根底本节内容包括Servlet容器、web效劳器、应用效劳器Web应用程序ServletAPIServlet的根本结构Servlet编译和安装25Servlet容器也称为Servlet引擎是一个编译好的可执行程序,它是web效劳器与servlet间的媒介负责将请求翻译成Servlet能够理解的形式传递给servlet,同时传给servlet一个对象使之可以送回响应负责管理servlet的生命周期10.2Servlet根底10.2.1Servlet容器、Web效劳器和应用效劳器26web效劳器能够处理Http请求的效劳器可以提供静态页面、图像等有的web效劳器也支持动态页面的生成,支持JSP、Servlet等,具有JVM应用效劳器可以处理基于多种协议的请求,当然也包括Http协议可以支持servlets和JSP,以及所有其他J2EE效劳,包括JNDI、EJBs、JMS等10.2Servlet根底10.2.1Servlet容器、Web效劳器和应用效劳器27servlet容器可以与web效劳器协作提供对servlet的支持一些servlet容器〔如ApacheTomcat〕自己也可以作为独立的web效劳器运行随着servlet和JSP的流行,一些主要的Web效劳器和应用程序效劳器都直接或者通过插件支持servlet和JSP。如:SunONEApplicationServerLotusDominoGoWebServerBEAweblogicTengahServerWebSphere应用效劳器JigsawNetForgeAcmeServerMotBaysJetty10.2Servlet根底10.2.1Servlet容器、Web效劳器和应用效劳器28ApacheTomcat5是servlet2.4和JSP2.0标准的官方参考实现完全免费,并且提供完整的源代码可以到下载最新版本初始设置设置JAVA_HOME。假设JDK安装在F:\ProgramFiles\Java\jdk1.6.0_10,可以仿照path和classpath的设置方法,新建一个环境变量:JAVA_HOME=F:\ProgramFiles\Java\jdk1.6.0_1010.2Servlet根底10.2.1Servlet容器、Web效劳器和应用效劳器
——ApacheTomcat5效劳器及其初始设置29为方便调试,还可进行如下设置启动servlet重新载入功能〔所请求servlet类文件发生变化后,自动重新载入到效劳器内存〕。翻开install_dir/conf/server.xml,在注释<!--Definepropertiesforeachwebapplication-->后插入语句<DefaultContextreloadable=“true”/>开启servlet调用器invokerservlet〔可以不修改Web应用的web.xml文件即可运行servlet〕。翻开install_dir/conf/web.xml,将servlet-mapping元素取消注释<servlet-mapping><servlet-name>invoker</servlet-name><url-pattern>/servlet/*</url-pattern></servlet-mapping>10.2Servlet根底10.2.1Servlet容器、Web效劳器和应用效劳器
——ApacheTomcat5效劳器及其初始设置30在install_dir/conf/web.xml中,将以下元素取消注释:
<servlet><servlet-name>invoker</servlet-name><servlet-class></servlet-class><init-param><param-name>debug</param-name>
<param-value>0</param-value></init-param>
<load-on-startup>2</load-on-startup></servlet>对于Tomcat6,还需在install_dir/conf/context.xml文件中,对Context节点添加“privileged="true"”属性,如下:<Contextprivileged="true">…………</Context>10.2Servlet根底10.2.1Servlet容器、Web效劳器和应用效劳器
——ApacheTomcat5效劳器及其初始设置3110.2.2Web应用程序Web应用程序组成局部包括servlet、JSP及其支持文件这些组成局部需要进行部署通常部署在Tomcat的webapps子目录中。一般其目录结构包括根目录(contextroot)和几个子目录,也可以把子目录捆绑到一个类型为war的存档文件中10.2Servlet根底3210.2.2Web应用程序(续)webapps子目录一般包括,WEB-INF包含Web应用程序的部署描述文件(web.xml)在web.xml文件中配置Web应用程序。可以制订各种配置参数:调用servlet的名称、servlet的描述、servlet的完全的类名和servlet容器调用servlet的路径修改web.xml的部署描述符后,需要重新启动Tomcat效劳器WEB-INF/classes包括Web应用程序中所使用的servlet和实用工具类文件。如果类文件是包的组成局部,那么包的目录结构从该目录开始WEB-INF/lib包含Java存档文件(JAR文件),是servlet和实用工具类文件10.2Servlet根底3310.2.3ServletAPIServletAPI开发servlet和JSP程序,需要参考ServletAPI文档包含javax.servlet和两个包中所有servlet须实现接口,通常继承如下两个类中的一个GenericServletHttpServletServletGenericservletHttpservletMyservlet10.2Servlet根底34Servlet接口所有servlets必须实现这一接口Servlet接口的所有方法都是被自动调用的HttpServlet类覆盖了接口的service方法service方法由servlet容器调用,对客户端的请求作出响应。它会根据请求类型的不同自动调用doGet或doPost等方法能够处理两个最普通的HTTP请求类型doGet方法响应get请求doPost方法响应post请求10.2.3ServletAPI(续)10.2Servlet根底3510.2.3ServletAPI(续)HttpServletRequest接口由Web效劳器创立该接口的一个对象,并将其传递给servlet的service方法该类对象含有来自于客户端的请求HttpServletResponse接口由Web效劳器创立该接口的一个对象,并将其传送给servlet的service方法通过该类对象效劳器端可以对客户端发出响应信息10.2Servlet根底3610.2.4Servlet的根本结构Servlet的根本结构一般扩展自HttpServlet覆盖doGet或者doPost方法doGet或doPost都接收两个类型的参数:HttpServletRequest和HttpServletResponse通过HttpServletRequest,可以得到所有的输入数据,比方表单数据、HTTP请求报头等客户信息通过HttpServletResponse可以指定输出信息由于doGet和doPost方法可能生成异常,必须在方法名称后声明抛出异常或者用try-catch语句处理异常10.2Servlet根底37GET请求是WEB浏览器请求的常见类型,用来请求Web页面。本例中通过doGet方法处理GET请求。在doGet方法中通过HttpServletResponse对象得到PrintWriter,然后将一个文档发给客户。最终在客户端生成一个网页importjava.io.*;importjavax.servlet.*;importjavax.servlet..*;publicclassMyServletextendsHttpServlet{ publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{res.setContentType("text/html"); PrintWriterout=res.getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE>MyFirstServlet</TITLE></HEAD>"); out.println("<BODY>"); out.println("<B>FirstServlet</B>"); out.println("</BODY></HTML>"); }}10.2.4Servlet的根本结构(续)
——例10-210.2Servlet根底3810.2.5Servlet编译和安装编译——在设置好path和classpath的前提下,servlet的编译和普通的java程序完全相同可以通过javac.exe编译,比方可以在Dos环境下输入:javacMyServlet.java也可以通过集成开发环境(IDE)编译复制——编译成功之后,将生成的类文件复制到相应的目录下即可。在Tomcat效劳器上,此目录可能是install_dir\webapps\ROOT\WEB-INF\classes\运行——启动Tomcat效劳器,在地址栏输入://localhost:8080/servlet/MyServlet10.2Servlet根底3910.3Servlet的生命周期首先效劳器仅创立servlet的一个实例创立servlet实例时,它的init方法都会被调用针对每个客户端的每个请求,都会创立一个线程该线程调用servlet实例的service方法Service方法根据收到HTTP请求得类型,调用doGet,doPost或者其他方法多个并发请求,一般会导致多个线程同时调用service方法,通过单线程模式〔SingleThreadModel〕也可以规定任何时间仅允许一个线程运行最后,卸载servlet效劳器调用servlet的destroy方法4010.3Servlet的生命周期(续)
——Servlet生命周期示意图4110.3.1初始化servlet的初始化效劳器启动,servlet被用户首次调用,效劳器构造servlet实例之后,即立刻调用init(ServletConfig)方法,执行servlet实例的初始化工作ServeletConfig对象包含servlet初始化所需的很多参数,比方计数器、默认值等init方法都会在servlet处理客户请求(request)之前被调用一旦init方法被调用,只有效劳器通过destroy方法销毁servlet之后,init方法才能再次被调用10.3Servlet的生命周期4210.3.1初始化(续)init方法的定义publicvoidinit(ServletConfigconfig)throwsServletException{ super.init(config); Stringgreeting=getInitParameter("greeting"); //Initializationcode…}10.3Servlet的生命周期4310.3.2销毁servlet的销毁效劳器卸载servlet实例之前,需要先调用servlet的destroy方法释放servlet所获得的资源使servlet有时机关闭数据库连接、停止后台运行的线程、将cookie列表和点击数写入到磁盘执行其他清理活动10.3Servlet的生命周期4410.4与客户端交互HTTPservlet与客户端的交互通过service方法处理客户端的请求service方法根据请求(request)类型的不同,调用不同的方法对于GET请求,调用doGet()方法进行处理对于POST请求,调用doPost()方法进行处理4510.4.1提取Servlet信息注册的servlet都有相关的很多初始化参数这些初始化参数写在web.xml中。getInitParameter()方法可以得到servlet初始化的一些参数返回一个指定参数的值〔String类型〕如果指定参数不存在,那么返回nullgetInitParameterNames()方法可以得到初始化参数名称返回String类型的Enumeration类型数据如果不存在初始化参数,那么返回一个null的Enumeration10.4与客户端交互46通过servlet初始化参数建立一个数据库连接的程序段如下java.sql.Connectioncon=null;publicvoidinit(ServletConfigconfig)throwsServletException{ super.init(config); Stringhost=getInitParameter("host");
intport=Integer.parseInt(getInitParameter("port"));
Stringdb=getInitParameter("db"); Stringuser=getInitParameter("user"); Stringpassword=getInitParameter("password"); Stringproxy=getInitParameter("proxy");
con=establishConnection(host,port,db,user,password,proxy);}10.4与客户端交互10.4.1提取Servlet信息(续)
——通过初始化建立数据库连接47输出全部初始化参数名称importjava.io.*;importjava.util.*;importjavax.servlet.*;publicclassPrintInitParaNamesextendsGenericServlet{ publicvoidservice(ServletRequestreq,ServletResponseres) throwsServletException,IOException{
res.setContentType("text/plain"); PrintWriterout=res.getWriter(); out.println("InitParametersAsFollowing:"); Enumerationenum=getInitParameterNames(); while(enum.hasMoreElements()){ Stringname=(String)enum.nextElement(); out.println(name":"+getInitParameter(name)); }}}10.4与客户端交互10.4.1提取Servlet信息(续)
——PrintInitParaNames.java4810.4.2提取效劳器信息servlet可以得到很多效劳器相关的信息,同时可以将这些信息发送到客户端getServerName()返回效劳器名称getServerPort()返回效劳器监听端口getServerInfo()输出效劳器程序和版本,之间用“/”分开getAttribute()返回效劳程序的属性得到路径相关的信息publicStringHttpServletRequest.getPathInfo()publicStringHttpServletRequest.getPathTranslated()10.4与客户端交互49提取效劳器信息举例importjava.io.*;importjava.util.*;importjavax.servlet.*;publicclassServerSnoopextendsGenericServlet{publicvoidservice(ServletRequestreq,ServletResponseres)throwsServletException,IOException{res.setContentType("text/plain");PrintWriterout=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"));}}10.4与客户端交互10.4.2提取效劳器信息(续)
——例10-35010.4.3提取客户端信息效劳器可以从request得到很多客户端的信息getRemoteAddr():得到IP地址getRemoteHost():得到客户端机器的名称利用InetAddress.getByName()方法可以将IP地址或客户端机器名称转换成一个类型的对象InetAddressremoteInetAddress=InetAddress.getByName(req.getRemoteAddr());通过获取客户端的地址,并判断是否隶属某个范围,可以限制某个地区的用户访问你的网站10.4与客户端交互5110.4.3提取客户端信息(续)效劳器可以得到客户想做的事情客户请求表现为表单数据,由“名/值”对组成。当提交某一个网页的时候常常在浏览器地址栏中看到类似格式的数据格式name/value,每对之间用&隔开,表达式为param1=value1¶m2=value2¶m3=value3…request.getParameter:得到表单参数的值request.getParameterValues:得到屡次出现的参数值reques.getParameterNames:得到当前请求中所有参数的完整列表,调用形式如下publicStringServletRequest.getParameter(Stringname)publicString[]ServletRequest.getParameterValues(Stringname)10.4与客户端交互52书本查询的一个HTML网页!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><HTML><HEAD><TITLE>ASampleFormforQueryaBook</TITLE></HEAD><BODYBGCOLOR="#FDF5E6"><FORMMETHOD=GETACTION="/Chapter11/QueryServlet">Booktolookup:<INPUTTYPE="TEXT"NAME="Book"VALUE="JavaServletProgramming"><!--Thedefaultbooktobelookedupis:《JavaServletProgramming》.--><INPUTTYPE=SUBMIT></FORM></BODY></HTML>10.4与客户端交互10.4.3提取客户端信息(续)
——Query.html53获取客户端信息的servletimportjava.io.*;import.*;importjavax.servlet.*;importjavax.servlet..*;publicclassQueryServletextendsHttpServlet{publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres) throwsServletException,IOException{res.setContentType("text/html;charset=UTF-8");StringqueryBookValue=req.getParameter("Book");PrintWriterout=res.getWriter();out.println("Thebookyouwantedis:"+queryBookValue);out.close();}}10.4与客户端交互10.4.3提取客户端信息(续)
——QueryServlet.java5410.4与客户端交互10.4.3提取客户端信息(续)
——Query.html与QueryServlet运行结果5510.4.4发送HTML信息Web效劳器响应(response)的构成状态行由版本(HTTP/1.1),一个状态代码(200)和一段对应状态代码的简短消息(OK)组成一些响应报头、Content-Type:text/html指定后面文档MIME类型,后面的其他报头可选。常用MIME类型有:text/html:HTML文档text/plain:纯文本text/xml:XMLimage/jpeg:JEPG图像application/msword:MicrosoftWord文档application/pdf:crobat文件application/zip:Zip档案一个空行和响应的文档10.4与客户端交互56HTTP/1.1200OK //状态行Content-Type:text/html //报头Header2:……HeaderN:… //空行<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN"> //文档<HTML><HEAD>headcode</HEAD><BODY>…</BODY></HTML>10.4.4发送HTML信息(续)10.4与客户端交互57向客户端输出一个简单网页,显示“HelloWorld!”importjava.io.*;importjavax.servlet.*;importjavax.servlet..*;publicclassHelloWorldextendsHttpServlet{publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{res.setContentType("text/html");PrintWriterout=res.getWriter();out.println("<HTML>");out.println("<HEAD><TITLE>HelloWorld</TITLE></HEAD>");out.println("<BODY>");out.println("<BIG>HelloWorld!</BIG>");out.println("</BODY></HTML>");}}10.4与客户端交互10.4.4发送HTML信息(续)
——例10-458程序说明HelloWorld继承了HttpServlet,然后重写doGet方法在doGet方法中,首先将HTTPContent-Type响应报头设置为text/html,即指定响应的类型为HTML文档;然后通过getWriter()得到PrintWriter类型的一个对象out,按照HTML格式输出一个简单网页运行结果10.4与客户端交互客户端跟踪10.4.4发送HTML信息(续)
——例10-4运行结果5910.5客户端跟踪客户端跟踪HTTP是无状态协议,效劳器不能自动维护客户连接的上下文信息许多情况下,Web效劳器必须要能够跟踪用户的状态比方购物网站和电子邮件网站,当用户登录以后,其身份和一系列的操作状态都需要被跟踪并保持servletAPI提供了两种可以跟踪客户端状态的方法CookieSession6010.5.1使用CookieCookie是Web效劳器保存在用户硬盘上的一段文本,Web效劳器将它发送到浏览器之后,当再次访问同一网络时,浏览器将它原封不动的返回其中的信息片断以‘名/值’对(name-valuepairs)的形式储存使用这种方法,网站可以维护客户的连接。这种用途可以表达在如下几点在电子商务中标识用户,实现短期跟踪用户记录用户名和用户密码,允许用户下次自动登陆定制站点,记录用户的偏好定向广告,记录用户感兴趣的主题,并显示与之相关的广告10.5客户端跟踪61调用Cookie的构造方法可创立一个cookie构造方法接受两个字符串参数cookie名称cookie的值例如创立一个名为CookieName,值为John的cookie,可以使用下面的语句Cookielogin=newCookie(“CookieName”,”John”);10.5客户端跟踪10.5.1使用Cookie(续)
——创立Cookie对象62创立了一个名为login的cookie之后,可通过很多现有的方法设置cookie的值和属性可通过如下语句设置cookie的注释:login.setComent(“YoucangetUserNameformthiscookie”);创立cookie并将它发送到浏览器后,默认情况下,它是会话级的cookie,仅仅存储在浏览器内存中,用户退出浏览器后,cookie将被删除;如果希望将cookie存储在磁盘上,那么需要设定MaxAge,给出一个以秒为单位的生命周期,如下可以将生命设置为一天login.setMaxAge(60*60*24) //onedaysetPath(),setValue(),setVersion(),setDomain(),setSecure()等,相关的具体用法请查看servletAPI10.5客户端跟踪10.5.1使用Cookie(续)
——设置Cookie属性63刚创立的cookie存在于效劳器内存中。必须将它发送到客户端,cookie才能真正的发挥作用。发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个HTTP响应报头。发送的语句如下publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{Cookielogin=newCookie(“UserName”,”John”);login.setComent(“YoucangetUserNameformthiscookie”);res.addCookie(login);//...}10.5客户端跟踪10.5.1使用Cookie(续)
——发送Cookie到客户端64从客户端读取你感兴趣的cookie,需要两个步骤首先调用request.getCookies得到一个Cookie对象的数组然后调用每个cookie的getName方法,从数组中寻找所需的cookieStringnameString=“UserName”Cookie[]cookies=request.getCookies();for(inti=0;i<cookies.length;i++){ Cookiecookie=cookies[i]; if(nameString.equals(cookie.getName())) { //dosomething…//cookies.setMaxAge(0); }}找到感兴趣的cookie之后,便可以操作此cookie,如通过getValue方法得到相关cookie的值,设置MaxAge等10.5客户端跟踪10.5.1使用Cookie(续)
——从客户端读取Cookie6510.5.2使用SessionSession一段时间内,单个客户与web效劳器的一连串的交互过程在一个Session中客户可能会屡次请求访问同一个网页,也有可能请求访问各种不同的效劳器资源,其间用户的状态需要跟踪并保持存在于效劳器端,不在网络上传送它的好处是可以用来记录客户端私有的信息,并且在时间范围内不会消失10.5客户端跟踪6610.5.2使用Session(续)Session的使用可以分为三个步骤获得一个session存储数据到session或从session读取数据销毁session10.5客户端跟踪67通过调用ServletRequest的getSession方法可以得到一个sessionHttpSessionsession=request.getSession();为了保持正确的会话,必须在发送任何文档到客户程序之前获得一个sessionpublicclassSessionServletextendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{//Gettheuser'ssessionHttpSessionsession=request.getSession(true);//...out=response.getWriter();//...}}10.5客户端跟踪10.5.2使用Session(续)
——获得一个Session68SessionIDServlet容器为HttpSession分配的一个唯一标识符作为Cookie保存在客户的浏览器中sessioncookie每次客户发出HTTP请求时,Servlet容器可以从HttpRequest对象中读取SessionID,然后根据SessionID在效劳器端找到相应的HttpSession对象,从而获取客户的状态信息,这样的cookie叫做sessioncookie存储于浏览器内存中的,并不写到硬盘上的针对某一次会话而言,会话结束也就随着消失了10.5客户端跟踪10.5.2使用Session(续)
——存储或读取数据69URL重写浏览器不支持Cookie,或者将浏览器设置为不接受Cookie的情况,可通过URL重写来实现会话管理向URL连接添加参数,并把sessionID作为值包含在连接中。为servlet响应局部的每个连接添加sessionID,可以使用一对方法response.encodeURL():使URL包含sessionIDresponse.encodeRedirectURL():使用重定向10.5客户端跟踪10.5.2使用Session(续)
——存储或读取数据70从Session中读取数据session.getAttribute(“name”)查找以前存储的值如果不存在那么返回null在调用此方法返回的对象前,一定要检查它是否为null向session中设置相关信息setAttribute替换掉此前设定的任何值removeAttribute移除而不是替换某个值10.5客户端跟踪10.5.2使用Session(续)
——存储或读取数据71publicclassSessionServletextendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{ //Gettheuser'ssessionHttpSessionsession=request.getSession(true);SomeClassscl=(SomeClass)session.getAttribute("name1“);//IftheuserhasnoSomeClassobject,createanewoneif(scl==null){scl=newSomeClass();
session.putAttribute("name1",scl);}//...}}10.5客户端跟踪10.5.2使用Session(续)
——SessionServlet.java72销毁Session意味着从系统删除session对象及其值自动销毁在一段时间〔时间长短依赖与Web效劳器的设定〕没有request的情况下,Web效劳器会自动销毁session手动销毁通过调用session的invalidate方法可以手动的销毁sessionlogout在支持servlet2.4的效劳器中,可调用logout将客户从Web效劳器中注销,同时废弃所有与该用户相关联的会话需要注意的是,这个动作会影响到此servlet之外的其他servlet,因此一定要与网站的其他开发人员协调使用10.5客户端跟踪10.5.2使用Session(续)
——销毁Session7310.6协作与通信协作与通信为了更好的响应客户端的请求,servlet有时需要和网络上的其他资源进行通讯,比方HTML网页其他servletJSP网页Servlet协作通讯的第一步是获得分发器(dispatcher),即RequestDispatcher接口的一个对象74RequestDispatcher接口产生一个RequestDispatcher接口的对象RequestDispatcherdispatcher=getServletContext().getRequestDispatcher("/SomePath/SomeString");通过设置字符串参数,可以获得servlet,HTML网页,JSP网页等“资源”forward方法将本servlet的request请求传递给“其他资源”响应通过利用此方法可实现:servlet先预处理request,然后将处理后的request传递给“其他资源”处理include方法引入“其他资源”来响应客户端的请求10.6协作与通信(续)
——RequestDispatcher接口75MyServlet1获取另外一个servlet〔MyServlet2〕,并用它来响应用户的请求importjava.io.*;importjavax.servlet.*;importjavax.servlet..*;publicclassMyServlet1extendsHttpServlet{publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{res.setContentType("text/html");RequestDispatchersummary=getServletContext().getRequestDispatcher("/servlet/MyServlet2");
10.6协作与通信(续)
——MyServlet1.java76if(summary!=null){ try{summary.include(req,res); } catch(IOExceptione){}catch(ServletExceptione){} } elseif(summary==null){ PrintWriterout=res.getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE>Error</TITLE></HEAD>"); out.println("<BODY>"); out.println("<BIG>SummaryisNull</BIG>"); out.println("</BODY></HTML>");}}}10.6协作与通信(续)
——MyServlet1.java77importjava.io.*;importjavax.servlet.*;importjavax.servlet..*;publicclassMyServlet2extendsHttpServlet{publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{res.setContentType("text/html");PrintWriterout=res.getWriter();out.println("<HTML>");out.println("<HEAD><TITLE>MYsecondServlet</TITLE></HEAD>");out.println("<BODY>");out.println("<tableborder=2><tr><td>name</td><td>Bush</td>");out.println("<td>Sex</td><td>Male</td></tr><tr><td>City</td>");out.println("<td>NewYork</td><td>Country</td><td>U.S.A</td></tr>");out.println("</BODY><HTML>");}}10.6协作与通信(续)
——MyServlet2.java10.6协作与通信(续)
——MyServlet2.java78在IE地址栏输入:://localhost:8084/Chapter11/MyServlet1,结果如下:7910.6.1Applet与Servlet的通信Applet与Servlet的通讯用户用Applet发送消息到效劳器对于动态网页,Applet与Servlet的通讯尤为重要比方在一个聊天系统中,当一个用户输入了某些语句时,聊天室内的所有其他用户都可以看到。此功能可能的实现步骤是用户先把消息发给效劳器然后效劳器发送给聊天室内的所有用户Applet和Servlet通讯的方式有多种通过socket直接建立网络连接通过远程方法调用(RemoteMethodInovation)通讯通过CORBA通讯10.6协作与通信80Socket通讯效劳器端的操作首先创立一个ServerSocket对象,在指定端口监听客户端的request在接收到request后,accept()方法返回一个Socket对象通过socket对象创立输入输出流对象,并实现与客户端的交互交互完毕后,关闭输入输出流和socket,最后关闭ServerSocker客户端的操作首先创立socket对象,建立与效劳器的连接然后通过socket对象创立输入输出流,实现与效劳器的交互最后关闭输入输出流和socket10.6协作与通信10.6.1Applet与Servlet的通信(续)
——Socket通讯81RMI通讯RemoteMethodInvocation的简写,即远程方法调用通过存在于远程机器上的对象,可以发消息给远程的机器,且可以取得远程机器程序执行的结果。整个调用过程类似于此对象存在于本地机器,无疑这大大简化了通讯过程当大量的数据是由效劳器端的对象动态提供时使用RMI通讯是非常适宜的如何使用RMI先定义一个继承自的公用接口。在该接口中定义要求在效劳器上运行的方法接下来是实现远程接口,远程接口的实现类应该实现:定义远程对象的构造方法,创立和安装平安管理器,创立一个或多个远程对象实例,并注册至少一个远程对象10.6协作与通信10.6.1Applet与Servlet的通信(续)
——RMI通讯82通过CORBA通讯即公用对象请求代理体系〔CommonObjectRequestBrokerArchitecture〕,是OMA定义的一套和语言无关的分布式对象交换标准框架(Standardframeworkofobjectinteroperability)CORBA的主要功能是RPC(RemoteProcedureCall)式的支持,它使得本机对象可以调用远端对象的方法使用方法类似于RMI定义接口创立类实现接口在效劳器上注册后客户就可以像本地对象一样访问远程对象了10.6协作与通信10.6
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2022年北京市平谷初三二模英语试卷及答案
- 财税知识专题培训课件
- 喝果汁问题教学设计-2024-2025学年五年级下册数学人教版
- 2025年营养午餐主题班会标准教案
- 古董烟斗购买合同范例
- 农商展期合同范例
- 产品加工转让合同范例
- 产品推广与渠道建设方案计划
- 工作技能培训与考核制度建立计划
- 社区医疗服务的工作安排计划
- 县城生活垃圾填埋场渗滤液两级DTRO处理设备采购及安装项目招投标书范本
- 转炉干法除尘技术介绍
- 北京市乡村振兴协理员面试题目
- 2024年国药集团招聘笔试参考题库含答案解析
- 投标管理制度(合集)
- 10广东省事业单位工作人员年度考核登记表(申报评审卫生版表十)
- 幼儿游戏活动指导第二版全套教学课件
- 南京市城市用地分类和代码标准
- 向下管理高尔夫-完整备注版104张课件
- 护理技术操作考核评分标准患者约束法
- 慢性心功能不全的护理查房
评论
0/150
提交评论