servlet基础
作用:servlet是运行在Web服务器或应用服务器上的程序;担当web浏览器或其他HTTP客户程序发出的请求与HTTP服务器上的数据库或应用程序之间的中间层。
1、读取客户程序发送的显式数据
2、读取浏览器发出的隐式HTTP请求数据
HTTP信息包括cookie、媒体信息和浏览器能够识别的压缩模式
3、生成结果
可能与数据库对方,调用web服务或者直接计算得到响应
4、向客户发送显式数据(即文档)
这种文档可以用各种不同的形式发送,包括文本、二进制、exce,甚至是其他压缩格式
5、发送隐式的HTTP响应数据
发送到用户的数据有两种:文档本身、以及后台的HTTP信息。两种类型的数据对开发工作都至关重要。发送HTTP响应数据时,需要告知浏览器或其他客户程序返回文档的类型(如HTML)、设置cookie并缓存参数、以及其他类似任务。
servlet的基本结构:
servlet一般扩展HttpServlet,并依据数据发送方式的不同(GET或POST),覆盖doGet或doPost方法。如果希望servlet对GET和POST请求采取同样的行动,只需要让doGet调用doPost,反之亦然。
doGet和doPost接受两个参数:HttpServletRequest和HttpServletResponse

生成HTML的servlet
大多数servlet生成HTML,而并非前面例子中的纯文本。要生成HTML,需要在刚才介绍的过程中加入下面3步:
1、告知浏览器,即将向他发送HTML
使用HTTP Content-Type响应报头设置为text/html来完成
必须在传送实际的文档之前设定内容的类型
2、修改println语句,构建合法的Web页面
3、验证生成的HTML语法

servlet的生命周期:
服务器只创建每个servlet的单一实例,每个用户请求都会引发新的线程。现在,更加详细的介绍servlet的创建和销毁方式,以及调用各种方法的方式和时间。
首次创建servlet时,它的init方法会得到调用。在这之后,针对每个用户请求,都会创建一个线程,该线程调用前面创建的实例的service方法。多个并发请求一般会导致多个线程共同调用service(尽管可以实现特殊的接口SingleThreadModel——规定任何时间只允许单个线程运行)。之后,由service方法依据收到的Http请求类型,调用对应的doGet等方法。最后,如果服务器决定卸载某个servlet,它会首先调用servlet的destory方法。

service方法:
服务器每次接受到对servlet的请求,都会产生一个新的线程,调用service方法。service方法检查HTTP请求的类型并相应地调用doGet等方法。
如果您需要在servlet中等同的处理POST和GET请求,您可能会倾向于不去实现doGet和doPost方法,而是直接覆盖service方法。这不是一个好思想。取而代之,只需让doGet调用doPost(或相反)即可。
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
//Servlet code
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
虽然这种方式要多出几行代码,但相对于直接覆盖service,它有好几项优点。首先,之后您还可以加入doPut,doTrace等,支持其他HTTP请求方法。其次,您还可以通过添加getLastModified方法,加入对修改日期的支持。由于getLastModified由默认的service方法调用,所以覆盖service方法也失去了这个选项。
doGet、doPost、doXX方法:
这些方法才是servlet的主体
init方法:
大多时候,您的servlet只需要处理单个请求的数据,doGet或doPost是成名周期中唯一需要的方法。然而,有时候您希望在servlet首次载入的时候执行复杂的初始化任务,并且不想每个请求都重复这些任务。init方法就专门为这种情况设计,它在servlet初次创建时被调用,之后处理每个用户的请求时,则不再调用这个方法。
servlet一般在用户首次调用对应servlet的URL时创建,也可以制定和servlet在服务器启动后载入。
init方法的定义:
public void init() throws ServletException {
//Initialization code...
}
init方法执行两种类型的初始化:常规初始化,以及由初始化参数控制的初始化。
常规初始化:
第一种类型的初始化中,init只是创建或载入在servlet生命周期内用到的一些数据,或者执行某些一次性的计算。
getLastModified方法为HttpServlet的方法,如果服务器接受到条件get请求(制定客户只想要那些自特定日期依赖发生的页面),系统会将指定的日期与getLastModified返回的日期进行比较,只返回那写在指定的日期之后发生发生改变的页面。
/**
* The standard service method compares this date against any date specified in the If-Modified-Since request header.
* If the getLastModified date is later or if there is no
* If-Modified-Since header, the doGet method is called
* normally. But if the getLastModified date is the same or earlier, the service method sends back a 304 (Not Modified)
* response and does not call doGet. The browser should use it cached version of the page in such a case.
* @param req
* @return
*/
由初始化参数控制的初始化:
要理解init参数的动机,您需要了解什么样的人可能希望对servlet的行为进行定制。它们主要可以分为3组:
1、开发人员
2、最终用户
3、部署人员
开发人员改变代码改变servlet行为
用户表单提交数据改变servlet行为
部署人员怎么办?init参数就是为了使管理员无需修改servlet的源代码就可以将servlet在机器间移动以及改变特定的参数。

1、web.xml中的servlet元素可以为servlet赋予名称
2、web.xml中的servlet为servlet指定一个定制URL
3、web.xml的servlet元素添加init-param子元素,可以指定初始化参数的名称和值
4、servlet的init方法中,调用getServletConfig获取servletConfig对象的引用
5、以init参数的名称为参数,调用ServletConfig的getInitParameter方法
destory方法:
服务器在移除servlet的实例前,会调用servlet的destory方法,可以使得servlet有机会关闭数据库连接等活动。但要注意web服务器有可能崩溃,因此不要将destory机制作为向磁盘上保存状态的唯一机制。
SignleThreadModel接口:
通常,系统只生成servlet的单一实例,之后为每个用户请求创建新的线程。所以doGet和doPost方法必须小心地同步对字段和其他共享数据访问。注意,多个线程并不共享局部变量,因此不需要特别的保护。
实现SignleThreadModel接口,系统会保证不会有多个请求线程同时访问该servlet的单个实例。使用了队列。但是服务器也可以创建由多个实例组成的池,同一时间每个实例都能够处理请求。然而,您依旧必须同步对类变量或存储在servlet之外的共享数据的访问。
SignleThreadModel尽管能阻止并发访问,但是实际上是不好的选择,原因:
1、同步对servlet的性能造成极大等待。应该考虑只同步操作共享数据那部分代码。
2、SingleThreadModel规范允许服务器使用多个实例来处理请求来替代对单个实例的请求进行排队的方案。只要每个实例同一时间只处理一个请求,实例共享的方式就满足规范的要求。但这不是一个好方案。
原因:
1、加入使用非静态存储共享数据。SingleThreadModel会阻止并发的访问,相当于把孩子和洗澡水同时泼掉了;每个servlet实例都拥有实例变量的单独副本,因此数据也不能正确共享。
2、加入使用静态共享数据。SingleThreadModel的共享池方式没有优点,多个请求仍然会并发访问静态数据。

例子:
String id = "User-ID-" + nextID;
out.println("<H2>" + id + "</H2>");
nextID = nextID + 1;
并发可能出问题。

解决方案:
1、减少竞争
修改为:String id = "User-ID-" + nextID++;
降低了并发问题的可能性,但是没有消除。和怒道情况下,降低错误出现的可能性是一件坏事而不是一件好事。
2、使用SingleThreadModel
前面说过坏处。
3、明确同步
synchronized(this) {
String id = "User-ID-" + nextID;
out.println("<H2>" + id + "</H2>");
nextID = nextID + 1;
}
servlet的调试:
1、println语句。
2、debug
3、日志
4、单元测试
5、检查源码
6、检查请求
7、检查响应
8、重启服务

servlet基础(组成与生命周期)的更多相关文章

  1. JavaEE Servlet 核心方法及生命周期

    做JavaWeb开发,免不了要和Servlet打交道.Servlet是Sun(Oracle)官方定义的一个Web开发规范,所有Servlet开发都必须遵守.自己以前也没有从头做过Web开发,所以这方面 ...

  2. JavaWeb之 Servlet执行过程 与 生命周期

    Servlet的概念 什么是Servlet呢? Java中有一个叫Servlet的接口,如果一个普通的类实现了这个接口,这个类就是一个Servlet.Servlet下有一个实现类叫HttpServle ...

  3. HTTP协议 Servlet入门 Servlet工作原理和生命周期 Servlet细节 ServletConfig对象

    1 HTTP协议特点   1)客户端->服务端(请求request)有三部份     a)请求行--请求行用于描述客户端的请求方式.请求的资源名称,以及使用的HTTP协议版本号 请求行中的GET ...

  4. [转]JavaWeb之 Servlet执行过程 与 生命周期

    https://www.cnblogs.com/vmax-tam/p/4122105.html Servlet的概念 什么是Servlet呢? Java中有一个叫Servlet的接口,如果一个普通的类 ...

  5. 【servlet】Servlet的API和生命周期]

    创建时间:6.15 一.Servlet的API(生命周期) (1)Servlet接口中的方法 1)init(ServletConfig config) 何时执行:servlet对象创建的时候执行 Se ...

  6. JavaEE基础(01):Servlet实现方式,生命周期执行过程

    本文源码:GitHub·点这里 || GitEE·点这里 一.Servlet简介 Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容.使用S ...

  7. JavaEE基础(01):Servlet实现方式,生命周期执行...

    一.Servlet简介Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容.使用Servlet,可以收集来自网页表单的用户输入,呈现来自数据库 ...

  8. Servlet执行流程和生命周期【慕课网搬】

    Servlet执行流程(GET方式为例) 首先用户客户端浏览器发出Get方式(点击超链接方式)向浏览器发出请求. 服务器接收到客户端点击超链接,接收到GET请求之后,服务器到WEB.xml中<s ...

  9. servlet 和filter 的生命周期说明

    servlet : 当客户端第一次访问servlet的时候,服务器就会创建servlet实例,servlet 就会执行init方法,每次请求,服务器会开一个新的线程访问servlet中得service ...

  10. [03] Servlet继承关系和生命周期

    1.Servlet的继承关系 假如现有我们自定义的一个Servlet,继承HttpServlet,那么实际上它的继承链如下图:   可以看到,核心的部分在于: 两个顶级接口 Servlet Servl ...

随机推荐

  1. 伪类:after的使用以及结合attr来添加属性的技巧

    本案例以实现侧边栏的效果为例来说明 直接上代码看效果: css <style type="text/css"> *{;;list-style: none;} ul{;t ...

  2. Robot framework(RF)学习基础

    1.框架特点 2.安装 3.基本内容 RF框架是通用的测试框架,一直由诺西网络维护. 易于使用 采用表格法 可以使用关键字驱动,数据驱动和行为驱动开发完成.(keyword-driven,data-d ...

  3. 【BZOJ】[HNOI2015]菜肴制作

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4010 要是考场上想不出,但是还是有一个分治的做法的嘛 做法就是反向连边,然后再反向输出字典 ...

  4. AttributeError: 'Request' object has no attribute 'json', cherrypy 无法接收到json字符串,解决方法

    @cherrypy.expose @cherrypy.tools.accept(media="application/json")   #加入这个装饰器 @cherrypy.too ...

  5. c++ 满足条件拷贝,容器扩容(copy_if)

    #include <iostream> // cout #include <algorithm> // copy_if, distance #include <vecto ...

  6. MongoDB(课时27 消除重复数据)

    3.7.2 消除重复数据 在SQL中对于重复的数据可以使用"DISTINCT"消除,在MongoDB中依然支持.(distinct不同的) 范例:查询所有name的信息 本次的操作 ...

  7. springboot全局配置文件可设置的属性

    # =================================================================== # COMMON SPRING BOOT PROPERTIE ...

  8. JQuery.Ajax()的data参数传递方式

    最近,新学c# mvc,通过ajax post方式传递数据到controller.刚开始传递参数,controller中总是为null.现记录一下,可能不全,纯粹记个学习日记. 重点在于参数的方式,代 ...

  9. poj1651 Multiplication Puzzle

    比较特别的区间dp.小的区间转移大的区间时,也要枚举断点.不过和普通的区间dp比,断点有特殊意义.表示断点是区间最后取走的点.而且一个区间表示两端都不取走时中间取走的最小花费. #include &l ...

  10. Mysql批量导入约束报错

    SET foreign_key_checks = 0;   禁用外键,在文件顶部加 SOURCE dump_file_name;      进行SQL执行 SET foreign_key_checks ...