核心:Servlet,ServletConfig,ServletContext
浏览器与服务器通信的过程:
客户端发送请求,由于要使用某种传输协议,所以在服务器这端,会有对应的连接器负责连接;Engine引擎分析处理传过来的url地址,截取出资源地址,去匹配配置文件中的
5)发送隐式的 HTTP 响应到浏览器。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他的任务。 (状态行和响应正文)
Servlet 生命周期:
从创建直到毁灭的整个过程。
Servlet 遵循的过程:
1)Servlet 通过调用 init () 方法进行初始化。
2)Servlet 调用 service() 方法来处理客户端的请求。
3)Servlet 通过调用 destroy() 方法终止(结束)。 最后Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
1)init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
2)service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost等方法。
service() 方法由容器调用,所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重载 doGet() 或 doPost() 即可。
3)doGet() 方法:GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。
4)doPost() 方法:POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。(只有HttpServlet中才有doPost(),doGet())
5)destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
Servlet在web应用中的位置:
Html,jsp一般存在web应用根目录下,根目录下的文件外界可以直接访问。
java类、jar包、web应用的配置文件存在这个目录下,该目录下的文件外界无法非法直接访问,由web服务器负责调用。
Servlet执行过程:
1,客户端发出请求http://localhost:8080/Demo1/abc
2,根据web.xml文件的配置,找到
3,读取
4,找到
5,读取
6,Servlet,到Tomcat安装目录
/webapps/Demo1/WEB-INF/classes/cn/itcast目录下查找到HelloServlet.class文件。
Servlet的运行过程:
Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
1)Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
2)装载并创建该Servlet的一个实例对象。
3)调用Servlet实例对象的init()方法。
4)创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
5)WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
Servlet主要作用是:处理从客户端发送的请求及服务端的响应。
常见的属性
Servlet标签用来定义一个Servlet对象
Servlet-mapping标签用来定义一个映射关系,其实就是访问方式
一个web项目中可以有多个servlet对象,每个Servlet对象实现不同的功能,对应不同的网页,就如同java应用程序中的一个项目有多个类;
web浏览器是通过url访问服务器资源
服务器直接调用servlet对象(servlet应用程序)。Servlet是运行于在web服务器(Tomcat)上的程序.它是作为来自web浏览器或其他客户端的请求和web服务器上的数据库或应用程序之间的中间层。
服务器创建Servlet的过程:
1)截取网络请求的Url,和url_pattern的值一一进行比较,然后找到对应的Servlet。
2)根据Servlet-class创建Servlet对象,调用init()方法,进行servlet的初始化,然后调用service()方法。
3)将处理好的数据放到response对象的缓存中;从Response对象的缓存中拿到数据,按照http协议的要求组织数据,发送到浏览器。
Servlet的生命周期:
方法的调用顺序init---->service---->destroy
init()方法和destroy()方法只会调用一次;service方法会反复不断的调用。
默认调用带参数的init()方法,用于初始化。
默认情况下,servlet对象在第一次请求的时候调用构造函数创建, 创建之后自动调用带参的init方法,然后调用service方法.destroy方法在停止服务器或者停止应用的时候调用。整个过程中,init方法和destroy方法只会调用一次,而service方法会反复调用。
★什么时候创建servlet对象:当浏览器第一次访问web应用程序时,创建servlet对象。什么时候销毁servlet对象。
★在用户通过浏览器第一次访问web网站时,tomcat服务器会匹配网址中的资源地址,如果能够匹配到
★可能会出现一个servlet对应多个
★先有配置文件,再有servlet对象(创建项目后,创建一个servlet对象)。
可以通过配置web.xml文件来改变创建servlet的时机.配置如下
servlet的创建问题:
创建一个servlet有3中方式:
1) 采用实现servlet接口, 然后创建类的实例servlet对象(不推荐)
2) 采用继承GenericServlet类(抽象类 不推荐) 支持所有的传输协议
3) 采用继承HttpServlet(抽象类推荐) 只支持Http传输协议,专门用于处理通过http协议发送的请求和相应。
在继承自HttpServlet抽象类的自定义类中,不要重写service()方法。此service()方法具有专门的用途:判断用户以哪种请求方式访问服务器端资源,主要用于请求转发。
Servlet:
理论上:servlet是一个接口,代表一种“响应规范”。因为它是一个接口,所以要使用它的实现类对象。
实际上:servlet代表一个java应用程序。
“请求重定向”与”请求转换”之间的区别:请求重定向是客户端行为,浏览器地址栏中的网址要发生;请求转换是服务器的行为,浏览器地址栏中的地址不会发生改变。
网址:协议+域名+端口号+应用目录+资源地址+资源名称。
如: http://localhost:8080/aaa/1.html。
第一个到达服务器的 HTTP 请求被委派到 Servlet 容器,里面装的是servlet对象。
Servlet 容器在调用 service() 方法之前加载 Servlet。
然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。
Servlet是位于Web 服务器内部的服务器端的Java应用程序。
Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机。
应用
url的写法注意:
客户端跳转:(由浏览器发出的请求) 一定需要在地址前加应用的名称
服务端跳转: (由服务端发出的请求) 不需要在地址前加应用的名称
应用:
1)实现数据共享。(全局只有一个ServletContext对象)
2)获取全局配置参数。进行全局参数配置
servlet创建的两种时机(☆)
1)服务器启动的时候创建,2)有请求到达时创建
1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。
2)它的值必须是一个整数,表示servlet应该被载入的顺序
2)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
3)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。
4)正数的值越小,该servlet的优先级越高,应用启动时就越先加载(已经测试过)。
5)当值相同时,容器就会自己选择顺序来加载。
Url配置:
由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用
一个
配置url-pattern有两种方式:
1)以/开头,/代表了工程路径 2)以*开头,后面必须添加后缀名。
注意:
1)
2)同一个Servlet可以被映射到多个URL上,即多个
Servlet的运行过程:
web浏览器发出http请求,web容器调用Servlet的service(Request,response)方法进行请求分发;
读取Request对象,拿到请求的信息;通过response对象写入响应信息,然后返回给wab容器,web容器根据http协议组织好数据格式,返回给客户端浏览器。
Request中包含请求头,请求体;response中包含响应头,响应体。
Tomcat的作用是什么?进行请求转发,把响应结果按照http协议的格式组织,然后返回给浏览器。
缺省的Servlet:
1)如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。
2)凡是在web.xml文件中找不到匹配的
Servlet的线程安全:
1)当多个客户端并发访问同一个Servlet时,Web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。
doGet() doPost()方法的执行是需要一段时间的。
2)如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。SingleThreadModel接口中没有定义任何方法,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可。这样也会有问题,多个请求可能出现排队现象,造成服务器端响应速度慢。
如何解决呢:合理决定在Servlet中定义的变量的作用域。把全局变量修改成doGet()方法中的局部变量,每次都进行初始化 int a=0;a++。
Servlet核心类图:
Servlet接口 ServletConfig接口 ServletContext接口
Servlet接口的实现类GenericServlet(抽象类)
HttpServlet继承自GenericServlet,也是抽象类
获取ServletConfig对象:
1)在Servlet的配置文件中,可以使用一个或多个
2)当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
1)使用带参数的init()方法获取ServletConfig
2)采用Servlet实例进行获取
注意:
一个init-param只能配置一个键值对
当前web.xml文件中的Servlet节点下,需要有
使用ServletConfig:使用ServletConfig对象获取配置文件里的参数
ServletResponse
servertest.ServletResponse
陈如水
君临天下
秦珍珍
十里桃花
//ServletConfig sc = getServletConfig();
//String name = sc.getInitParameter("陈如水");
//System.out.println(name+"text");
//以枚举的形式获取所有配置键的集合 Enumeration枚举类的使用
//Enumeration params = sc.getInitParameterNames();
//while (params.hasMoreElements()) {
// String content = params.nextElement();
// System.out.println(content + ":" + sc.getInitParameter(content));
//}
//获取ServletContext对象(这三个方法获取的对象是同一个)
//ServletContext servletContext = this.getServletConfig().getServletContext();
//ServletContext servletContext1 = this.getServletContext();
//ServletContext servletContext2 = request.getServletContext();
ServletContext对象的应用:
1)把ServletContext当做域对象进行使用
2)通过ServletContext获取全局的配置参数
3)通过ServletContext进行请求转发
4)通过ServletContext获取资源文件
name
小龙女
age
18
//把ServletContext当做域对象进行使用
//String name = (String) servletContext.getAttribute("name");
//System.out.println(name);
//通过ServletContext获取全局的配置参数(获取单个配置参数)
//ServletContext servletContext = getServletContext();
//String age = servletContext.getInitParameter("age");
//System.out.println(age);
//ServletContext servletContext = this.getServletContext();
//Enumeration names = servletContext.getInitParameterNames();
//while (names.hasMoreElements()) {
// //names:表示枚举值,内部是键值对
// String key = names.nextElement();
// System.out.println(key + ":" + servletContext.getInitParameter(key));
//}
//通过ServletContext进行请求转发(获取请求转发器,转发到新的web资源)
//这种请求转发很少使用,Request对象中自带请求转发的方法了
//ServletContext servletContext = this.getServletContext();
//servletContext.setAttribute("test","请求转发");
//RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/ServletResponse8");
//requestDispatcher.forward(request,response);
//获取资源文件的三种方式(里面全部都是键值对, 资源文件和配置文件是不一样的)
//获取全局对象
ServletContext sc = this.getServletContext();
//获取资源文件的路径(相对路径)
String path = sc.getRealPath("/p1.properties");
//读取资源文件中的数据
Properties properties = new Properties();
properties.load(new FileInputStream(new File(path)));
System.out.println(properties.getProperty("s001"));
//请求转发之后,获取资源
ServletContext sc = this.getServletContext();
String test = (String) sc.getAttribute("test");
System.out.println(test);