Servlet学习笔记(一)之Servlet原理、初始化、生命周期、结构体系
Servlet是用java语言编写的应用到Web服务器端的扩展技术,与java对象的区别是,Servlet对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器的支持(以下会介绍原因,也可以看之前的一篇介绍Servlet容器的博客,(http://blog.csdn.net/megustas_jjc/article/details/52923132)),在JavaWeb中,Servlet主要用于处理各种业务逻辑,并且还可以输出HTML代码来显示指定页面。
Servlet
用来 动态web资源 开发:
静态web资源 : 固定数据文件
动态web资源 : 通过程序动态生成数据文件
Servlet技术基于Request-Response编程模型 ,HTTP协议也是基于请求响应 模型 ,新航道托福因此 Servlet技术 用来 开发基于HTTP
web 应用程序 。
接触 JavaEE API ------ 程序 接口 和 已经实现接口 类的 使用 (JavaEE ---- Java Platform,
Enterprise Edition 缩写 )
建立一个简单servlet的步骤:
1、创建web project
2、编写 class 继承
HttpServlet
3、在web.xml 配置 Servlet程序 虚拟访问路径 (用户在浏览器上通过这个路径 访问编写Servlet程序
)
4、覆盖doGet或者doPost方法 进行输出
其中,Servlet程序在编写和运行时,需要javaee 类库
(API支持),例如在学习javase List 需要 import java.util.List 需要
jre/lib/rt.jar,对于eclipse需要自行导入jar包,先要找到文件所在的路径,如下。
C:\Tomcat
5.0\common\lib\servlet-api.jar。 然后在eclipse里面 Project ->Properties,在左边找到Java
Builder Path,单击,在右边找到Libraries,然后Add External Jars,找到C:\Tomcat
5.0\common\lib\servlet-api.jar。完毕,接着可以使用 import javax.servlet.*
Servlet运行原理分析
编写Servlet程序没有 main函数(意味着不能独立执行,需要tomcat)
---- tomcat调用Servlet程序执行
1、用户在客户端发起url请求 : http://localhost/day05/hello 。
2、web.xml /hello 映射
HelloServlet程序。
3、用户提交请求时,get方式提交执行HelloServlet的doGet方法,post方式提交执行
HelloServlet的doPost 方法 。
手动编写Servlet运行(servlet在运行时需要依赖外界的jar包)
手动编写Servlet运行(servlet在运行时需要依赖外界的jar包)
1、在webapps
新建 day05test目录 — 虚拟应用
2、在day05test 新建
WEB-INF/classes
3、将编写Servlet的java源码文件 放入 classes ,在 WEB-INF 配置web.xml
(进行虚拟路径配置)
4、编译Servlet的 java程序
javac -classpath
E:\apache-tomcat-6.0.14\lib\servlet-api.jar HelloServlet.java // 通过 -classpath
指定 Servlet需要jar 包
生成Servlet package结构
javac -d . -classpath
E:\apache-tomcat-6.0.14\lib\servlet-api.jar HelloServlet.java
Servlet生命周期与初始化
(1)Servlet生命周期
(2)init(ServletConfig config)
初始化
(3)service(ServletRequest req, ServletResponse res)
提供服务方法
(4)destroy() 销毁
原理:
1、tomcat服务器启动时,没有创建Servlet对象
2、第一次访问时,tomcat构造Servlet对象,调用
init,执行service
3、从第二次以后访问 tomcat 不会从新创建Servlet对象,也不会调用init ----
每一次访问都会调用service
4、当服务器重启或正常关闭时 调用destroy (正常关闭 shutdown.bat)
servlet生命周期小结:
- 针对客户端多次Servlet请求,通常情况下**,服务器只会创建一个Servlet实例对象**,雅思初级也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其他请求服务,直至web容器退出,servlet实例对象才会销毁。
- 在整个Servlet生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求导致Servlet引擎调用一次servlet的service方法,对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
因此,Servlet对象是tomcat创建的,每次请求调用Servlet中service方法,tomcat服务器会在每次调用Servlet的service方法时,为该方法创建Request对象和Response对象(在
JavaEE API 中没有Request和Response实现类(HttpServlet是包装类,因此不能产生Servlet对象) -----
实现类由Servlet服务器提供的,tomcat提供实现类 weblogic 提供实现类 ) 。
service方法 和 HttpServlet doGet/doPost
关系区别
在HttpServlet代码实现中,根据请求方式不同 调用相应doXXX方法 get方式请求 — doGet post方式 —
doPost (必须阅读HttpServlet源代码 )
其中可以通过对Servlet进行配置,使其启动时进行初始化,而不是之前的调用时进行初始化,其实现可以通过<
load-on-startup>(< load-on-startup > 参数可以是一个数字 0-9 代表服务器加载优先级 0 最高
,例如:在tomcat启动时,想通过Servlet加载一些框架配置文件 配置随服务器启动 )
Servlet结构体系
GenericServlet和HttpServlet都是Servlet接口的两个默认实现类,GenericServlet对Servlet接口及ServletConfig接口提供了部分实现,但是并没有对Http请求处理进行实现,这一操作由其子类HttpServlet进行实现,其为Http请求中的POST、GET等类型提供了具体的操作方法,所以通常情况下,编写的Servlet对象都是继承与HttpServlet。因此,编写Servlet
不需要覆盖service方法,只需要覆盖doGet和doPost 方法;Servlet初始化时覆盖init()
,无需覆盖init(config),因为init(Config)
调用了init()。并且,当doGet方法与doPost方法逻辑相同时,可以互相调用,简化编程,例如:
一般Servlet只初始化一次(只有一个实例)。对于更多的客户端请求,Server创建新的请求和响应对象,仍然激活此Servlet的service()方法,将这两个对象作为参数传递给该方法。如此重复以上的循环,但无需再调用init()方法(Web容器收到请求后,Web容器会产生一个新的线程来调用Servlet的service(),service()方法检查HTTP请求类型(GET、POST、PUT、DELETE等),雅思辅导班然后相应调用doGet()、doPost()、doPut()、doDelete()等方法,即用多个线程去执行各个请求)。
原因:
出于性能的考虑:特别的对于门户网站而言,每一个Servlet在每一秒内的并发访问量都可以是成千上万的。在一个面向模块化开发的现在,常常一个点击操作就被定义为一个Servlet的实现,而如果Servlet的每一次被访问,都创建一个新的实例的话,服务器的可用资源消耗量将是一个相当重要的问题。
退一步,一般Servlet的访问是很快的,每一个实例被快速的创建,又被快速的回收,GC的回收速度也跟不上,频繁的内存操作也将可能带来次生的问题。
所以,Servlet的“单一实例化”是一个很重要的策略。
问题描述:
写一个Servlet对象,使用不同的浏览器浏览时,刷新,会出现数据安全问题。由于servlet对象只有一个,其中的属性很容易称为servlet方法执行的临界资源,尽可能不要在Servlet中定义成员变量
解决方法:
在servlet中添加同步代码块
最近在复习web相关的内容,将遇到的问题通过网上一些文章和参考用书进行了一个整理,整理为如下内容:
首先我们先来看如下的一个例子,现在假设有两个jsp页面,jsp1与jsp2:
jsp1页面
jsp2页面:
会发现无法显示test,因为在jsp2页面中找不到test,那么原因是什么呢?
其实那就要从request的生命周期或者是说作用范围说起了,setAttribute()用来在同一个request周期中保存变量使用。
比如servlet调用后,引出JSP页面,这是一个request周期。如果在Jsp页面需要servlet中的一些
处理结构,就从request.getAttribute中获取。
而sendRedirect()方法是通过浏览器重定向的,所以第二个JSP页面中获得的request并非是前一个页面的request(两次请求生成了前后两个不同的
request对象了)。而此时使用RequestDispatcher接口的forward()方法则能够得到request中的对象了,这是因为后者并不是使用客户端浏览器进行重定向的,从函数的名字就可以看出,RequestDispatcher.forward()就是从服务器端进行任务转发。
sendRedirect()是请求从定向,和超连接是一个意思,比如你在A页面中写一个request.setAtribute,sendRedirect到B页面,就是说服务器从A页面中给你一个response,然后你的浏览器再去request到B页面,由于有两次request和response,是不能在B页面取到request.setAtribute里的值,能从地址栏看到url的改变。
request.getRequestDispatcher().forward(request,response)是请求分发器,比如你在A页面中写一个request.setAtribute,request.getRequestDispatcher().forward(request,response)到B页面,那就是说服务器给你的response是B页面的,并且只有一次request和response,所以是能在B页面取到request.setAtribute里的值,地址栏的url仍然是A页面的。
所以通常情况下,setAttribute()方法都和RequestDispatcher.forward()都在一起使用,具体用法示例:
request.setAttribute()和request.getAttribute()配对使用,作用域是请求和被请求页面之间。雅思机经request.setAttribute()是只在此action的下一个forward需要使用的时候使用;request.getAttribute()表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为Object对象类型。其实表单控件中的Object的
name与value是存放在一个哈希表中的,所以在这里给出Object的name会到哈希表中找出对应它的value。setAttribute()的参数是String和Object。
sendRedirect不能传递request对象。使用request.setAttribute时不能使redirect而是forward。即是将请求转发而不是重定向。
request.getParameter()表示接收参数,参数为页面提交的参数。包括:表单提交的参数、URL重写(就是xxx?id=1中的id)传的参数等,因此这个并没有设置参数的方法(没有setParameter()),而且接收参数返回的不是Object,而是String类型。
(1)request.getParameter()取得是通过容器的实现来取得通过类似post,get等方式传入的数据,request.setAttribute()和getAttribute()只是在web容器内部流转,仅仅是请求处理阶段。
(2)request.getParameter()方法传递的数据,会从Web客户端传到Web服务器端,代表HTTP请求数据。request.getParameter()方法返回String类型的数据。
request.setAttribute()和getAttribute()方法传递的数据只会存在于Web容器内部
还有一点就是,HttpServletRequest类有setAttribute()方法,而没有setParameter()方法。
拿一个例子来说一下吧,假如两个WEB页面间为链接关系时,就是说要从1.jsp链接到2.jsp时,出国留学中介被链接的是2.jsp可以通过getParameter()方法来获得请求参数.
假如1.jsp里有
请输入用户姓名:
的话在2.jsp中通过request.getParameter(“username”)方法来获得请求参数username:
<%
String username=request.getParameter(“username”); %>
但是如果两个WEB间为转发关系时,转发目的WEB可以用getAttribute()方法来和转发源WEB共享request范围内的数据,也还是说一个例子吧。
有1.jsp和2.jsp
1.jsp希望向2.jsp传递当前的用户名字,如何传递这一数据呢?先在1.jsp中调用如下setAttribute()方法:
在2.jsp中通过getAttribute()方法获得用户名字:
<% String
username=(String)request.getAttribute(“username”); %>
不同页面间传值使用request.setAttribute(position,
nameOfObj)时,只会从a.jsp到b.jsp一次传递,之后这个request 就会失去它的作用范围,再传就要再设一个
request.setAttribute()。而使用session.setAttribute()会在一个过程中始终保有这个值。
session.setAttribute()和session.getAttribute()配对使用,作用域是整个会话期间,在所有的页面都使用这些数据的时候使用。详细的session相关内容可以参考http://blog.csdn.net/megustas_jjc/article/details/53443012。
Servlet学习笔记(一)之Servlet原理、初始化、生命周期、结构体系的更多相关文章
- 【JSP&Servlet学习笔记】5.Servlet进阶AIP、过滤器与监听器
Servlet接口上,与生命周期及请求服务相关的三个方法是init().service()与destory()方法.当Web容器加载Servlet类并实例化之后,会生成ServletConfig对象并 ...
- Android学习笔记(五)——活动的生命周期
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 为了能写出流畅连贯的程序,我们需要了解一下活动的生命周期. 一.返回栈 Android 中的活动是可以层叠的. ...
- 【React】学习笔记(二)——组件的生命周期、React脚手架使用
原教程视频:ttps://www.bilibili.com/video/BV1wy4y1D7JT?p=2&spm_id_from=pageDriver 目录 一.组件的生命周期 1.1.生命周 ...
- Android学习笔记(六)Fragment的生命周期
在上一篇博文中对Fragment做了简单的介绍,现在再来探讨一下Fragment的生命周期. 一.Fragment的几种状态: 与Activity类似,Fragment也有一下几种状态: · 活动状态 ...
- 张高兴的 Xamarin.Android 学习笔记:(三)活动生命周期
本文将直接解释我写的一个示例.示例目的在于展示 Android 活动在 Xamarin 中的用法.如果有朋友对基础知识不太了解建议先学 Android . 新建一个 Xamarin.Android 项 ...
- Android学习笔记(十) Activity的生命周期
一.如何在一个应用程序中定义多个Activity -定义一个类,继承Activity -复写onCreate() setContentView(R.layout.secondLayout):设定该Ac ...
- Laravel5.1学习笔记9 系统架构1 请求生命周期 (待修)
Request Lifecycle Introduction Lifecycle Overview Focus On Service Providers Introduction When using ...
- Servlet学习笔记(四)
目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...
- # jsp及servlet学习笔记
目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...
- Servlet学习笔记(三)
目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...
随机推荐
- nacos Failed to obtain JDBC Connection 连接异常
在conf/目录下,将application.properties.example 改名为bootstrap.properties 将连接数据库信息添加到末尾 # db mysql spring.da ...
- mysql zip 安装
第一步下载mysql.zip https://dev.mysql.com/downloads/mysql/5.7.html#downloads 第二步:解压文件后在其目录下, 新建 my.ini ...
- Feign远程调用
有关微服务中,服务与服务如何通信,我已经给大家介绍了Ribbon远程调用的相关知识,不知道大家有没有发现Ribbon的问题呢? Ribbon的问题 在Ribbon中,如果我们想要发起一个调用,是这样的 ...
- node溢出
在做项目的过程中,项目越来越大,后面导致项目无法正常启动,查了原因是因为node 溢出了. 先看看溢出时报的错 解决办法: increase-memory-limit插件 1.在package.js ...
- 小白学习Vue第五天(v-model实用的地方)
用法一radio单选项 <!-- 添加name男女选项互斥 --> <label for="male"> <input type="radi ...
- git基本命令-直接上手使用
git基本命令-直接上手使用 此篇为直接是使用git,如果想了解其原理和其他详细信息,请关注我,看其它相关文章 git创建仓库(初始化仓库) 使用当前目录作为仓库 git init // 执行该目录后 ...
- 端口,InetSocketAddress类的使用
端口 端口表示计算机上的一个程序的进程: 不同的进程有不同的端口号!用来区分软件 被规定:0~65535 TCP,UDP:65535*2 单个协议下,端口号不能冲突 端口分类: 公有端口:0~1023 ...
- IOC(概念和原理)
什么是 IOC (1)控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理 (2)使用 IOC 目的:为了耦合度降低 (3)做入门案例就是 IOC 实现 IOC 底层原理 xml 解 ...
- Java自定义注解使用和详解
前言 我们在做开发springboot 项目时候会遇到各种各样注解,使用各种各样注解,极大的简便了我们开发流程,方式,从JDK5开始支持 注解是Java语言的一种强大的功能 可以理解为代码上的特殊标记 ...
- Python语言系列-04-高阶函数
闭包 #!/usr/bin/env python3 # author:Alnk(李成果) # 什么是闭包 # 1,闭包存在于函数中 # 2,闭包就是内层函数对外层函数(非全局变量)的引用 # 3,最内 ...