530 likes | 788 Views
JSP 程序设计. 第 9 章 Servlet 简介. 本章简介. 什么是 Servlet ? Servlet 相对于 CGI 的特性 Servlet 的处理流程和生命周期 HttpServlet HttpServletRequest 和 HttpServletRepsonse ServletContext RequestDispatcher ServletConfig Servlet 对象之间的关系. 什么是 Servlet.
E N D
JSP程序设计 第9章 Servlet简介
本章简介 • 什么是Servlet? • Servlet相对于CGI的特性 • Servlet的处理流程和生命周期 • HttpServlet HttpServletRequest和HttpServletRepsonse • ServletContext RequestDispatcher • ServletConfig • Servlet对象之间的关系
什么是Servlet • Servlet是对支持java的服务器的一般扩充。最常见的用途是扩展Web服务器,提供安全、可移植、易于使用的CGI替代品。它是一种动态加载的模块,并为服务器接收的请求提供服务。 • Servlet还可以看成是服务器端的Applet。它能被Web服务器加载和执行,它接收客户端发送的请求,执行需要的操作,然后返回结果给服务器。
Servlet执行的基本流程 • 客户端通过HTTP发送请求 • 服务器接收该请求发送给Servlet。如果处理请求的Servlet没有被加载,服务器就把它加载到JVM并执行它。 • Servlet接收该HTTP请求并执行某种处理。 • 服务器接收Servlet处理的结果,并将其发送给客户端。
Servlet执行的基本流程 Application Server servlet instance 3. Servlet引擎会调用Servlet的Service方法 Web Server Browser (Client) 2. Server将请求信息发给Servlet 1. Client向 Server发出请求 4. Servlet构建一个响应,并将其传给Server 5. Server将响应返回给Client
Servlet和CGI的对比 • 相似点 -产生动态Web内容 • Servlet替代CGI 在可移植性和平台无关性方面,因为Java Servlet API在Web服务器和Servlet之间定义了一个标准的接口,而且Servlet是用Java编写的,这使得Servlet能够跨平台,和不同的Web服务器交互,几乎所有的主流服务器都能够直接或间接地通过插件支持Servlet。 在持久性和性能方面,一个Servlet只要被Web服务器装载一次,就能够被每一个客户请求调用,这意味着,Servlet能够维护请求之间的系统资源,比如数据库连接,Servlet不会因为每一个请求而产生一个新的多余的实例,然而当CGI每一次被调用的时候,必须产生新的进程,所以Servlet比CGI性能更高。
Servlet的其它特性 • Servlet功能更强大 Servlet可以解析HTML表单数据,读取和设置HTTP头,处理COOKIE,跟踪会话状态等。在Servlet中很多使用CGI程序很难完成的任务都可以轻松地完成,所以Servlet易于编写,功能更强大。 • Servlet可以与其它的系统资源交互 比如它可以调用系统中其它的文件,访问数据库、Applet、Java应用程序等。从而以此产生响应给客户端的动态内容,如果需要的话,还可以保存请求响应过程中的信息,服务器可以完全授权Servlet对本地资源的访问,比如数据库,并且Servlet自身也会控制外部用户的访问数量以及访问性质。
Servlet的其它特性 • Servlet可以是其它服务的客户端程序 比如它们可以用于分布式的应用系统中。可以通过本地硬盘或者是网络从远端激活Servlet。Servlet可以被链接,也就是一个Servlet可以调用一个或一系列Servlet。 • Servlet API与协议无关的 Servlet能够被用于多种协议,比如HTTP、FTP等。主要介绍HttpServlet。
服务器为Servlet提供的服务 一个基于Servlet应用的客户,通常不直接和Servlet通信,而是由Web应用服务器通过Java Servlet API调用Servlet来实现请求服务。Web应用服务器的角色是管理、装载和初始化Servlet、处理服务请求,卸载或撤消Servlet,这通常是由Web应用服务器的Servlet管理服务功能实现的,也就是Web Container。
服务器为Servlet提供的服务 一般来说,在某一时刻,在Web服务器环境中只有一个特定的Servlet对象的实例,当Servlet第一次装进运行环境的时候,Web应用服务器负责实现Servlet实例的初始化,在Servlet整个生命周期内,Servlet保持激活状态或持久状态,每一个客户对这个Servlet的请求是通过在Servlet的初始对象实例上创建一个新的线程来处理的,Web应用服务器负责创建每个应用请求的新线程,另外它还负责卸载或重新安装Servlet。
服务器为Servlet提供的服务 Web应用服务器 Servlet1 的线程2 Servlet1 的线程1 Servlet1 的实例
Java Servlet API • Servlet通过API接口来处理客户的请求,Serlvet API是一组Java类,它定义了Web客户端和Web Servlet之间的标准接口,客户的请求发给Web应用服务器,Web应用服务器通过这组API接口调用请求服务。 • 这组API有两个包组成 -javax.servlet -javax.servlet.http
Java Servlet API javax.servlet.Servlet implement javax.servlet GenericServlet javax.servlet.http.HttpServlet • javax.servlet.Servlet是一个接口类,它是Java Servlet 的抽象类,这个类定义了Servlet必须实现的方法,比如处理请求的Service方法。
Java Servlet API javax.servlet.Servlet implement javax.servlet GenericServlet javax.servlet.http.HttpServlet • GenericServlet类实现了javax.servlet.Servlet这个接口,而且它定义了一个通用的与协议无关的Servlet。 • 为了编写在Web上使用的HttpServlet,使用一个更特殊的类,javax.servlet.http.HttpServlet,它继承了GenericServlet。
Servlet的生命周期 • 生命周期定义了一个Servlet如何被加载和被初始化,它怎样接收请求、响应请求、怎样提供服务。 • Servlet的生命周期从把它装入到Web应用服务器的内存开始到终止或重新装入Servlet的时候结束。 • 生命周期的接口由javax.servlet.Servlet定义 -init() -service() -destroy() 上述方法会在特定的时间安装一定的顺序被调用。
Servlet的生命周期 创建 初始化失败 服务不可用 初始化 销毁 可用服务 卸载 抛出 “unavailable” 异常 请求服务
生命周期中的各API方法(1/3) 1、Servlet的初始化 • 什么情况下初始化servlet -启动服务器时(配置了自动装入选项) -客户机首次向Servlet发出请求时 • 调用init()方法 • init方法的形式是接收一个 ServletConfig对象参数,该参数描述有关Service环境的信息。
生命周期中的各API方法(2/3) 2、Servlet如何处理请求 • 两个重要的参数对象 -HttpServletRequest对象封装客户的请求信息,包括客户的环境信息,和从客户端传到服务器端的任何的数据。 -HttpServletResponse对象封装了动态产生的响应,比如一个返回给客户的HTML页面,该页面通常是由来自HttpServletResponse对象的数据构成的。 • service()、doGet()、doPost()方法
生命周期中的各API方法(3/3) 3、Servlet如何被释放 当Web服务器卸载SERVLET的时候会调用destroy()方法,通常在这个方法中执行一些清除资源的操作,比如释放数据库连接或者是关闭文件。
Servlet示例 pachage simple.servlet; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class FirstSimpleServlet extends HttpServlet{ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException{ response.setContentType("text/html"); PrintWriter out=response.getWriter(); out.println("<HTML><TITLE>First servlet </TITLE><BODY>"); out.println("<H2>This is your first servlet. </H2><HR>"); out.println("</BODY></HTML>"); } }
示例分析-Servlet基本框架 • 自定义Java包 • 三个import语句是访问其它Java包的导入声明 pachage simple.servlet; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; 导入java.io包,在程序当中就可以访问一些标准的java IO操作。javax.servlet和javax.servlet.http的导入是非常重要的,这样才能在程序当中访问Servlet API的一些类和一些接口的方法。
示例分析-Service方法 public class FirstSimpleServlet extends HttpServlet{ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException.IOException{ response.setContentType("text/html"); PrintWriter out=response.getWriter(); out.println("<HTML><TITLE>First servlet </TITLE><BODY>"); out.println("<H2>This is your first servlet. </H2><HR>"); out.println("</BODY></HTML>"); } }
HttpServlet • Javax.servlet.http.HttpServlet支持HTTP协议 • 实现HTTP方法 -doGet()处理GET请求(URL) -doPost()处理POST请求(HTML表单) • service()方法调用doGet()和doPost() • 可能重载init()和destroy()
Requests和Responses Web Server Browser (Client) Application Server servlet instance • service(),doGet()和doPost()方法的参数 -HttpServletRequest提供访问请求信息 -HttpServletResponse动态产生的响应 • 大多数servlet读入一个请求,并产生一个动态的响应
HttpServletRequest • 封装HTTP请求信息 -请求头信息:请求方法、浏览器类 型、正文长度等 -请求servlet的URL路径信息 -客户端安全类型 -参数 • HttpServletRequest类定义了从请求对象中抽取信息的一系列方法
HTTP请求信息 一段HTTP请求信息 POST /Music/SearchServlet HTTP/1.0 Referer:http://www.music.ibm.com/musicSearch.html Connection:Keep-Alive User-Agent:Mozilla/4.72[en](WinNT 5.0; U) Host:localhost:8080 Accept:image/gif,image/x-xbitmap,image/jpeg,*/* Accept-Language:en Accept-Charset:iso-8859-1,*,utf-8 Content-length:50 song_title=Hello&song_artist=Jones&limit_number=20
通过HttpServletRequest获取HTTP信息 • getHeader("headername") 例如:getHeader("Accept-Language") • 请求头:Content-type、Content-length 方法:getContentType()、 getContentLength • 请求头:Cookie 方法:getCookies() • 方法:getMethod()返回请求方法
示 例 private void processRequest(HttpServletRequest request, HttpServletResponse response) { ...... String method=request.getMethod(); if(method.equals("GET")) { //作相应的处理 } String lang=request.getHeader("Accept- Language"); //得到浏览器支持的语言 ...... }
通过HttpServletRequest获取参数 • 名称数值对 • 两种 -跟随在URL地址后的参数数组 -POST提交的参数 • 获取参数的方法 -getParameterNames()返回参数名字 -getParameterValues(String name) -getParameter(String name)
获取参数示例 • <song_title,value_entered> • <song_artist,value_entered> <P>Please fill out this form with the song's name. <FORM METHOD="POST" ACTION="/Music/SearchServlet"> <P>Song Name: <INPUT NAME="song_title" TYPE="TEXT" SIZE="12" MAXLENGTH="20"> <P>Artist Name: <INPUT NAME="song_artist" TYPE="TEXT" SIZE="15" MAXLENGTH="25"> <P>Thank you! <INPUT TYPE="SUBMIT"> <INPUT TYPE="RESET"> </FORM>
获取参数示例 public class SearchServlet extends HttpServlet{ public void doPost(HttpServletRequest req, HttpServletResonse res) throws ServletException,IOException{ ... Enumeration enum=req.getParameterName(); while(enum.hasMoreElements()){ String name=(String)enum.netElement(); String value=req.getParameter(name); //对每个参数作相应操作 } } } String title=req.getParameter("song_title");
HttpServletResponse • HttpServletResponse封装动态产生的响应 • Servlet通过HttpServletResponse把所有的响应信息传递给客户 • 设置content type、状态码 • 设置content Header(cookies,caching) • 响应对象还可以是指向另一个URL的重定向
HttpServletRepsonse的方法 • HTTP响应信息 • setContentType(String type) • getWriter() -PrintWriter对象 • getOutputStream() -ServletOutputStream HTTP/1.1 200 OK Content-Type;text/plain Hello World
HTTP 1.1状态代码及其含义 HTTP 1.1中定义的状态码有以下几种 • 1**表示初始的请求已经接受,客户应当继续发送请求的其余部分 • 2**表示响应成功 - 200 OK • 3**表示重定向 - 301 Moved Permanently • 4**表示客户端错误 - 404 Not Found • 5**表示服务器端错误 - 503 Service Unavailable
HttpServletResponse设置状态码 • HttpServletResponse.setStatus() -参数是一个整数,也就是状态代码 • 为使代码具有更好可读性,用常量替换整数 • 常量根据HTTP 1.1中的标准状态信息命名,加SC前缀 -状态码404对应常量名字为SC_NOT_FOUND • 定制应答时应当在通过PrintWriter发送任何内容之前先调用response.setStatus()。
示例 public class MyServlet extends HttpServlet{ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,IOException{ res.setStatus(HttpServletResponse.SC_OK); res.setContentType("text/html"); PrintWriter out=res.getWriter(); out.println(" <HTML><BODY><H1>Today is " +(new Date())); out.println("</H1></BODY></HTML>"); } }
Servlet示例 package simple.servlet import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import javax.io.IOException; import javax.io.PrintWriter; public class AnotherSimpleServlet extends HttpServlet{ public void doGet(HttpServletRequest request, HttpServletResponse response) throws SERVLETException,IOException{ String browser=request.getHeader("User-Agent"); response.setStatus(HttpServletResponse.SC_OK); response.setContentType("text/html"); PrintWriter out=response.getWriter(); out.println("<HTML><HEAD><TITLE>First servlet</TITLE></HEAD>"); out.println("<BODY>Browse details:"+browser+"</BODY></HTML>"); } }
Web Containers和Servlet Context www.hotel.ibm.com web container /HRApps/Personnel /Rooms /Hire /Retire /Log in /DisplayRooms Servlet Servlet Context /Room Servlet Context /HRApps/Personnel • javax.servlet.ServletContext接口 -定义Servlet的环境对象,多个客户端共 享信息
Request Dispatcher • java.servlet.RequestDispatcher对象实现流控制技术 • forward(转发) -把处理用户请求的控制权转交给其它Web组件 • include(包括) -执行include的组件维持对请求的控制权,只是简单地请求另一个组件的输出包括在本页面的某个特定的地方
forward和include forward Servlet A Servlet B Content returned to Browser include Servlet A Servlet B Content returned to Browser
getRequestDispatcher() • getServletContext() getRequestDispatcher("/pages/ showBalance.jsp").forward(req,res); • getServletContext() getRequestDispatcher("/pages/ navigation.html").include(req,res);
forward()示例 private void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOExcption{ ... if(errorFound){ String errorPage="/ErrorFound.html"; getServletContext(). getRequestDispatcher(errorPage). forward(request,response); return; } }
共享数据 有以下几种方式在Servlet或JSP页面之间 共享数据 • ServletContext -getServletContext().setAttribute ("objectName",anObject); -getServletContext().setAttribute ("objectName"); • HttpServletRequest -request.setAttribute ("objectName",anObject) -request.getAttribute("objectName");
示例 //Servlet "A" private void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,IOException{ Customer cust; ... req.setAttribute("CUSTOMER",cust); String nextServlet="/Internal/ServletB"; getServletContext().getRequestDispatcher(nextServlet). forward(req,res); return; } //Servlet "B" private void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,IOException{ Customer aCust=(Customer)req.getAttribute("CUSTOMER"); ... }
ServletConfig和初始化参数 • javax.servlet.ServletConfig接口 -由于Container配置Servlet -每一个ServletConfig对象对应着一个唯一的Servlet -名称数值对形式 • 相关方法 -getServletConfig() -public String getInitParameter(String name) -public Enumeration getInitParameterNames()
Servlet对象 ServletRequest ServletResponse ServletConfig Thread 1 Client1 Thread 2 ServletContext Client2 Servlet A ServletRequest ServletResponse
Servlet对象 ServletRequest ServletResponse Servlet A Thread 1 ServletConfig Client1 ServletContext Servlet B Thread 2 ServletConfig Client2 ServletRequest ServletResponse
总结 • 什么是Servlet • Servlet相比于CGI的特性 • Servlet的处理流程和生命周期 • HttpServlet -HttpServletRequest和HttpServletResponse • ServletContext -RequestDispatcher • ServletConfig • Servlet对象之间的关系
Servlet程序示例 • 启动Eclipse,创建一个项目。
并在该项目下创建新的HttpServlet类Info,将该类放入test包中。并在该项目下创建新的HttpServlet类Info,将该类放入test包中。