web学习二——Servlet

  1. Servlet

Sun在 其api 中定义了servlet 接口,不要去到 jdk 中找, 而要去 javaee的api 找。
Servlet是sun公司提供的一门用于开发动态web资源的技术。
servlet 基于request - response 请求模型 (http协议)
Sun公司在其API中提供了一个servlet接口,用户若想开发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
编写一个Java类,实现servlet接口。
把开发好的Java类部署到web服务器中。
4.1 快速入门(编写servlet步骤)

  1. 继承 javax.servlet.http.HttpServlet
  2. 覆盖doGet、doPost
  3. web.xml配置Servlet的虚拟路径
    这里写图片描述
  4. 启动服务器, 发布web应用,去访问http://localhost:8080/day08_servlet/hello
    web.xml配置Servlet访问虚拟路径:
    这里写图片描述
    GET方式请求提交映射关系:
    这里写图片描述

4.2 为什么要去继承HttpSerlvet

这里写图片描述

4.3 servlet的生命周期

servlet的生命周期方法执行顺序:
Init : 第一次访问, 创建serlvet的时候会执行, 用来 初始化 serlvet
Service: 每次 请求的时候, 都会执行
Destroy: 当servlet销毁, 不再服务客户端请求的时候销毁
小结: 一个servlet第一次被访问的时候,会创建出来,调用init 初始化,然后这个servlet类的一个实例对象就驻留在内存中,后续再去访问这个servlet的时候, 就会拿 内存中servlet实例来响应请求. 直至 服务器 停止…

  • Servlet是一个供其他Java程序(Servlet引擎,服务器)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。
  • 针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。
  • 在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。

4.4 自定义的servlet 的doGet,doPost方法是如何被调用到的

Servlet程序不是 咱们自己调用的, 是服务器调用的.
Servlet在每次访问的时候都会调用service方法, 但是 我们在访问自定义的sevlet的时候, 发现没有service方法, 只写了doGet和doPost, 但是 这个doGet ,doPost方法在每次请求的时候 也都相应的执行了. 那么这里的 doGet,doPost方法是如何被调用到的呢?
这里写图片描述
生命周期的service方法, 调用了 httpservlet 自定义的那个 service方法, 而自定义的service 方法中,又 根据当前的请求方式, 调用 了具体的doXxx方法
原来, doGet,doPost方法 实际上还是 通过调用了生命周期的service , 再根据请求方式 调用过来的.
4.5 覆盖servlet时,几个注意点

第一个:
覆盖init方法时, 不要覆盖 有参数的 init方法
这里写图片描述
这里写图片描述
第二个:
根据Http请求的方式,覆盖相应的doGet或者doPost方法,无需覆盖Service方法
第三个:
当doGet和doPost代码逻辑相同时,可以相互调用,简化编程
观察 doGet和doPost,两个方法 接收的参数 是一模一样的, 只是 方法名字不一样.
那么 如果在开发过程中. doGet和doPost里的代码逻辑完全一致, 那么 就可以在 其中一方调用下 对方,这样可以简化编程.
4.6 映射servlet的对外访问路径

通过 url-pattern 来实现映射.
这里写图片描述
这个 路径有三种写法:
第一种:
绝对路径 匹配, 必须要以 / 开始 -------- 例如: /aaa/bbb
第二种:
目录匹配, 必须要以 / 开始, 以 * 结束 ----- 例如: /mmm/nnn/* , /aaa/bbb/*
第三种:
扩展名匹配, 必须要以 * 开始. 扩展名结束 ---- 例如: *.do , .xxx
当出现 多个servlet 都对访问 的目标路径都 匹配时, 那么 会有优先级顺序.
http://localhost/day08/aaa/bbb
优先级顺序: 第一种> 第二种> 第三种
经典的错误:  /
.do —
这里写图片描述
4.7 Servlet的启动配置

默认的情况下, 一个serlvet类 只有在访问的时候才会创建实例. 然后驻留在内存中
但是 实现上, 对与一些 servlet ,如果 这个servlet 要完成一些特殊功能, 比方说 读取web工程中比较大的资源配置 文件,
那么在这种场景下, 你可能就需要在 web应用一启动的时候 就去 启动的serlvet, 实例化, 去读取 大的资源配置文件.
就需要将 servlet 配置为 web应用启动时就加载 .
这里写图片描述
4.8 ServletConfig对象

ServletConfig---- 代表 着 一次请求的时候, 关于servlet的 配置信息. 这个对象中封装的就是 针对于 某个具体的servlet的 启动配置信息…
Serlvet生命周期方法中 :
这里写图片描述
这个对象是服务器 在调用init 方法时 ,传递进来的.
在web.xml文件中,你 注册 serlvet的时候, 是可以通过 init-param 来 配置 servlet的具体的参数信息的.
这里写图片描述
Tomcat服务器 会将 这些参数信息封装到一个叫做 serlvetConfig的对象中,并且将这个对象在 调用 init方法的时候传递进来 . 那么你就可以拿到 对这个对象的引用.
这里写图片描述
注意点 : 每个serlvet的都有其独占的 servletConfig对象, 用来封装各自的初始化参数 信息.
例如: A serlvet的配置, 是不能 够通过 B servlet的 serlvetConfig 来获得的.
4.9 使用servletContext对象

ServletContext对象就代表着 一个web应用, 那么只要拿到一个SerlvetContext对象, 就 代表着一个web应用…
每个web应用,都有 与其相对应的唯一的servletContext对象.

  • 常识 :
    Context — 上下文 , 贯穿始终的 玩意 … 一般就是一个工具类 . 可以让你去获得 一些 文件, 配置信息, 读取一些资源等等功能.
    ServletContext – 代表着web应用
    Context — 代表着 你的那个 app
    4.9.1 获得全局的配置信息

在web.xml文件中, 可以配置web应用的全局的初始化参数信息.
这里写图片描述

  • 如何获得对servletContext对象的引用呢?
    在任何一个servlet中 通过 getServletContext() 方法 获得 对当前web应用的 serlvetContext的 引用
    4.9.2 实现数据共享

对于每个web应用,都有一个唯一的sevletContext对应与其 对应, 那么 如果你在servlet1 拿到了 对serlvetContext对象引用, 向 serlvetContext 存入了一些值, 然后 现在去 servlet2, 那么 也可以获得 对serlvetContext 引用,这个时候 ,那么拿到的同一个 对象, 都是代表着 当前的web应用, 由于 拿到的是 同一个对象, 那么就可以实现数据的 共享.

  • 域对象:
    1.域对象是一个容器,
    2.域对象容器就会有大小(范围)
    3.域对象都有实现数据共享的方法
    setAttribute(name,value) — String , Object
    getAttribute(name) , 返回值是 Object ---- String
    removeAttribute(name) ------- String

SerlvetContext 对象是一个域对象

类加载器 : 负责 将 classpath 路径下的 资源 文件 加载到 虚拟机中去, .class文件 一旦被加载到虚拟机中, 那么 就 完成了类加载的过程,

  • 使用serlvetContext实现统计网站的访问次数
  1. 在init 方法中 搞个计数器的初始值 是 0, 并且存到 servletContext域 中去
  2. 在doGet 方法中,取出 原有的值, 然后 +1 ,然后再 放回去 .
  3. 取出 存在 servletContext 的次数, 显示一下.
  • 使用serlvetContext去获得web应用下文件的路径

ServletContext context = getServletContext();
String realPath2 = context.getRealPath("/2.txt");
String path3 =context.getRealPath("/WEB-INF/3.txt");
String path4 = context.getRealPath("/WEB-INF/classes/4.txt");
readContent(path4);

public static void readContent(String path) {
try {
InputStream in = new FileInputStream(path);
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) > 0) {
System.out.println(new String(buf, 0, len));
}
} catch (Exception e) {
e.printStackTrace();
}
}

  • 使用 类加载器 去获得 4.txt 的 路径
    由于 4.txt 在src 目录下, 那么 这里4.txt 又 多了一种 使用 类加载器 去 获得 路径的方式

      //类加载
     Class clazz  = Class.forName("com.A");	
     	  
     // 使用这种方式 的时候 要 加 个  /  
     URL url = ReadContentServlet.class.getResource("/4.txt");	
     String realpath = url.getFile();
     readContent(realpath);
    

4.10 缺省的Servlet

  • 如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。
  • 凡是在web.xml文件中找不到匹配的元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。
  • 在<tomcat的安装目录>\conf\web.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet设置为了缺省Servlet。
  • 当访问Tomcat服务器中的某个静态HTML文件和图片时,实际上是在访问这个缺省Servlet。

当没有任何一个servlet 程序可以 响应客户端的请求时 ,默认的serlvet 就出来干活了.
你每次向服务器发送的时候, 都是由 一个serlvet 来处理你的请求的, 包括你访问的是
静态的html 页面的时候也是 由 一个servlet来响应你的请求的.
在tomcat服务器的 conf目录下的 web.xml 文件中
这里写图片描述
这里 由于 默认的servlet的 对外访问路径是 / , 那么就表示配置成了默认的serlvet . 用于响应 当找不到对应的servlet的时候, 来响应客户端的请求.
你以后在配置 serlvet的对外访问路径, 不要 将你的servlet 的对外访问路径 弄成 / , 如果弄成/ , 那么就会将你自己 写的那个servlet 弄成默认的. 那样的话, 就 看不到 之前的 访问 资源不存在的时候404, 500 等等错误友好提示信息了.

猜你喜欢

转载自blog.csdn.net/lln_lln/article/details/80722297
今日推荐