软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 编程语言 -> servletapi简介(一) -> 正文阅读

[编程语言]servletapi简介(一)


javax.servlet包中有9个类,如下,其中最后2个是异常类:
  • GenericServlet
  • ServletContextEvent
  • ServletContextAttributeEvent
  • ServletInputStream
  • ServletOutputStream
  • ServletRequestWrapper
  • ServletResponseWrapper
  • ServletException
  • UnavailableException

GenericServlet抽象类可以用于开发独立于协议的servlet,为此我们只需要实现service方法。然后日常编程中,更常见的是使用HttpServlet。
ServletContextEvent和ServletContextAttributeEvent是用于提供ServletContext及其属性的改变情况的事件类。
ServletInputStream和ServletOutputStream为与客户端通信,即发送和读取二进制数据提供了输入、输出流。
包装器类ServletRequestWrapper、ServletResponseWrapper提供了ServletRequest和ServletResponse接口的有用实现。我们可以从它们派生出子类,以增强包装对象的功能。
ServletException是servlet在遇到问题必须放弃时可以抛出的一个通用异常,抛出这个异常表明用户请求、处理请求或者发送响应时出了问题。这个异常抛到了servlet容器中以后,应用程序便失去了处理请求的控制权,容器会接着负责清理这些请求,并向客户返回一个响应。根据容器的实现和配置,容器可能向用户返回一个出错页面。
当一个过滤器或servlet临时或永久性地不可用时,应该抛出UnavailableException,可以应用在servlet请求的资源(数据库、DNS、其他servlet等等)不可用时。

Servlet接口

生命周期方法


所有的servlet必须实现Servlet接口。该接口定义了三个生命周期方法,由servlet容器调用:
  • public void init(ServletConfig config) throws ServletException
  • public void service(ServletRequest  req, ServletResponse res) throws ServletException, IOException
  • public void destroy()

servlet生命周期有着明确定义。客户向Web服务器发出一个请求,服务器再根据需要把请求重定向到servlet容器:
  1. servlet的加载和实例化有servlet容器负责。容器需要找到servlet类,加载并实例化,以供使用。
  2. 容器通过调用init方法来初始化servlet,传入init的参数是一个ServletConfig对象,描述了该servlet的运行环境。
  3. 若servlet没有成功初始化,则抛出UnavailableException或ServletException异常,该servlet会被释放,然后系统会试图实例并初始化一个新的servlet。
  4. 若servlet成功初始化,则表明servlet已经准备完毕,可以处理客户请求。请求和响应信息分别包装在ServletRequest、ServletResponse对象中,它们被传递到service方法中,由service方法负责处理请求并且返回响应信息。
  5. ServletException、UnavailableException异常都可以在请求处理时抛出。若抛出一个异常,则容器必须清理掉该请求,可能要卸载相应的实例并调用destroy方法。
  6. 一旦容器决定删除某个servlet,则必须允许任何service调用结束。之后再调用destroy方法,进而释放相应实例以便垃圾回收。

其他方法


在Servlet接口中还有更多的方法需要由servlet实现:
  • public ServletConfig getSerletConfig(),获取初始化参数。该函数返回的ServletConfig实例中,包含了servlet的初始化和启动参数,这个实例在servlet初始化过程中被传递给init。
  • public String getServletInfo() throws ServletException, IOException,获取关于servlet的信息。该方法返回String对象,包含了关于该servlet的信息,如作者、版本、版权等信息,具体返回哪些内容由开发者决定(默认是空串),Web服务器管理工具可以调用该方法显示servlet的信息。

servlet线程问题


服务器/容器会收到很多请求,这些经常会同时出现,因此容器必须负责为每个请求建立不同的线程。service方法可以由容器在不同线程中调用,来处理各个不同的请求。由于容器是在不同线程中处理请求,所以servlet必须编写为线程安全(thread-safe)代码。为了实现线程安全,我们需要进行适当的管理,如同步锁等;此外,servlet提供了SingleThreadModel接口,但这种实践将导致 Web 容器创建多个 servlet 实例,即为每个用户创建一个实例。对于任何大小的应用程序,这种实践都将导致严重的性能问题【参考2】。 

抽象类GenericServlet


抽象类GenericServlet实现了三个接口,Servlet、ServletConfig、java.io.Serializable【参考3】,对于Servlet接口而言,除了service()方法外,它提供了其他所有内容的具体实现,所以当我们要继承GenericServlet时,必须至少要实现service()方法。也就是说,大多数标准工作可以交给从父类GenericServlet继承而来的方法;如果真的有必要更改默认实现,我们只需重写(override)相应方法。注意,除了Servlet接口中定义的方法外,GenericServlet还定义了其他几个方法。

生命周期方法


  • 初始化方法:public void init(ServletConfig config)、public void init()。有参数的init方法是Servlet接口中方法的实现。当容器调用时,init(ServletConfig)会在servlet中存储ServletConfig对象的一个引用,然后调用无参的init方法。这个无参的init方法是为了方便使用而提供的,省却了 super.init(config) 的调用。
  • public abstract void service(ServletRequest req, ServletResponse res)。这里的service方法是抽象方法,子类必须实现该方法以处理它们的请求。
  • public void destroy()。destroy方法由容器调用,以保证没有数据损失、相关资源得到正确释放。

servlet环境方法


除了getServletConfig、getServletInfo,由于实现了ServletConfig接口,GenericServlet还提供了其他的、继承自ServletConfig接口的、环境有关的方法【参考3】。
  • public ServletContext getServletContext(),可以得到servlet容器的相关信息。
  • public Enumeration getInitParameterNames(),返回servlet初始化参数名字的枚举集合。
  • public String getInitParameter(String name),结合上面的函数,来获取参数的值。
  • public String getServletName(),每个servlet都是通过名字由servlet容器识别的,而通过该方法即可获得该servlet实例的名字。

实用方法


GenericServlet提供了两个日志记录方法,这样servlet就可以向web应用程序的日志文件写入信息:
  • public void log(String msg)
  • public void log(String msg, java.lang.Throwable t)

ServletRequest接口


继承自它的接口有HttpServletRequest,继承自它的类有HttpServletRequestWrapper、ServletRequestWrapper。ServletRequest接口负责包装客户请求,并提供方法使请求信息可供servlet使用,下面按功能对接口的函数进行介绍。

获取请求参数


  • public java.util.Enumeration getParameterNames(),返回该请求中所有参数名字构成的枚举
  • public String getParameter(String name),返回指定参数的值
  • public String[] getParameterValues(String name),与上面方法相似,在参数对应的是多个值(数组形式)的情况下,使用这个方法
  • public java.util.Map getParameterMap(),返回一个Map对象,包含了所有请求参数,其中参数名字作为键,参数值作为值。

访问请求头信息


  • public int getContentLength(),获取请求的大小(在附带一个文件或者其他大型对象时使用),返回以字节为单位的长度值(如果长度未知则返回-1)
  • public String getContentType(),获取请求实体中的数据类型,返回请求的MIME类型(如果未知则返回null)
  • public String getProtocol(),返回发出请求时所使用的协议名字和版本号,如HTTP/1.1

使用属性


属性类似于请求参数,但不是由客户设置,而是由servlet容器设置,或者由此前使用javax.servlet.RequestDispatcher把请求和附加信息作为属性转发给请求的servlet设置。同时,属性值可以是任何Java对象。
  • public java.util.Enumeration getAttributeNames(),返回该请求的属性名组成的Enumeration对象
  • public Object getAttribute(String name),返回指定的属性值(返回的是Object类型,可能需要转型~)
  • public void setAttribute(String name,Object o),存储指定的属性值,一般用在把请求转发到servlet或过滤器进行处理的时候
  • public void removeAttribute(String name),从请求中删除指定属性,一般用在把请求转发到servlet或过滤器进行处理的时候

获取请求路径信息


  • public String getScheme(),返回建立请求的协议,例如http、https或ftp。不同的协议会有不同的构造URL的规则,servlet需要知道相应的方案才能够正确地解释URL。
  • public String getServerName(),返回接收这个请求的服务器名字,也是客户寻址服务器使用的名字。若服务器通过IP地址而不是名字来寻址,则这个方法返回IP地址。
  • public int getServerPort(),返回服务器接收其请求时使用的端口号。不同的协议使用不同的默认端口,服务器可以在任何空闲的合法端口上侦听请求。

检查安全连接


public boolean isSecure(),servlet可通过该方法确定当前处理的请求是否在一个安全的连接上。这个方法尤其适合于过滤器、网关servlet,它们可能被设置为截获请求并且重定向到需要安全连接的资源上。传输敏感信息,如信用卡、密码等数据时需要用到。

国际化处理


有些方法可以帮助我们开发适应于世界不同地区和字符集的程序。客户所发送的请求中包含了相关信息,这些信息表明它愿意使用什么地区设置来接收响应。提供一些列的地区是很有必要的,若servlet不支持首选设置,可能会支持其次的设置,如此尽可能地满足用户要求。如果客户没有指定地区设置,那么这些方法返回服务器的默认地区设置。
  • public java.util.Locale getLocale(),返回首选地区设置
  • public java.util.Enumeration getLocales(),返回一组地区,这些按照优先性由高到低排列

编码问题也是处理请求中需要考虑的:
  • public String getCharacterEncoding(),返回在请求中使用的字符编码名字(若没有指定则返回null)
  • public void setCharacterEncoding(String env) throws java.io.UnsupportedEncodingException,替代在请求中使用的字符编码,必须在使用getReader或getInputStream方法读取请求参数或者读取输入之前调用它。默认的编码方式是ISO-8859-1。

从请求中读取流


Servlet API为请求输入流和响应输出流提供了两个IO流包装类。
  • public ServletInputStream getInputStream() throws java.io.IOException,使用这个方法从请求中读入一个文件或序列化对象,可把返回的对象包装在有效的输入类中,如ObjectInputStream,以读入数据
  • public java.io.BufferedReader getReader() throws java.io.IOException,使用这个方法读入字符数据,可把返回的对象包装在一个适当的输入类中,如FileReader,来读取数据

注意,我们只能调用两者中的一个。如果调用了一个后,再尝试调用另一个,则会抛出IllegalStateException异常,表明已经调用了其他方法读取数据。

获取客户信息


  • public java.lang.String getRemoteAddr(),返回客户的IP地址
  • public java.lang.String getRemoteHost(),返回客户的完整名字

生成RequestDispatcher


servlet通过使用RequestDispatcher对象,把请求转发给指定资源或者在响应中包含该资源。这个资源可以是动态或静态的。
  • public RequestDispatcher getRequestDispatcher(String path),返回RequestDispatcher对象,该对象包装这path参数中指定的资源,该资源可以是另一个servlet或者静态资源(如HTML文件)

ServletResponse接口


ServletResponse对象用于把servlet的响应回送给客户。它把相应信息包装在一个接口中【参考4】。

设置内容长度和MIME类型


  • public void setContentLength(int len),设置响应头,用于指定响应信息的长度
  • public void setContentType(java.lang.String type),用于设置MIME类型,这个方法应该在输出流对象写任何输出信息之前调用。对于标准的网页,使用“text/html”,对于串行化的Java对象,使用“application/x-java-serialized-object”

国际化处理


针对特殊用户定制响应信息,包括地区设置和字符集设置。
  • public java.util.Locale getLocale(),访问地区信息
  • public void setLocale(java.util.Locale loc),重新设置响应信息的地区信息,必须在getWriter之前调用
  • public java.lang.String getCharacterEncoding(),返回响应信息中MIME实体使用的字符集类型,默认是ISO-8859-1
  • public void setCharacterEncoding(java.lang.String charset),设置MIME的字符集类型

在响应中返回数据


为了在响应中返回信息,需要从Response对象中访问输出对象,可以通过调用下列方法之一来实现:
  • public ServletOutputStream getOutputStream() throws java.io.IOException,返回的ServletOutputStream对象直接用于或包装在一个IO对象中,以输出一个响应。
  • public java.io.PrintWriter getWriter() throws java.io.IOException,返回PrintWriter对象,向客户回送文本信息。

注意,只能调用上述中的一个方法。因此需要决定将向客户回送什么类型的数据,对于字符数据要使用getWriter,对于混合类型(如序列化对象、文件等),要使用getOutputStream并且把返回的对象包装在适当类中以完成数据回送。

输出缓冲存储


不同servlet容器的缓冲存储策略各不相同,容器对此并没有做什么要求。有许多方法可供servlet使用以改善输出缓冲存储策略。
  • public int getBufferSize(),返回使用的基层缓冲存储区的大小
  • public void setBufferSize(int size),允许servlet向容器建议一个缓冲区大小,容器要实现的缓冲区大小至少为这个值,必须在向客户返回任何内容之前调用该方法
  • public boolean isCommitted(),可以供servlet确定响应信息是否已经开始开始被传送到客户
  • public void reset(),如果响应信息还没有被提交,reset方法将清除缓冲区中的所有数据(包括数据、响应头、状态码) ;如果响应信息已经被提交,将抛出IllegalStateException异常
  • public void resetBuffer(),与reset类似,resetBuffer讲复位缓冲区中的数据(但不包括响应头、状态码),且若响应信息已提交,将抛出IllegalStateException异常
  • public void flushBuffer() throws java.io.IOException,立即把缓冲区中的内容发送给客户。一旦一个缓冲区满了,容器会立即把它的内容传送给客户,也就提交了响应信息。

每个容器请求都在改变缓冲区大小,会产生一种累积效果。对于传入的新的值,容器会决定保持较大的缓冲区大小。如果把缓冲区增加的太大(快抛出异常了),就必须把缓冲区大小重新设置为一个有意义的值,如1024(通过用新值重新编译,或者重新启动服务器),然后才能继续使用这个servlet。
参考
1 《Java Servlet编程指南》
2 http://www.ibm.com/developerworks/cn/websphere/library/bestpractices/do_not_implement_single_thread_model_in_servlets.html
3 http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/GenericServlet.html
4 http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletResponse.html
......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-04-04 00:13:46  
编程语言 最新文章
Java面试题(1)
ReactiveX序列——RxSwift
C++STL之ACM相关知识大全
c++中vector向量几种情况的总结(向量指针,
SSH框架整合demo
JAX
UVA
curl备忘(1)
C#机房重构——万事开头难(二)
OJ刷题
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2017年12日历
2017-12-15 21:45:24
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --