Servlet
来源:互联网 发布:网络溜溜球的意思 编辑:程序博客网 时间:2024/06/04 18:53
突然就想写一篇关于servlet的文章,方便一些初学者进行入门,转载文章请注明出处。
Servlet介绍
一、Servlet简介
Servlet是Server与Applet的缩写,是服务端小程序的意思。是SUN公司提供的一门用于开发动态Web资源的技术。
Servlet本质上也是Java类,但要遵循Servlet规范进行编写,没有main()方法,它的创建、使用、销毁都由Servlet容器进行管理(如Tomcat)。Servlet是和HTTP协议是紧密联系的,其可以处理HTTP协议相关的所有内容。
提供了Servlet功能的服务器,叫做Servlet容器,其常见容器有很多,如Tomcat, Jetty, resin, Oracle
Application server, WebLogic Server, Glassfish, Websphere, JBoss等。
二、servlet的工作原理简介
1、一个HTTP请求的执行过程:
客户端发出请求http://localhost:8080/xxx根据Web.xml文件的配置,找到<url-pattern>对应的<servlet-mapping>读取<servlet-mapping>中<servlet-name>的值找到<servlet-name>对应的<servlet-class>找到该class并加载执行该class
2、Servlet的执行过程
3、Servlet生命周期
void init(ServletConfig config):初始化方法 * 初始化方法 * 执行时机:默认第一次访问的时候 * 执行次数:一次 * 执行者:服务器void service(ServletRequest request,ServletResponse response):服务方法 * 服务方法 * 执行时机:每次访问的时候 * 执行次数:访问一次执行一次 * 执行者:服务器void destroy():销毁方法 * 销毁方法 * 执行时机:servlet被移除的时候或者服务器正常关闭的时候 * 执行次数:一次 * 执行者:服务器 Servlet是单例多线程的,第一次请求来的时候,通过init()来创建servlet,之后调用service()方法根据请求方式的不同调用doXxx的方法,以后每次请求来的话都会调用一次service,当servlet销毁或当服务器关闭时,调用destroy()方法关闭servlet
4、Servlet接口实现类
- SUN公司定义了两个实现类,GenerricServlet和HttpServlet,其中后者是前者的子类,它在原有基础上添加了一些HTTP协议处理方法,它比GenerricServlet功能更强大,所以我们一般将自己的类继承自HttpServlet,并重写doGet方法和doPost方法,不需要重写Service方法。
5、Servlet的一些细节
映射关系:
由于客户端是通过URL地址访问web服务器中的资源,所以servlet必须映射到一个url上,所以要在web.xml上配置映射关系
<servlet> <servlet-name>AnyName</servlet-name><!--自定义的逻辑名--> <servlet-class>HelloServlet</servlet-class><!--Servlet对应类的全类名--> </servlet> <servlet-mapping> <servlet-name>AnyName</servlet-name><!--上面定义的逻辑名--> <url-pattern>/demo/hello.html</url-pattern><!--匹配的URL--> </servlet-mapping>
URL配置细节:
同一个Servlet可以被映射到多个URL上,在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:
格式一:“*.扩展名”。<url-pattern>*.do</url-pattern> 格式二:(/)开头并以(/*)结尾。/action/*
优先级:/* 的优先级高于 *.扩展名 会先匹配
缺省servlet:
如果某个Servlet的映射路径只有一个(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。 凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它们的请求访问都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。 在tomcat的安装目录/conf/web.xml中,注册了一个名称org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet设置为缺省Servlet。 当访问Tomcat服务器中的某个静态HTML文件或图片等资源时,实际上是在访问这个缺省Servlet。
Servlet API和体系结构
- 以TOMCAT为例,/lib/servlet-api.jar文件为Servlet
API的类库文件。如图所示。
Servlet API主要由两个Java包组成:
javax.servlet 和 javax.servlet.http
在javax.servlet包中定义了Servlet接口及相关的通用接口和类;
在javax.servlet.http包中主要定义了与HTTP协议相关的HttpServlet类,HttpServletRequest接口和HttpServletResponse接口;
servlet结构体系简介
1.Servlet接口 (一级接口)
在Servlet接口中定义了5个方法,其中3个方法都是由Servlet容器来调用的,容器会在Servlet的生命周期的不同阶段调用特定的方法:
init(ServletConfig)
负责初始化Servlet对象,容器在创建好Servlet对象后,就会调用该方法;
service(ServletRquest req, ServletResponse res)
负责相应客户的请求,为客户提供相应服务。当容器接受到客户端要求访问特定Servlet对象的请求时,就会调用该Servlet对象的service()方法;
destroy()
负责释放Servlet对象占用的资源。当Servlet对象结束声明周期时,容器会调用此方法;
2.GenericServlet抽象类 (二级类)
GenericServlet抽象类为Servlet接口提供了通用实现,它与任何网络应用层协议无关,GenericServlet除了实现了Servlet接口,还实现了ServletConfig接口和Serializable接口:
GenericServlet类实现了Servlet接口中的init(ServletConfig config)初始化方法。GenericServlet类有一个ServletConfig类型的private成员变量,当Servlet容器调用GenericServlet的init(ServletConfig)方法时,该方法使得私有变量引用由容器传入的ServletConfig对象。GenericServlet类还定义了一个不带参数的init()方法,init(ServletConfig)方法会调用此方法。因此在子类中重写init时,最好重写init()方法,若重写Init(ServletConfig)方法,还需要先调用父类的init(ServletConfig)方法(super.init(config))。
GenericServlet类没有实现Servlet接口中的service()方法。service()方法是GenericServlet类中唯一的抽象方法,GenericServlet类的具体子类必须实现该方法。
GenericServlet类实现了Servlet接口的destroy()方法,但实际什么也没做。
GenericServlet类实现了ServletConfig接口的所有方法。
3. HttpServlet抽象类 (三级类)
HttpServlet类是GenericServlet类的子类。HttpServlet类为Serlvet接口提供了与HTTP协议相关的通用实现,也就是说,HttpServlet对象适合运行在与客户端采用HTTP协议通信的Servlet容器或者Web容器中。
在我们自己开发的Java Web应用中,自定义的Servlet类一般都扩展自HttpServlet类。
HttpServlet类实现了Servlet接口中的service(ServletRequest , ServletResponse)方法,而该方法实际调用的是它的重载方法HttpServlet.service(HttpServletRequest, HttpServletResponse);
在上面的重载service()方法中,首先调用HttpServletRequest类型的参数的getMethod()方法,获得客户端的请求方法,然后根据该请求方式来调用匹配的服务方法;如果为GET方式,则调用doGet()方法,如果为POST方式,则调用doPost()方法。
对于HttpServlet类的具体子类,一般会针对客户端的特定请求方法,覆盖HttpServlet类中的相应的doXXX方法。如果客户端按照GET或POST方式请求访问HttpsServlet,并且这两种方法下,HttpServlet提供相同的服务,那么可以只实现doGet()方法,并且让doPost()方法调用doGet()方法。
4.ServletRequest接口(一级接口)
ServletRequest表示来自客户端的请求;当Servlet容器接收到客户端要求访问特定Servlet的请求时,容器先解析客户端的原始请求数据,把它包装成一个ServletRequest对象。
ServletRequest接口提供了一系列用于读取客户端的请求数据的方法,例如:
• getContentLength()—— 返回请求正文的长度,如果请求正文的长度未知,则返回-1;
• getContentType() —— 获得请求正文的MIME类型,如果请求正文的类型未知,则返回null;
• getInputStream() —— 返回用于读取请求正文的输入流;
• getLocalAddr() —— 返回服务端的IP地址;
• getLocalName() —— 返回服务端的主机名;
• getLocalPort() —— 返回服务端的端口号;
• getParameters() —— 根据给定的请求参数名,返回来自客户请求中的匹配的请求参数值;
• getProtocal() —— 返回客户端与服务器端通信所用的协议名称及版本号;
• getReader() —— 返回用于读取字符串形式的请求正文的BufferReader对象;
• getRemoteAddr() —— 返回客户端的IP地址
• getRemoteHost() —— 返回客户端的主机名
• getRemotePort() —— 返回客户端的端口号
5.HttpServletRequest接口(二级接口)
HttpServletRequest接口是ServletRequest接口的子接口。HttpServletRequest接口提供了用于读取HTTP请求中的相关信息的方法:
• getContextPath() —— 返回客户端请求方法的Web应用的URL入口,例如,如果客户端访问的URL为http://localhost:8080/helloapp/info,那么该方法返回“/helloapp”;
• getCookies() —— 返回HTTP请求中的所有Cookie;
• getHeader(String name) —— 返回HTTP请求头部的特定项;
• getHeaderName() —— 返回一个Enumeration对象,它包含了HTTP请求头部的所有项目名;
• getMethod() —— 返回HTTP请求方式;
• getRequestURL() —— 返回HTTP请求的头部的第一行中的URL;
• getQueryString() —— 返回HTTP请求中的查询字符串,即URL中的“?”后面的内容;
6.ServletResponse接口(一级接口)
Servlet通过ServletResponse对象来生成响应结果。ServletResponse接口定义了一系列与生成响应结果相关的方法,例如:
• setCharacterEncoding() —— 设置相应正文的字符编码。响应正文的默认字符编码为ISO-8859-1;
• setContentLength() —— 设置响应正文的长度;
• setContentType() —— 设置响应正文的MIME类型;
• getCharacterEncoding() —— 获得响应正文的字符编码
• getContentType() —— 获得响应正文的MIME类型
• setBufferSize() —— 设置用于存放响应正文数据的缓冲区的大小
• getBufferSize() —— 获得用于存放响应正文数据的缓冲区的大小;
• reset() —— 清空缓冲区内的正文数据,并且清空响应状态代码及响应头
• resetBuffer() —— 仅仅清空缓冲区的正文数据,不清空响应状态代码及响应头;
• flushBuffer() —— 强制性地把缓冲区内的响应正文数据发送到客户端;
• isCommitted() —— 返回一个boolean类型的值,如果为true,表示缓冲区内的数据已经提交给客户,即数据已经发送到客户端;
• getOutputStream() —— 返回一个ServletOutputStream对象,Servlet用它来输出二进制的正文数据;
• getWriter() —— 返回一个PrinterWriter对象,Servlet用它来输出字符串形式的正文数据;
ServletResponse中响应正文的默认MIME类型是text/plain,即纯文本类型,而HttpServletResponse中响应正文的默认MIME类型为text/html,即HTML文档类型。
为了提高输出数据的效率,ServletOutputStream和PrintWriter首先把数据写到缓冲区内。当缓冲区内的数据被提交给客户后,ServletResponse的isComitted方法返回true。在以下几种情况下,缓冲区内的数据会被提交给客户,即数据被发送到客户端:
• 当缓冲区内的数据已满时,ServletOutPutStream或PrintWriter会自动把缓冲区内的数据发送给客户端,并且清空缓冲区;
• Servlet调用ServletResponse对象的flushBuffer方法;
• Servlet调用ServletOutputStream或PrintWriter对象的flush方法或close方法;
为了确保SerlvetOutputStream或PrintWriter输出的所有数据都会被提交给客户,比较安全的做法是在所有数据都输出完毕后,调用ServletOutputStream或PrintWriter的close()方法(Tomcat中,会自动关闭)。
7.HttpServletResponse接口(二级接口)
HttpServletResponse接口提供了与HTTP协议相关的一些方法,Servlet可通过这些方法来设置HTTP响应头或向客户端写Cookie。
• addHeader() —— 向HTTP响应头中加入一项内容
• sendError() —— 向客户端发送一个代表特定错误的HTTP响应状态代码
• setHeader() —— 设置HTTP响应头中的一项内容,如果在响应头中已经存在这项内容,则原来的设置被覆盖
• setStatus() —— 设置HTTP响应的状态代码
• addCookie() —— 向HTTP响应中加入一个Cookie
在HttpServletResponse接口中定义了一些代表HTTP响应状态代码的静态常量。
8.ServletConfig接口(一级接口)
当Servlet容器初始化一个Servlet对象时,会为这个Servlet对象创建一个ServletConfig对象。在Servlet对象中包含了Servlet的初始化参数信息。
ServletConfig接口中定义了以下方法:
• getInitParameter(String name) —— 返回匹配的初始化参数值
• getInitParameterNames() —— 返回一个Enumeration对象,里面包含了所有的初始化参数名
• getServletContext() —— 返回一个ServletContext对象
• getServletName() —— 返回Servlet的名字,即web.xml文件中相应元素的子元素的值;如果没有为servlet配置子元素,则返回Servlet类的名字
HttpServlet类继承了GenericServlet类,而GenericServlet类实现了ServletConfig接口,因此HttpServlet或GenericServlet类及子类中都可以直接调用ServletConfig接口中的方法。
9.ServletContext接口(一级接口)
ServletContext是Servlet与Servlet容器之间直接通信的接口。Servlet容器在启动一个Web应用时,会为它创建一个ServletContext对象。每个Web应用都有唯一的ServletContext对象,可以把ServletContext对象形象地理解为Web应用的总管家,同一个Web应用中的所有Servlet对象都共享一个ServletContext,Servlet对象可以通过其访问容器中的各种资源。
ServletContext接口提供的方法可以分为以下几种类型:
• 用于在web应用范围内存取共享数据的方法:
o setAttribute(String name, Object object) —— 把一个Java对象与一个属性名绑定,并存入到ServletContext中;
o getAttribute() —— 返回指定属性名的属性值
o getAttributeNames() —— 返回一个Enumeration对象,包含所有存放在ServletContext中的属性名
o removeAttributes() —— 从ServletContext中删除匹配的属性
• 访问当前Web应用的资源:
o getContextPath() —— 返回当前Web应用的URL入口
o getInitParameter() —— 返回Web应用范围内的匹配的初始化参数值。在web.xml中,直接在根元素下定义的元素表示应用范围内的初始化参数
o getServletContextName() —— 返回Web应用的名字,即web.xml文件中元素的值
o getRequestDispatcher() —— 返回一个用于向其他WEB组件转发请求的RequestDispatcher对象
• 访问Servlet容器中的其他WEB应用:
• 访问Servlet容器的相关信息:
• 访问服务器端的文件系统资源:
o getRealPath() —— 根据参数指定的虚拟路径,返回文件系统中的一个真实的路径
o getResources() —— 返回一个映射到参数指定的路径的URL
o getResourceAsStream() —— 返回一个用于读取参数指定的文件的输入流
o getMimeType() —— 返回参数指定的文件MIME类型
• 输出日志:
o log(String msg) —— 向Servlet的日志文件中写日志
o log(String message, Throwable throwable) —— 向Servlet的日志文件中写入错误日志,以及异常的堆栈信息
Servlet相关类的关系
与Servlet主动关联的是三个类,分别是ServletConfig,ServletRequest和ServletResponse。这三个类都是通过容器传递给Servlet的;其中,ServletConfig是在Servlet初始化时传给Servlet的,后两个是在请求到达时调用Servlet传递过来的。
对于Request和Response,以TOMCAT为例,tomcat接到请求首先将会创建org.apache.coyote.Request和org.apache.coyote.Response,这两个类是Tomcat内部使用的描述一次请求和相应的信息类,它们是一个轻量级的类,作用就是在服务器接收到请求后,经过简单解析将这个请求快速分配给后续线程去处理。接下来当交给一个用户线程去处理这个请求时又创建org.apache.catalina.connector.Request和org.apache.catalina.connector.Response对象。这两个对象一直贯穿整个Servlet容器直到要传给Servlet,传给Servlet的是Request和Response的Facade类。
Request和Response的转变过程:
Servlet如何开始工作
当用户从浏览器向服务器发起的一个请求通常会包含如下信息:
hostname和port用来与服务器建立TCP连接,后面的URL用来选择在服务器中哪个子容器服务用户的请求。
在Tomcat7中,这种映射工作由专门的一个类完成:org.apache.tomcat.util.http.mapper,这个类保存了tomcat的Container容器中的所有子容器的信息。org.apache.catalina.connector.Request类在进入Container容器之前,Mapper将会根据这次请求的hostname和contextpath将host和context容器设置到Request的mappingData属性中,所以当Request进入container容器之前,对于它要访问哪个子容器就已经确定了。
对于servlet具体的操作使用,下一回合在述。如果觉得可以,请给小弟留下个赞。
- Servlet
- servlet
- Servlet
- servlet
- Servlet
- servlet
- servlet
- Servlet
- Servlet
- servlet
- Servlet
- servlet
- servlet
- servlet
- Servlet
- servlet
- servlet
- servlet
- POJ
- 据说这个说话的。。。。。。。那啥。
- taskctl自带工具splitexm功能及使用
- SpringMVC 、JSP、Servlet中的相对路径和绝对路径完全手册
- C#打印时带背景颜色
- Servlet
- Mvp简单实现
- Java多线程知识整理
- html入门篇--css优先级
- docker 私服
- Linux环境编程主要头文件分析
- Win10使用附件中的远程桌面连接Ubuntu 16.04图形界面(xrdp方法)
- JAVA date类型处理的一些小知识
- 9-27 DAIRY