什么是Servlet
Servlet 运行在服务端(Tomcat)的Java小程序,是sun公司提供一套规范, ?????????? 不是apache公司写的吗?
Servlet接口在tomcat的jar包里,所以不导包不行, 因此创建工程时导了tomcat运行环境/ 使用maven后直接加servlet依赖
一套接口和规范: 处理请求,响应资源
其实现类是, java的web层的代码
但servlet的实质( 发布在tomcat里的java代码 web层 [实现服务器的servlet接口] ) 就是java代码,
处理请求, 动态的向客户端输出内容
Servlet有狭义和广义的定义
狭义的servlet:指的就是servlet接口规范
广义的servlet:指的是实现了Sevlet接口的所有的实现类 (说起来都是指这种)发布在服务器的 java代码对服务器servlet接口的实现
Servlet演示
实现步骤:
1)创建类实现Servlet接口
2)覆盖尚未实现的方法(着重关注service方法) doGet/doPost
3)在web.xml进行servlet的配置 资源名(url-name)-(servlet-name)-(class-name) 反射
(web.xml就相当于web工程清单)
创建servlet
public class Demo1Servlet implements Servlet{
/**
* 这是servlet的销毁方法,服务器停止或者将项目从tomcat移除的时候,销毁servlet。
*/
public void destroy() {
System.out.println("servlet被销毁了。");
}
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
/**
* servlet的初始化方法, servlet对象 在第一次被访问的时候创建(由tomcat创建),并且调用init方法。
这个servlet被访问(可以想象成虚拟机执行这个servlet实现类) 执行的基本含义: 对象调用方法
*/
public void init(ServletConfig arg0) throws ServletException {
System.out.println("servlet的初始化方法");
* ServletConfig:代表了当前servlet的配置信息对象。
/**
* 第一个功能:获取当前servlet的名称
*/
// String servletName = arg0.getServletName();
// System.out.println(servletName);
/**
* 第二个功能,获取当前servlet的初始化配置参数(自己手动配的东西)
*/
String initParameter = arg0.getInitParameter("name");
System.out.println(initParameter);
Enumeration<String> initParameterNames = arg0.getInitParameterNames();
while(initParameterNames.hasMoreElements()){
String name = initParameterNames.nextElement();
String value = arg0.getInitParameter(name);
System.out.println(name+":"+value);
}
/**
* 第三个功能:用来获取servletContext对象(web应用对象)
*/
ServletContext servletContext = arg0.getServletContext();
System.out.println(servletContext);
}
/**
* 这是servlet的服务方法,每当发出请求的时候,都会执行一次这个service方法。(tomcat接受请求时就会生成两个参数传入request/response)
* ServletRequest:这个代表了http的请求,所以这个对象中get方法居多。
* ServletResponse:这个就代表了http的响应,set方法居多。
*/
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
System.out.println("running...");
}
}
web.xml:
工程清单 url-pattern->servlet-name->servlet-class
<servlet>
<servlet-name>Servlet</servlet-name>
<servlet-class>com.itheima.servlet.Demo1Servlet</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>lisi</param-value>
</init-param>
<init-param>
<param-name>age</param-name>
<param-value>18</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Servlet</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
Servlet的API
对象的生命周期
指的是一个对象从创建到销毁的整个过程。
Servlet方法按照功能的不同,大致分为三个执行的阶段,分别是 初始化阶段(init),运行阶段(service) 和 销毁阶段(destroy)。
其中初始化阶段和销毁阶段只会执行一次(第一次被访问和服务器关闭) , 而运行阶段每次请求都会执行。
Servlet作为对象 // servlet作为类的对象
Servlet的API中的描述如下:
Servlet接口中的方法
1)init(ServletConfig config)
创建servlet时会调用的方法,用来初始化一些配置信息,仅在创建servlet时执行一次。
2)service(ServletRequest request,ServletResponse response)
每次请求Servlet都会执行的方法(有请求才会有响应)
3)destroy()
servlet在销毁之前会执行的方法,仅在销毁servlet时执行一次。
运行阶段-service()
在这个阶段,tomcat服务器会为这个请求 创建 代表HTTP请求的ServletRequest对象 和 代表HTTP响应的 ServletResponse对象,然后将他们作为参数传递给service() 方法。
servcie() 方法从ServletRequest对象获取请求的信息并做出处理;通过ServletResponse 对象生成响应的结果。
在servlet的整个生命周期内,对于servlet的每一次访问请求,tomcat都会调用servlet的service方法,也就意味着service() 方法会在servlet的生命周期内会被调用多次。
销毁阶段-destroy
当服务器正常关闭或者Web应用被移出服务器时,servlet会随着Web应用的销毁而销毁。在销毁serlvet之前,tomcat 会调用Servlet的destory方法,以便让Servlet对象释放他所占用的资源。
注意:如果对servlet中的代码进行了任何修改,一旦保存,会重新加载servlet,而这个过程就等于是将servlet先卸载,然后重新加载,因此也会执行destroy方法
注意:销毁方法只有在正常关闭下才会执行
正常关闭:在servers中点击关闭按钮才算正常关闭
非正常关闭:在console中点击关闭按钮属于强制关闭
Servlet的生命周期(重点---笔试/面试)
1)Servlet何时创建
默认第一次访问该servlet时创建(tomcat创建)
该servlet对象创建时执行init方法 (传入servletConfig 对象 配置信息对象)
Servlet对象只有一个(单例的)
2)Servlet何时销毁
服务器关闭/从服务器中将web应用移除
销毁servlet对象之前执行destroy方法
3)每次访问必然执行的方法
service方法---每次访问该servlet资源都会执行的方法
ServletRequest/ServletResponse
ServletRequest和ServletResponse由tomcat创建,在调用service方法的时候传递
/**
* 这是servlet提供服务的方法
* 每次浏览器发出访问当前servlet的 请求,那么都会执行一次service方法。
* ServletRequest 代表了http的请求。所以这个中以get方法居多。
* ServletResponse 代表了http的响应。所以set方法居多。
*/
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
System.out.println("servlet 的service方法");
}
ServletConfig的介绍(了解)
每一个servlet都有一个与之对应的servletConfig对象,它是servlet 的配置对象,封装了servlet的初始化配置信息。
tomcat在创建Servlet的时候会调用init方法将ServletConfig对象传递过来。
1.(放置初始化信息的).
2. 获取servletcontext对象 .
初始化参数配置 (自己配的) name /
<servlet>
<servlet-name>Demo1Servlet</servlet-name>
<servlet-class>com.itheima.servlet.Demo1Servlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>yanyan</param-value>
</init-param>
<init-param>
<param-name>age</param-name>
<param-value>18</param-value>
</init-param>
</servlet>
/**
* servlet的初始化方法
* servlet在默认情况 下是第一次被访问的时候初始化。
*/
public void init(ServletConfig config) throws ServletException {
/**
* ServletConfig 代表了当前servlet的 配置信息 对象。
* 1.获取当前servlet的名字
* 2.获取当前servlet配置的初始化参数
* 3.用来获取servletContext对象
*/
String servletName = config.getServletName();
System.out.println(servletName);
String initParameter = config.getInitParameter("username");
System.out.println(initParameter);
Enumeration<String> initParameterNames = config.getInitParameterNames();
while(initParameterNames.hasMoreElements()){
String name = initParameterNames.nextElement();
String value = config.getInitParameter(name);
System.out.println(name+":"+value);
}
System.out.println("serlvet初始化了");
ServletContext servletContext = config.getServletContext();
System.out.println(servletContext);
}
HttpServlet 子类
Servlet - httpServlet (无协议-http协议)
Servlet是一个无协议的接口,要获取请求和响应数据更多信息,就需要实现servlet接口并且支持http协议,而Servlet其中的一个子类javax.servlet.http.HttpServlet就支持http协议。
因此在开发中我们一般会编写一个类来继承HttpServlet来接收和响应来自客户端的请求。 不直接实现servlet接口了
编写serlvet的步骤
继承HttpServlet,重写doGet和doPost方法
将servlet配置到web.xml中
步骤一:编写类继承HttpServlet
public class Demo2Servlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//如果是post提交方式,那么执行doPost方法
System.out.println("post提交");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//如果是get提交方式,那么执行doGet方法
System.out.println("get提交");
}
}
步骤二:配置web.xml
<servlet>
<servlet-name>Demo2Servlet</servlet-name>
<servlet-class>com.itheima.servlet.Demo2Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo2Servlet</servlet-name>
<url-pattern>/demo2</url-pattern>
</servlet-mapping>
步骤三:发布工程
步骤四:测试访问
doGet/doPost方法与service方法联系
Servlet和GenericServlet以及httpServlet之间的关系:
因为有了httpservlet:
所以:
我们在编写servlet的时候一般不会去实现Servlet接口,
而是继承HttpServlet,并且也不会复写service方法,而是复写doGet或者doPost方法。
原因如下:
在HttpServlet类中有一个service方法,在该方法中对请求的方法进行了判断,如果是get方法就执行doGet()方法,如果是post方法就执行doPost方法:
使用Eclipse模版
Eclipse工具内部提供了直接创建servlet程序的方法
步骤一:选中包名右键或者,Ctrl + n 新建servlet
步骤二:生成如下
步骤三:编写和优化代码
public class Demo3Servlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("执行get请求");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
在上述使用eclipse工具生成servlet的时候发现,其中有很多不需要的代码或者注释,每次去删除显得非常麻烦,因此可以设置servlet的模版来使每次创建的servlet符合我们自身的要求。
关联源码
选择apache-tomcat-7.0.78-src.zip 源码包即可 / 和jar包进行区别
Servlet配置(web.xml)
url-pattern的配置方式
(重点掌握)
<!--
url-pattern的配置:
/ 在后台代表的是 http://服务器的ip地址:服务器的端口/当前项目名
1.全路径匹配 以/开始,后面跟上具体的路径 例如:/demoServlet
http://localhost:8080/web02/demoServlet
2.通配符写法 以/开始,路径要有* 例如:/user/*
http://localhost:8080/web02/user/*
-->
如果tomcat启动的时候报错,那么表示<url-pattern>标签之间的路径格式不正确。 (/不能少打)
url-pattern的配置方式有三种:
1、 全路径匹配
客户端的访问资源的地址与配置的地址完全一致
/ 代表了 htttp://ip地址:端口号/项目名/
2、 通配符匹配
以/开始 以*结束
示例:/aaa/bbb/* --- 代表访问/aaa/bbb下的任何资源都匹配 ? 简单理解:随便写
3、 扩展名匹配
以*开始 以扩展名结束
示例:*.abc
注意:第二种与第三种不能混合使用
例如:/aaa/bbb/*.abc ---- 错误的
全路径匹配
在书写url-pattern的时候,必须以/开始,后面书写具体浏览器访问时的路径。
外界的访问方式:
http://localhost:8080/web_day02/demo3
url的请求名称必须和其一致才能访问
路径通配符匹配
在书写url-pattern 的时候,以/开始,后面可以使用*号表示任意的匹配
外界在访问的时候,只要能够和/demo3匹配上,不管后面有几层路径都可以。
http://localhost:8080/web_day02/demo3/abc/bb/ccc/ddd/eee
扩展名匹配
在书写url-pattern 的时候,不以/开始,而是以*开始,后面书写扩展名
常见的扩展名书写:
*.action *.do
访问的方式:
http://localhost:8080/web_day02/demo.do
<servlet>
<servlet-name>Demo4Servlet</servlet-name>
<servlet-class>com.itheima.servlet.Demo4Servlet</servlet-class>
<!--
load-on-startup : 配置一个正整数,那么当服务器启动的时候,servlet也会随tomcat
服务器的启动一起被创建。
如果数值越小,那么优先级就越高。一般情况,将1给空出来。
-->
<load-on-startup>4</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Demo4Servlet</servlet-name>
<!--
url-pattern的3种配置方式:
1.全路径匹配 就是以 / 开始,/后面跟上具体内容 例如: /Demo4 /代表了http://localhost:8080/web02
所以 /Demo4 ====== http://localhost:8080/web02/Demo4
2.通配符写法 * 表示匹配所有 以/开始,其中包含* 例如 : /aa/* === http://localhost:8080/web02/aa/*
localhost:8080/web02/bb/aabb
3.扩展名写法 不能有/ 例如: *.action *.do
如果有3个如下配置
/aa/bb.action
/aa/*
*.action
客户端发出的请求:
http://localhost:8080/web02/aa/bb.action 上述3个配置全部满足?访问的是哪一个?
3种配置方式的优先级问题?
全路径> 通配符匹配 > 扩展名匹配
-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
url-pattern标签中的路径可以按照上述的三种书写,它们的优先级:
全路径匹配 > 通配符匹配 > 扩展名匹配
※练习:
对于如下的一些映射关系:
Servlet1 映射到 /abc
Servlet2 映射到 /abc/*
Servlet3 映射到 /*
Servlet4 映射到 *.do
问题:如果在web.xml中同时存在以上的url配置,那么请求思考,以下的url会优先执行哪个servlet?
问题1:当请求URL为“/abc/a.html”
问题2:当请求URL为“/abc”时,
问题3:当请求URL为“/abc/a.do”
问题4:当请求URL为“/a.do”
问题5:当请求URL为“/xxx/yyy/a.do”
服务器启动 实例化Servlet 配置(知道作用)
服务器启动时就创建servlet, 不待访问和请求
实际应用场景:
连接池初始化、缓存的加载、定时任务、
servlet的生命周期:
何时创建:默认第一次访问时创建该servlet对象
何时销毁:正常关闭服务器或者将项目从服务器中移除。
修改servlet的创建时间:
因为存在<load-on-startup>配置,可以让服务器一启动就创建servlet对象
语法:<load-on-startup>正整数</load-on-startup>
<load-on-startup> 一般用于启动一些初始化的java程序
其中正整数越小创建对象优先级越高,建议不要将1占用。
因为如果以后需要在执行一些servlet之前需要先初始化哪个servelt的话,起码还有1可以设置,否则就需要一个一个改过去了。
设置Demo1Servlet和Demo2Servlet的创建顺序,分别查询哪个servlet先创建。
<!--
服务器启动实例化的配置,一旦配置一个正整数,那么在tomcat服务器启动的时候,就去创建servlet的实例。
load-on-startup 配置的正整数越小,优先级越高。一般情况下不设置1的。
-->
<load-on-startup>1</load-on-startup>
缺省(默认)Servlet
缺省的servlet:当所有的servlet匹配都不成功时,缺省servlet负责响应
当url-pattern配置成/时,那么该servlet就是缺省的servlet
缺点:当访问一个存在的静态资源的时候,会自动去访问缺省的servlet. (静态资源实际上并不需要去通过servlet给予动态回应)
(因为所有的servlet动态资源都不匹配)
演示:将DemoServelt的配置修改如下
步骤一:
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
步骤二:
在WebContent下创建一个index.html页面
步骤三:测试访问该页面
结果发现访问的是缺省的servlet 而导致访问不到真正的静态资源了 (本来是要去访问tomcat全局的web.xml的)
Tomcat全局的web.xml
注意:工程中的web.xml的优先级要高于Tomcat内置的web.xml
先在工程里面找, 找不到, 再去全局web.xml, 去找静态资源, 再找不到, 就4o4
1) 欢迎页面
2) 缺省的servlet //静态资源
用来解析静态资源的。比如:http://localhost:8080/WEB13/demo.html,会先到web.xml中查找有没有一个url-pattern是demo.html的servlet,如果没有,那么会执行缺省的DefaultServlet,到WEB13工程的根目录下去查找有没有demo.html的静态文件,有就读取内容并且返回给浏览器,没有就报404。
3) jsp的响应servlet
在访问jsp的过程中会执行JspServlet
扩展名匹配方式:当请求路径的后缀是以下面三个为结尾时,就去执行JspServlet.
4) session的失效时间
session默认的失效时间为30分钟。
如果要重新设置session的失效时间,只要将其在工程中的web.xml设置即可,因为工程中web.xml的优先级高于tomcat内置的web.xml
5) MIME类型
Window系统看文件的类型是通过扩展名 .avi .jpg .rmvb .mp4 .gif
浏览器区分文件的类型是通过MIME类型
原文:https://www.cnblogs.com/wenhui2015/p/11427160.html