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设置响应 ...
随机推荐
- WEB安全新玩法 [9] 重置密码之验证流程防绕过
一般来说,业务流程中出现多个操作环节时,是需要顺序完成的.程序设计者往往按照正常用户的操作顺序实现功能,而忽略了攻击者能够绕过中途环节,直接在后续环节上进行非法操作.iFlow 业务安全加固平台能够在 ...
- Linux下获取当前程序的绝对路径
在Linux开发应用时,我们常常需要在程序中获取当前程序绝对路径,我们可以通过readlink读取符号链接/proc/self/exe进行获取,这个符号链接代表当前程序,它的源路径就是当前程序的绝对路 ...
- 如何使用SQL Server实现SignalR的横向扩展
一般来说,Web应用的扩展有两种:scale up(纵向扩展)和scale out(横向扩展). 1.纵向扩展 使用配置高(大内存,多处理器)的服务器或者虚拟机. 2.横向扩展 使用多个服务器(Web ...
- php cookie赋值使用
setcookie('username',$user,time()+3600*24); //cookie赋值 public function login(){ //cookie 使用 ...
- 填坑-关于IIC通讯
01.概述 在之前的文章中<STM32IIC详解>中详细讲解了IIC协议,并且使用是NXP的官方手册,demo示例使用IIC读取RTC芯片,运行正常,没有任何问题.并且更新了<II ...
- PS Lite 笔记
本文讲解的 PS Lite 源码版本限定如下: GitHub: https://github.com/dmlc/ps-lite/tree/master Commit: f45e2e78a7430be0 ...
- 记录21.07.26 —— Vue/cil
VUE搭载脚手架 搭载环境 下载node node.js下载地址 控制台输入 npm install -g @vue/cil 查看版本 创建vue项目 创建完后会显示启动服务的指令 这个指令可以在pa ...
- 记录21.07.20 —— js语言回顾
js语言回顾 1.语法 a并没有声明,也可以输出,不会报错. 添加一条语句 则需要声明,称之为严谨语法 2.数组 2.1数组遍历三种方法 for-in与for-of forEach forEach调用 ...
- 工作中后端是如何将API提供出去的?swaggo很不错
工作中后端是如何将API提供出去的?swaggo很不错 咱们上一次简单分享了 GO 权限管理之 Casbin ,他一般指根据系统设置的安全规则或者安全策略 分享了权限管理是什么 Casbin 是什么 ...
- 在包一级定制log4j日志输出
软件开发和维护过程中,日志是必不可少的工具,对于一个10万行规模的产品,要分析它的某一部分,最简单的方法是将log4j配置文件的rootLogger的输出级别设置为debug,但这样将使产品的所有部分 ...