Servlet Learner03

继承图
Servlet<---GenericServlet<---HttpServlet<---MyServlet
大多数servlet方法来自GenericServlet doGet doPost doHead do...方法都在HttpServlet中
==============================================================================
作为Web应用
初始化参数 eg 在DD中配置email地址 而不是硬编码到servlet类中
out.println("[email protected]"); 要改email 不用每次都冲洗编译servlet 只要写DD就可以了

DD文件
<servlet>
<servlet-name>Ch3 Beer</servlet-name>
<servlet-class>com.example.web.BeerSelect</servlet-class>

<init-param>
<param-name>adminEmail</param-name>
<param-value>[email protected]</param-value>
</init-param>
</servlet>

在servlet代码中
out.println(getServletConfig().getInitParameter("adminEmail"));

在servlet初始化之前不能使用servlet初始化参数
容器初始化一个servlet时 会为中国servlet建一个唯一的ServletConfig
容器从DD读出servlet初始化参数 并把这些参数交给ServletConfig 然后ServletConfig传递给init方法

servlet初始化参数只能读一次 就是在容器初始化servlet的时候 一旦参数放在ServletConfig中 就不会再读
了 除非你重新部署servlet

过程
1.容器读取这个servlet的DD 包括servlet的初始化参数
2.容器为这个servlet创建一个新的ServletConfig实例 容器---new了--->ServletConfig
3.容器为每个servlet初始化参数创建一个String名/值对,假设这里只有一个初始化参数
4.容器向ServletConfig提供名/值初始化的引用
5.容器创建servlet类的一个实例!!!!!!!!!!!!!!!!!!!!!!(这里才创建实例 用了构造函数)
6.容器调用servlet的init()方法传入ServletConfig

上下文初始化参数 context 上下文;语境;环境
上下文参数对整个Web应用而不只是一个servlet可用 所以 应用中所有的servlet和JSP都自动的能访问
上下文初始化参数 我们不必费心为每个servlet配置DD 而且如果值有变化 只需在一个地方修改就行
<context-param>
<param-name>adminEmail</param-name>
<param-value>[email protected]</param-value>
</context-param>

==============================================================================
监听者

我们需要一个单独的类 它能做到
1.上下文初始化时得到通知(应用得到部署)
i.从ServletContext得到上下文初始化参数
ii.使用初始化参数查找名建立一个db连接
iii.吧数据库连接存储作为一个属性 使得Web应用的各个部分都可以访问
2.上下文撤销的时候得到通知(应用取消部署或者结束)
关闭数据库

一个Listerner的例子
---MyServletListener.java

package com.example;
import javax.servlet.*;
public class MyServletListener implements ServletContextListener
{
@Override
public void contextInitialized(ServletContextEvent event)
{
//由事件得到ServletContext
ServletContext sc = event.getServletContext();
//使用上下文得到初始化参数
String dogBreed = sc.getInitParameter("breed");
Dog d = new Dog(dogBreed);

//使用上下文属性来设置属性(name/object)对这个属性是Dog 现在用其他部分就能得到属性(Dog)的值了 Attribute:属性
sc.setAttribute("dog", d);//vodi setAttribute
}

@Override
public void contextDestroyed(ServletContextEvent servletContextEvent){}
}

---Dog.java

package com.example;

/**
* Created by Melody on 2015/10/31.
*/
public class Dog
{
private String breed;
public Dog(String breed)
{
this.breed = breed;
}

public String getBread()
{
return breed;
}
}

---ListenerTester.java

package com.example;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
* Created by Melody on 2015/10/31.
*/
public class ListenerTester extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest      request,HttpServletResponse response)
    throws ServletException, IOException
    {
        PrintWriter out = response.getWriter();

        out.println("test context attributes set by listener<br/>");
        out.println("<br/>");

        //getServletContext    返回ServletContext(是个对象 一切皆对象)         getAttribute返回的是Object!!!!!!!!!切记
        //getInitParameter() returns String
        Dog dog = (Dog) getServletContext().getAttribute("dog");
        out.println("Dog‘s breed is: " + dog.getBread());
    }
}   

http://localhost:8080/listenerTest/ListenTest.do

Servlet类名: ListenerTester.class
Web应用目录: listenerTest
映射到servlet的URL模式: ListenTest.do

完整的故事
1.容器读这个应用的DD(web.xml) 包括<listener>和<context-param>
2.容器为这个应用创建一个新的ServletContext 应用的所有部分都会共享这个上下文
容器---new了--->SservletContext
3.容器为每个上下文初始化参数创建一个String名/值对 这里假设只有一个参数
容器---new了--->"breed"(String)          | 来自DD的上下文初始化参数         |
    |---new了---->"Great Dane"(String) |_________________________|

4.容器将名/值参数的引用交给ServletContext(传递引用)
ServletContext------>"breed"(String)
                   |------>"Great Dane"(String)

5.容器创建MyServletContextListener类的一个新实例
容器---new了--->MyServletContextListener.class的实例

6.容器调用监听者的contextInitialized()方法 传入新的ServletContextEvent 这个事件对象有一个
ServletContextEvetn引用 所以事件处理代码可以从事件得到上下文初始化参数

ServletContext|------>"breed"(String)
                                                               |------>"Great Dane"(String)
                                                ↑
                                     ServletContextEvent
                                                ↓
容器------contextInitialized(ServletContextEvent)--->监听者

7.监听者向ServletContextEvent要ServletContext的一个引用
监听者--getServletContext()-->ServletContextEvent(这样写是一个对象) 现在监听者得到ServletContext

8.监听者向ServletContext要上下文初始化参数"breed"
监听者--getInitParameter("breed")-->ServletContext(这样写是一个对象) |------>"breed"(String)
                                                                                                   |------>"Great Dane"(String)
现在监听者得到上下文初始化参数"breed"

9.监听者使用初始化参数来构造一个新的Dog对象
监听者---new了--->Dog.class

10.监听者吧Dog设置为ServletContext中的一个属性
监听者--setAttribute("dog", d)--->ServletContext(对象)

11.容器建立一个新的servlet(利用初始化参数建立一个新的ServletConfig,为这个ServletConfig提供Servlet
Context的要给引用 然后调用servlet的init()的方法)
             ServletContext|------>"breed"(String)
                                  |------>"Great Dane"(String)
                           ↑
                   ServletConfig
                           ↓
容器------init(ServletConfig)--->ListenerTester.class(这个是servlet 也是controller)的实例

12.servlet得到一个请求 向ServletContext请求属性"dog"
Servelt---getAttribute("dog")--->ServletContext(对象)

13.servlet在Dog上调用getBread() 并将结果打印到HttpResponse
Servlet---getBread()--->Dog(对象)

监听者不只是针对上下文事件只要是生命周期里的重要时刻 总有一个监听者在监听
除了上下文事件之外 还可以监听与上下文属性 servlet请求和属性 以及HTTP会话和会话属性相关的事件

web应用上下文中是否增加 删除或替换了一个属性 监听者接口 ServletContextAttributeListener
attributeAdded attributeRemoved attributeReplaced

想跟踪活动的会话 HttpSessionListener
sessionCreated sessionDestroyed

每次请求到的时候你都想知道以便建立日志记录 ServletRequestListener
requestInitalized requestDestroyed

你想知道什么时候增加删除或者替换一个属性 ServletRequestAttributeListener
attributeAdded attributeRemoved attributeReplaced

你有个属性类 这个类型的对象绑定到一个会话或从会话删除时得到通知 HttpSessionBindingListener
valueBound valueUnbound

你想知道什么时候增加删除或替换一个会话属性 HttpSessionAttributeListener
attributeAdded attributeRemoved attributeReplaced

你想知道是否创建或撤销了一个上下文 ServletContextListener
contextInitialized contextDestroyed

你有一个属性表 而且希望此类对象绑定的会话迁移到另一个JVM时得到通知 HttpSessionActivationListener sessionDidActvie sessionWillPassivate

到底什么是属性
属性就是一个对象
设置(也称为绑定)到另外三个servlet API对象中---ServletContext HttpServletRequest(这个放到请求中以便
JSP/view能看到这个值)或者HttpSession 可以简单吧它认为是一个映射实例对象中的名/值对
(String/Object) 我们关心的只是属性所在的作用域 换句话说我们关心谁能看到这个属性以及属性能存活
多久

属性就像钉到公告栏上的一个对象 有人在公告栏上贴公告 以便其他人看到
这里有一个关键的问题:谁能访问公告栏 公告栏能存在多久 换句话说 属性的作用域是什么
属性不是参数
属性的设置方法是setAttribute(String name, Object value) 返回类型是Object 获取方法是
Object getAttribute(String name)
参数的是在DD中设置 返回String 获取方式是String getInitParameter(String name)

三个作用域 上下文 请求和会话
上下文属性(Context) 应用中的每一个部分都可以访问
会话属性(HttpSession) 能访问特定HttpSession的部分才能访问
请求属性(Request) 能访问特定ServletRequest的部分才能访问

上下文作用域不是线程安全的 应用中的每一部分都可以访问上下文属性
这意味着有多个servlet 多个servlet则说明你有多个线程 请求是并发处理的 每个请求在一个单独的线程
中处理 不论这些请求针对的是同一个servlet还是不同的servlet 但是servlet实例只会有一个 但可以有多个线程

时间: 2024-08-09 02:19:43

Servlet Learner03的相关文章

Description Resource Path Location Type The superclass &quot;javax.servlet.http.HttpServlet&quot; was not foun

一段时间没亲自建新项目玩乐,今天建立了一Maven project的时候发现了以下异常,Description Resource Path Location Type The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path index.jsp /easyBuy/src/main/webapp line 1 JSP Problem 经过查找原因,原来是因为忘记设置server

Spring Cloud ZooKeeper集成Feign的坑2,服务调用了一次后第二次调用就变成了500,错误:Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.n

错误如下: 2017-09-19 15:05:24.659 INFO 9986 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.spring[email protected]56528192: startup date [Tue Sep 19 15:05:24 CST 2017]; root of context hierarchy 2017-09-19 15:05:24.858 INFO 9986 --

Java web之servlet

入坑必备之servlet(O(∩_∩)O哈!) 两个问题:是什么?怎么用? the first question:what?       Servlet是sun公司提供的一门用于开发动态web资源的技术,sun公司在其API中提供了一个servlet接口.由此可以理解为原生的servlet是一个接口,提到接口,我们应该想道我们必须去实现它才能被我们使用,servlet这个接口当然也不例外,从概念上讲,servlet是指sun公司提供的这个API接口,约定俗称,现在我们说的servlet是指实现这

JavaWeb之Java Servlet完全教程(转)

Servlet 是一些遵从Java Servlet API的Java类,这些Java类可以响应请求.尽管Servlet可以响应任意类型的请求,但是它们使用最广泛的是响应web方面的请求. Servlet必须部署在Java servlet容器才能使用.虽然很多开发者都使用Java Server Pages(JSP)和Java Server Faces(JSF)等Servlet框架,但是这些技术都要在幕后通过Servlet容器把页面编译为Java Servlet.也就是说,了解Java Servle

servlet理解

一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤: 1.编写一个Java类,实现servlet接口. 2.把开发好的Java类部署到web服务器中. 按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet 二.Servlet的运行过程 Servlet程序是由WEB

web.xml 中的listener、filter、servlet加载及一些配置

在项目中总会遇到一些关于加载的优先级问题,近期也同样遇到过类似的,所以自己查找资料总结了下,下面有些是转载其他人的,毕竟人家写的不错,自己也就不重复造轮子了,只是略加点了自己的修饰. 首先可以肯定的是,加载顺序与它们在 web.xml 文件中的先后顺序无关.即不会因为 filter 写在 listener 的前面而会先加载 filter.最终得出的结论是:listener -> filter -> servlet 同时还存在着这样一种配置节:context-param,它用于向 Servlet

Servlet简介与生命周期

转载请注明原文地址: 一:Servlet是什么 Servlet是运行在Web服务器上的Java程序,作为处理来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层.JSP在web服务器上要先转换成servlet,然后才能在JVM运行,并把结果拼接成浏览器可识别的文件(如html)传回浏览器显示. 二:Servlet的应用场景 单纯地对客户端的请求做处理时,如果我们用纯JSP文件(即:只有Java语句)来处理的话,还需要先转换为servlet才能运行

Java—Servlet开发

掌握Servlet API是Java Web的基础. 首先新建一个Web类型的工程,然后再创建Servlet类.而且Servlet类名,要以Servlet作为后缀.--Servlet技术,就在Servlet类中. 然后要运行Servlet,就需要一个容器(JSP也需要),如开源的Tomcat. Tomcat的配置: 下载:

Servlet的生命周期

Servlet的生命周期是由Servlet的容器来控制的,它可以分为三个阶段:初始化.运行.销毁1.初始化阶段:(1)Servlet容器加载Servlet类,把Servlet类的.class文件中数据读到内存中:(2)然后Servlet容器创建一个ServletConfig对象.ServletConfig对象包含了Servlet的初始化配置信息:(3)Servlet容器创建一个Servlet对象:(4)Servlet容器调用Servlet对象的init方法进行初始化.2.运行阶段当Servlet