Servlet的实现和相关的方法 |
---|
一、关于servlet
servlet 是运行在 Web 服务器中的小型 Java 程序。
servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
要实现此接口,可以编写一个扩展 javax.servlet.GenericServlet 的一般 servlet,
或者编写一个扩展 javax.servlet.http.HttpServlet 的 HTTP servlet。
此接口定义了初始化 servlet 的方法、为请求提供服务的方法和从服务器移除 servlet 的方法。
这些方法称为生命周期方法,它们是按以下顺序调用的:
1. 构造 servlet,然后使用 init 方法将其初始化。
2. 处理来自客户端的对 service 方法的所有调用。
3. 从服务中取出 servlet,然后使用 destroy 方法销毁它,最后进行垃圾回收并终止它。
(二)如果创建工程没默认自动配置servlet 的xml 则手动配置如下:
图1
(三)servlet的生命周期
servlet的生命周期。
什么时候创建一个servlet?
什么时候去销毁一个servlet?
Servlet的生命周期
1.先调用 Servlet的构造方法
2.调用 init 方法 初始化Servlet
3.调用 Servlet中的service方法 处理请求操作
4.调用 destory方法 执行Servlet销毁的操作
《1》init方法:当服务器创建一个serlvet的时候,会去调用init方法。
当我们第一次去访问一个servlet的时候,会去创建这个servlet对象。并且只会创建一次。
《2》Dopost 或 doget 方法 则每访问一次就会执行一次
《3》destory 在关闭服务器的时候被注销 此servlet资源将被释放
eclipse自动创建servlet时注意其访问的url
图2
《4》、Servlet类的继承体系:
图3
二、与Servlet相对于的 几个核心对象和类
(1)、ServletConfig类(一个Servlet对应一个config对象)
ServletConfig类,见名知义。它是Servlet类的配置文件类。封装了Servlet的配置文件的信息。
它常用的功能有三个。
1.获取Servlet在web.xml文件中配置的Servlet名称
(也就是servlet-name的值<servlet-name>ConfigServlet</servlet-name>)。
2.获取Servlet初始化信息。(web.xml文件中<Servlet>标签中 <init-param>的初始化信息 )
3.获取ServletContext域对象
String servlet_name = config.getServletName();
String param_value = config.getInitParameter("username");
ServletContext context = config.getServletContext();
2) web.xml文件中的配置信息:
<servlet>
<servlet-name>ConfigServlet</servlet-name>
<servlet-class>com.atguigu.servlet.ConfigServlet</servlet-class>
<!-- 给servlet添加初始化参数 -->
<init-param>
<!-- param-name 是初始化参数的名 -->
<param-name>username</param-name>
<!-- param-value 是初始化参数的值 -->
<param-value>root</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ConfigServlet</servlet-name>
<url-pattern>/configServlet</url-pattern>
</servlet-mapping>
★★★
注意事项:
当我们继承HttpServlet类实现Servlet程序的时候,
重写Servlet中的init方法,
我们要在方法内第一行调用super.init(config),
否则会在其他调用getServletConfig方法或者getServletContext方法的时候抛空指针异常
(2)、servletContext说明(ServletContext对应一个Web工程
★★☆
当Tomcat启动的时候,有多少个动态web工程,就会创建多少个ServletContext。
一个动态web工程,对应一个ServletContext。
那么一个动态web工程中,所有的Servlet都可以共享一个ServletContext对象。
什么是ServletContext?
第一:ServletContext是一个接口。
第二:ServletContext是一个域对象! 就是存储数据的范围。
它的范围是整个工程共享。
第三:每个Web工程,都对应一个ServletContext对象!
ServletContext有什么作用?
第一:ServletContext可以获取web.xml文件中的配置上下文参数,
是整个工程的上下文参数。(不是Servlet中的init-param参数)
第二:ServletContext可以获取web工程在服务器的工程名
第三:ServletContext可以获取web工程中文件夹或文件在服务器硬盘上的绝对路径(经常用来和上传和下载一起使用)
第四:ServletContext可以设置web工程的全局属性
1) Servlet中的示例代码:
public class ContextServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 获取ServletConfig对象
ServletConfig config = getServletConfig();
// 获取Servlet的上下文对象
ServletContext context = config.getServletContext();
// 获取web.xml文件中配置的参数的值
// 正确。ServletContext只能获取context-param配置的参数
String passwordValue = context.getInitParameter("password");
System.out.println("获取context-param参数:" + passwordValue);
// ServletContext无法获取Servlet中配置的init-param参数
String usernameValue = context.getInitParameter("username");
System.out.println("获取servlet配置的init-param参数:" + usernameValue);
}
2) web.xml中的配置信息
<!-- 配置由ServletContext获取的参数 -->
<context-param>
<!-- 配置参数的名 -->
<param-name>password</param-name>
<!-- 配置参数的值 -->
<param-value>root</param-value>
</context-param>
<servlet>
<!-- 配置Servlet中的别名 -->
<servlet-name>ContextServlet</servlet-name>
<!-- 配置Servlet的全类名 -->
<servlet-class>com.atguigu.servlet.ContextServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 配置Servlet的别名 -->
<servlet-name>ContextServlet</servlet-name>
<!-- 配置Servlet的访问路径 -->
<url-pattern>/contextServlet</url-pattern>
</servlet-mapping>
3)ServletContext对象获取布署后的工程名
图4
4)、ServletContext获取工程目录或文件在服务器硬盘上的绝对路径
// 获取ServletConfig对象
ServletConfig config = getServletConfig();
// 获取Servlet的上下文对象
ServletContext context = config.getServletContext();
//获取/表示的路径表示从http://127.0.0.1:8080/工程名/ 所表示的硬盘绝对路径
// /也就是WebContent下的内容
String path = context.getRealPath("/");
System.out.println("/的硬盘路径:" + path);
//获取/imgs表示的路径
// /imgs也就是表示WebContent目录下的imgs目录,发布后的硬盘绝对路径。
String imgspath = context.getRealPath("/imgs");
System.out.println("/imgs的硬盘路径:" + imgspath);
//获取/imgs表示的路径
// /imgs也就是表示WebContent目录下的imgs目录里wrong.png文件,发布后的硬盘绝对路径。
String wrongpath = context.getRealPath("/imgs/wrong.png");
System.out.println("/imgs/wrong.png的硬盘路径:" + wrongpath);
5)ServletContext设置全局共享属性
我们可以创建两个Servlet程序。分别是:ContextAttrServlet1和ContextAttrServlet2.
a) 在ContextAttrServlet1 中直接通过ServletContext获取一个没有设置的属性值。
b) 然后在ContextAttrServlet2 中,通过ServletContext设置一个全局的属性值。
c) 然后通过不同的访问顺序测试ServletContext对象管理的全局共享属性。
代码:
ContextAttrServlet1的代码:
图5
ContextAttrServlet1的配置信息:
<servlet>
<description></description>
<display-name>ContextAttrServlet1</display-name>
<servlet-name>ContextAttrServlet1</servlet-name>
<servlet-class>com.atguigu.servlet.ContextAttrServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextAttrServlet1</servlet-name>
<url-pattern>/contextAttrServlet1</url-pattern>
</servlet-mapping>
ContextAttrServlet2的代码
图6
ContextAttrServlet2的配置信息
<servlet>
<description></description>
<display-name>ContextAttrServlet2</display-name>
<servlet-name>ContextAttrServlet2</servlet-name>
<servlet-class>com.atguigu.servlet.ContextAttrServlet2</servlet-class>
ContextAttrServlet2
/contextAttrServlet2
6) 访问测试过程:
1.先访问http://127.0.0.1:8080/day07/contextAttrServlet1 查看全 局的username属性,因为还没设置,所以获取是null
2.然后访问http://127.0.0.1:8080/day07/contextAttrServlet2 设置全局的username属性值。
3.最后再访问http://127.0.0.1:8080/day07/contextAttrServlet1 由于 contextAttrServlet2中已经设置了属性值,这时候再访问可以获取到值。
控制台打印信息:
图7