文章目录
Servlet对象
Servlet的本质是什么?
Servlet是服务器端的小java程序,这个小java程序不能随意编写,必须实现SUN制定的javax.servlet.Servlet接口,实现其中的方法。Servlet是一个满足java规范的java类。Servlet既然满足Servlet规范,Tomcat服务器我们可以叫做“WEB容器(Container)”,那么Servlet 就可以叫做容器中的“组件(Component)”
Servlet对象的生命周期是什么样的,什么时候创建,创建几次,什么时候销毁?
假设客户端向web服务器发送的请求是/login请求,当用户向web服务器第一次发送/login请求的时候,Tomcat在容器中搜索/login对象的Servlet对象,但是没有找到该对象,此时会从web.xml文件中获取/login对象的完整Servlet类名,通过反射机制,调用Servlet的无参数构造方法创建Servlet对象,马上调用init方法完成Servlet对象的初始化操作,然后调用service方法提供核心服务。
当用户第2+次再发送/login请求的时候,Tomcat还是在容器中搜索/login对象的Servlet对象,此时可以找到该对象,直接调用该对象的service方法提供核心服务。
当用户长时间没有访问该Servlet,或者服务器关闭,或者项目重新部署的时候,Tomcat容器会去回收Servlet对象所占用的内存,在回收该内存之前调用该Servlet对象的destroy方法,完成回收之前的准备。
结论:
Servlet对象只创建一次(构造函数只执行一次)
Servlet对象的init方法在对象创建之后马上执行(只执行一次完成初始化操作)
Servlet对象service方法,只要用户访问一次则执行一次。
Servlet对象的destroy方法,也是只执行一次,执行之前对象没有销毁,即将销毁。
Servlet对象的生命周期由Tomcat容器管理,对象的创建,对象内存的释放,还有对象中的方法调用都是由Tomcat容器完成,程序员不能干涉,只能编写该类实现Servlet接口,将其配置在web.xml文件中。
Servlet对象是单实例的,并且是在多线程的环境下运行,可能存在线程并发带来的安全问题。
什么情况下在init方法中编写程序?什么情况下在service方法中编写程序?什么情况下在destroy方法中编写程序?
- init方法是SUN规范中为程序员提供的一个对象初始化时机,这是一个特定的时刻,有的时候我们需要在这个特定的时刻执行一段特定的程序,此时将该程序写入init方法,例如:项目经理要求在Servlet对象创建时刻记录日志,请将该程序编写到init方法中。对象第一次创建的时候执行记录日志,并且只执行一次,记录一次日志信息。(init方法一般很少用)
- Service方法是Servlet的核心业务方法,核心业务都在该方法中完成,只要编写一个Servlet,service方法是一定要编写代码的,完成业务的处理。(常用)
- destroy方法init方法相同,只不过是一个不同的时机。(destroy方法一般很少使用)
研究Servlet对象的生命周期
1、在myeclipse中设置文件的默认打开方式:
Window–>Preferences–>file associations–>找到对应扩展名选项–>设置默认打开方式default
2、什么是Servlet生命周期?
Servlet对象的生命周期表示:Servlet对象从最初的创建,到最终的销毁,经历了哪些不同的过程。
3、Servlet对象的创建,Servlet对象的方法被调用,Servlet对象的销毁,都是由WEB容器来负责管理的,
javaweb程序员是不需要管理这些的。
javaweb程序员主要负责:
Servlet类的编写,
service方法的实现,
Servlet类在web.xml文件中的配置。
4、myeclipse快捷键:
alt + / 自动补全
ctrl + 1 纠错
ctrl + o 查看类的属性和方法
ctrl + shift + t 查找类
ctrl + shift + o 组织导入
ctrl + / 注释和取消注释
tab 缩进
shift + tab 取消缩进
ctrl + shift + f 格式化【不建议使用】
ctrl + alt + 向下箭头 复制一行
ctrl + z 撤销
ctrl + y 重做
ctrl + s 时刻记住这个“保存”
ctrl + c
ctrl + x
ctrl + v
ctrl + d 删除光标所在行
5、web.xml文件在服务器启动阶段被解析,若web.xml文件编写有错误,启动Tomcat服务器的时候,当前webapp启动失败。
6、Servlet对象“默认情况”下,在服务器启动阶段是不会实例化的。不会创建对象
7、Servlet对象的生命周期
1) 用户打开浏览器在浏览器地址栏上输入URL:http://localhost:8080/oa/save,回车
2) WEB服务器截取请求路径,得知用户要访问的资源是:/oa/save
3) WEB服务器从整个容器中检索/oa/save请求路径对应的Servlet对象
4) 若找到了该Servlet对象
4-1) web容器负责调用该Servlet对象的service方法提供服务,处理请求
5) 若没有找到该Servlet对象
5-1) 通过请求路径/save找到对应的Servlet完整类名(web.xml文件支持的,web.xml文件在服务器启动阶段解析,路径和类名已经绑定在一起了)
5-2) 通过反射机制调用Servlet类的无参数构造方法完成Servlet对象的实例化操作。(Servlet对象已经创建完毕)
5-3) web容器调用该Servlet对象的init方法完成初始化操作。
5-4) web容器调用该Servlet对象的service方法提供服务,处理请求
6) 若“服务器关闭”或“webapp重新部署”或“长时间没有用户再访问该Servlet”,WEB容器
会销毁该Servlet对象占用的内存空间,web容器在销毁该Servlet对象之前,web容器负责
调用该Servlet对象的destroy方法,完成销毁之前的准备工作。
8、Servlet对象是单实例的,不符合单例模式,是一种伪单例,真单例的构造方法必须是私有化的。
Servlet对象是在多线程环境下运行的一个对象。【单实例多线程环境下运行的一个java对象】
之所以Servlet对象是单实例的,是因为该对象的创建是由WEB容器负责的,javaweb程序员不能干涉
9、单例分类:
真单例
伪单例
10、总结:
1) 无参数构造方法只调用一次,对象只创建一个,对象是单例的
2) init方法只被调用一次,在对象创建之后马上执行它,完成初始化操作
3) service方法,只要用户发送请求一次,则执行一次
4) destroy方法也是只执行一次
注意:
init方法在执行的时候,对象已经存在了。
destroy方法在执行的时候,对象还没有被回收,还存在。
11、分析Servlet中重要的三个方法:
init
service
destroy
问题:你觉得哪个方法使用最多?
service方法,因为在这个方法中需要提供服务,处理当前的请求,这是核心方法,用户访问的每一次都是要执行的。
问题:你觉得init方法和destroy,SUN公司为什么在Servlet接口中设计这两个方法,这两个方法什么时候使用?
其实init、destroy方法都是SUN公司为javaweb程序员准备的特殊的时刻,初始化时刻/销毁时刻
一般这两个方法中是不需要编写任何代码的,但是在特殊的情况下,例如:需求要求在对象被初始化
的那一刻记录日志,那么记录日志的代码就编写到init方法中,例如:需求要求在该Servlet对象
被销毁的那一刻记录日志,那么记录日志的代码就需要编写到destroy方法。自然会被服务器调用
并执行。
12、重点:
在Servlet类中最好不要手动编写任何构造函数,这样做可能会导致无参数构造函数不存在,
这样通过反射机制创建对象的时候,会出现实例化异常。Servlet对象创建失败。
13、错误代号:【HTTP状态号】
404 - 资源找不到,通常是路径问题,还有可能是项目本身启动失败
500 - 服务器内部错误,通常是服务器中的java程序出现了异常。
…
研究服务器启动阶段怎么实例化Servlet对象呢?
在web.xml文件的标签内部添加:1
该标签表示在服务器启动阶段加载Servlet,完成实例化和初始化。
数字越小,优先级越高。
关于一个web站点的欢迎页面的设置
1、设置欢迎页面的作用:
在访问该web站点的时候,没有提供任何资源路径,直接访问的是该web站点的欢迎页面
若欢迎页面没有进行相关的设置,会出现404
例如:访问 http://localhost:8080/prj-servlet-04/
直接跳转到欢迎页面,但是没有设置欢迎页面的时候,出现404错误
2、当修改web.xml文件的时候,保存之后,Tomcat服务器会自动重新解析web.xml文件,
这个时候,就相当于项目重新部署了。
2、怎么设置欢迎页面?
修改web.xml文件:
<welcome-file-list>
<welcome-file>login.html</welcome-file>
<welcome-file>save.html</welcome-file>
<welcome-file>welcome.html</welcome-file>
<welcome-file>html/welcome.html</welcome-file>
</welcome-file-list>
注意:
欢迎页面可以设置多个,第一个优先级最高,以此类推
欢迎页面路径问题:不需要以“/”开始,但是从WebRoot作为起点
3、欢迎页面必须是一个HTML吗?可以是Servlet吗?
欢迎页面也可以是一个Servlet
例如:
<servlet>
<servlet-name>deleteServlet</servlet-name>
<servlet-class>com.bjpowernode.javaweb.servlet.DeleteServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>deleteServlet</servlet-name>
<url-pattern>/user/delete</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>user/delete</welcome-file>
</welcome-file-list>
4、当前web站点没有设置任何欢迎页面的话,欢迎页面是:index.html、index.htm、index.jsp
这是怎么回事?
是因为在CATALINA_HOME/conf/web.xml文件中有全局配置:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
在当前webapp中配置的欢迎页面属于局部配置,局部优先(就近原则)
ServletConfig对象详解
l javax.servlet.ServletConfig是SUN制定的接口,apache对ServletConfig接口的实现类的完整类名是:org.apache.catalina.core.StandardWrapperFacade,但是作为程序员不需要关心具体的类型,只要面向javax.servlet.ServletConfig接口调用即可,程序运行阶段执行的是apache的ServletConfig的实现类中的方法。
l Servlet****对象的创建以及方法的调用过程
Class c = Class.forName("com.bjpowernode.javaweb.servlet.ServletConfigTest");
Servlet servlet = (Servlet)c.newInstance();
ServletConfig config = new org.apache.catalina.core.StandardWrapperFacade();
servlet.init(config);
ServletRequest request = 创建了apache的一个request对象;
ServletResponse response = 创建了apache的一个response对象;
servlet.service(request,response);
servlet.service(request,response);
servlet.service(request,response);
servlet.service(request,response);
………………
servlet.destroy();…
Servlet和ServletConfig之间的关系?
一个Servlet对象会对应一个ServletConfig对象。
ServletConfig对象的本质是什么?
ServletConfig实际上是一个Servlet对象相关的配置信息对象。一个Servlet在web.xml文件中标签中配置的信息会自动被封装到ServletConfig对象中,通过ServletConfig对象我们可以获取到当前的Servlet对象的相关配置信息。
ServletConfig接口中常用的方法
通过初始化参数的name获取初始化参数的value
String value = config.getInitParameter(String name);
获取所有初始化参数的name
Enumeration names = config.getInitParameterNames();
获取ServletContext对象
ServletContext application = config.getServletContext();
研究javax.servlet.ServletConfig接口:
1、javax.servlet.ServletConfig是接口
2、apache Tomcat服务器对ServletConfig接口的实现类完整类名是:
org.apache.catalina.core.StandardWrapperFacade
public class org.apache.catalina.core.StandardWrapperFacade
implements javax.servlet.ServletConfig{
}
注意:
对于javaweb程序员来说,我们不需要关心ServletConfig接口的实现类是什么!!!!
我们只需要面向ServletConfig接口调用即可。
这就是面向接口编程
ServletConfig接口的调用者:javaweb程序员
ServletConfig接口的实现者:web容器/web服务器/Tomcat服务器
Tomcat容器实现了Servlet+JSP规范。
3、ServletConfig对象中保存了什么信息?ServletConfig是干什么的?
ServletConfig对象是“Servlet对象的配置信息对象”
Servlet对象的配置信息在web.xml文件中的<servlet></servlet>标签内部
ServletConfig对象封装了当前Servlet对象的配置信息。
通过ServletConfig对象可以获取该Servlet对象的相关配置信息。
4、一个Servlet对象对应一个ServletConfig对象,100个Servlet对象对应100个ServletConfig对象。
5、ServletConfig接口中常用方法有哪些?
- String getInitParameter(String name) 通过初始化参数的name获取value
- Enumeration getInitParameterNames() 获取所有初始化参数的name
- ServletContext getServletContext() 获取ServletContext对象【ServletContext后面讲】
- String getServletName() 【使用较少】
ServletConfig在init方法中,怎么样能在service方法中使用ServletConfig呢?
1、提供一个实例变量:private ServletConfig config;
2、在init方法中编写:this.config = config;
3、实现getServletConfig方法,直接返回:config
ServletContext对象详解
javax.servlet.ServletContext是SUN制定的接口,apache对ServletContext接口的实现类完整类名:org.apache.catalina.core.ApplicationContextFacade,但是程序员不需要关心具体的类名,直接面向ServletContext接口调用方法即可。
如何获取ServletContext对象呢?
通过ServletConfig对象获取ServletContext对象
ServletContext application = config.getServletContext();
ServletContext代表什么?什么时候被创建?什么时候被销毁?
ServletContext在Tomcat服务器启动阶段解析webapp中的web.xml文件的时候创建ServletContext对象。
在Tomcat服务器关闭的时候ServletContext对象被销毁。
对于同一个webapp来说,ServletContext对象只有一个。
ServletContext代表“Servlet上下文”。ServletContext上下文指的是“所有Servlet对象共享的一个四周环境”对象。在同一个WEBAPP中,所有的Servlet对象共享一个ServletContext对象。存储在ServletContext对象中的数据所有的Servlet共享。ServletContext对象可以完成多个Servlet之间数据的传递。
ServletContext接口中常用的方法
向Servlet上下文中存储数据
application.setAttribute(String name,Object obj);
从Servlet上下文中读取数据
Object obj = application.getAttribute(String name);
删除Servlet上下文中的数据
application.removeAttribute(String name);
获取Servlet上下文参数所有的name
Enumeration names = application.getInitParameterNames();
通过Servlet上下文参数的name获取value
String value = application.getInitParameter(String name);
通过ServletContext获取文件的绝对路径真实路径
String realPath = application.getRealPath(“/index.html”); 注意:必须保证webapp的根下有index.html
什么样的数据适合存储到ServletContext对象中?
很少的数据量
所有用户共享的数据
这些共享数据不涉及到修改操作,或者很少涉及到修改操作。
多线程环境下,什么情况下需要考虑线程并发带来的安全问题?
多线程环境下运行程序
有共享的数据
共享数据涉及到修改操作
解决线程安全问题有两种解决方案?
使用局部变量替代成员变量、静态变量,局部变量在栈中存储,栈内存不共享,成员变量在堆内存的java对象内部存储,堆内存是共享的,静态变量在方法区中存储,方法区内存也是多线程共享的。
使用线程同步机制:synchronized语法支持线程同步机制。(会使并发量降低,吞吐量降低)
研究javax.servlet.ServletContext接口
1、javax.servlet.ServletContext是一个接口
2、apache Tomcat服务器对ServletContext接口的实现,实现类的完整类名:org.apache.catalina.core.ApplicationContextFacade
public class org.apache.catalina.core.ApplicationContextFacade implements javax.servlet.ServletContext{
}
注意:javaweb程序员不需要关心具体的实现类,还是面向ServletContext接口调用方法即可。实现类是服务器负责的。
Tomcat就是一个实现了Servlet+JSP规范的容器。
3、ServletContext对象的个数?
在同一个webapp中,ServletContext对象只有一个
在web服务器启动阶段被创建
在web服务器关闭的时候被销毁
ServletContext对象是一个应用级别的对象。
注:100个app对应100个ServletContext
一个Servlet对应一个ServletConfig,所有的Servlet共享一个ServletContext
4、ServletContext怎么理解,它是什么,主要作用是什么?
-
ServletContext是一个Servlet上下文对象
-
ServletContext对象是所有Servlet共享的一个四周环境对象
- Context单词翻译:上下文
- 例如:contextPath就是上下文路径: /prj-servlet-06 【webapp的根路径】
- ServletContext可以完成多个Servlet之间共享同一些数据。
- ServletContext对象中封装了web.xml文件中所有信息,
ServletContext对象只有一个,web.xml文件也是只有一个
web.xml文件也是在服务器启动阶段被解析,ServletContext也是在服务器启动阶段被创建。
5、ServletContext接口中常用的方法:
void setAttribute(String name, Object object) //向Servlet上下文中绑定一个数据object,起名name (map.put(key,value))
Object getAttribute(String name) //从Servlet上下文中取object,通过name (Object value = map.get(key))
void removeAttribute(String name) //移除Servlet上下文中的某个数据,通过name (map.remove(key))
String getInitParameter(String name) //通过上下文参数的name获取上下文参数value
Enumeration getInitParameterNames() //获取所有上下文参数的name
String getRealPath(String path) //获取绝对路径
InputStream getResourceAsStream(String path) //直接获取文件输入流
6、通过ServletContext对象可以完成:跨用户传递数据
Servlet、ServletConfig、ServletContext对象的内存关系
Servlet、ServletConfig、ServletContext三个对象的代码关系如下所示:
public class Servlet{
private ServletConfig config;
public ServletConfig getServletConfig(){
return config;
}
}
public class ServletConfig{
private ServletContext servletContext;
public ServletContext getServletContext(){
return servletContext;
}
}
Servlet、ServletConfig、ServletContext三个对象内存关系图:
结论:一个Servlet对应一个ServletConfig对象,所有的Servlet对象共享一个ServletContext对象。