随着 Web 应用业务需求的增多,动态 Web 资源的开发变得越来越重要。目前,很多公司都 提供了开发动态 Web 资源的相关技术,其中比较常见的有 ASP、PHP、JSP 和 Servlet 等。 基于 Java 的动态 Web 资源开发,Sun 公司提供了 Servlet 和 JSP 两种技术接下来,接下来我 们将学习 Servlet 的使用
针对 Servlet 技术的开发,Sun 公司提供了一系列接口和类,其中最重要的是 javax.servlet. Servlet 接口,Servlet 就是一种实现了 Servlet 接口的类,它是由 Web 容器负责创建并调用, 用于接收和响应用户的请求。在 Servlet 接口中定义了 5 个抽象方法,具体如下:
void&emspinit(ServletConfigconfig) 创建好 Servlet 对象后,会调用此方法,负责 Servlet 初始化工作
ServletConfig&emspgetServletConfig() 获取 ServletConfig 对象 StringgetServletInfo() 返回 Servlet 的信息
void&emspservice() 当容器接收到客户端的请求时,就会调用此 方法,在该方法里,可以使用 ServletRequest、 ServletResponse,对象处理请求和响应
void&emspdestroy() Servlet 对象被销毁时,此方法会被调用
编写一个类,实现 Servlet 接口,重写 5 个方法。并在 service() 方法里面添加输出
- 控制台:System.out.println(“123478”);
- 浏览器:response.getWriter().write(“12345678”);
public class MyServlet implements Servlet {
@Override
public void service(ServletRequest request, ServletResponse response ) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().write("123487");
System.out.println("12345678");
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
}
在 WebContent->WEB-INF,web.xml 文件下添加配置信息
访问的路径为:localhost:8080/项目名/servlet 名字(url-patten 节点配置的名字)
如上面的示例,路径为:http://localhost:8080/ServletQuickExperience/myservlet
在 Java 中,任何对象都有生命周期,Servlet 也不例外
Servlet生命周期图
阶段一:初始化阶段
Servlet 接收到请求后,会先检查内存中是否有该 Servlet 对象,如果有直接使用该 对象,如果没有就创建实例,后调用 init()方法,需要注意,在 Servlet 的整个生命周期 内,它的 init() 方法只会调用一次。
阶段二:运行阶段 Servlet 生命周期中最主要的阶段,该阶段会为这个请求创建
ServletRequest
对象和ServletResponse
对象,然后传递给 service()方法,在整个 Servlet 生命周期内,每一次 访问请求,都会创建新的ServletRequest
和ServletResponse
对象。并且调用 service()方 法
阶段三:销毁阶段
Servlet 随着 Web 应用的销毁而销毁,在销毁 Servlet 之前,Servlet 的 destroy() 方 法会被调用,在该方法里面可以进行资源释放操作,destroy()只会被调用一次,需要注 意的是 Servlet 对象一旦被创建就会驻留在内存中,直到服务器关闭。
public class MyServlet implements Servlet {
/*
* service 调用几次?
* 有一次请求,调用一次 service 方法
*/
@Override
public void service(ServletRequest request, ServletResponse response ) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().write("123487");
System.out.println("12345678");
}
/*
* Servlet 实例什么时候被销毁?
* 服务器关闭,手动移除。
* destroy 调用几次
* 一次
*/
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("destory...");
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
/*
* Servlet 实例被创建后,调用 init 方法进行初始化
* Servlet 什么时候被创建呢?
* 不是服务器一启动时,实例被创建,第一次访问的时候,实例才被创建。
* init 方法调用几次呢?
* 只被调用一次。
*/
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
System.out.println("init...");
}
}
由于大多数 Web 应用都是通过 HTTP 和客户端进行交互,因此,在 Servlet 接口中,提供了 一个抽象类 javax.servlet.http.HttpServlet,它是 GenericServlet 的子类,专门用于创建应用 于 HTTP 的 Servlet
抽象类,专门用于处理 HTTP 请求的 Servlet
- 主要功能
1. 根据用户请求方式不同,定义相应的 doXxx()方法处理用户请求。
2. 通 过 service() 方 法 将 HTTP 请 求 和 响 应 分 别 转 为 HttpServletRequest 和 HttpServletResponse 类型的对象
使用步骤
示例:
编写一个类,继承 HttpServlet 类,演示 doGet 和 doPost 方法调用时机
public class MyHttpServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append(“Served at: doget”).append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append(“Served at: dopost”).append(request.getContextPath());
}
}
MyHttpServlet
MyHttpServlet
com.guo.srevlet.MyHttpServlet
MyHttpServlet
/myhttpservlet
有时候我们希望某些 Servlet 可以在 Tomcat 启动时随即启动, 可以通过使用 来完成
元素是的一个子元素,用于指定 Servlet 被加载的时机和顺序。
HelloServlet
com.guo.srevlet.HelloServlet
1
我们希望每个目录下的所有路径都可以访问同一个 Servlet,这时,可以在 Servlet 映射的路 径中使用通配符“*”
- 通配符的格式分为
格式为“ .扩展名 ”,例如“ .c ”匹配以“ .c ”结尾的所有 URL 地址
格式为“ /* ”,例如 “ /abc/* ”匹配以“ /abc ”开始的所有 URL 地址
有如下映射关系
Servlet1 映射到 /abc/*
Servlet2 映射到 /*
Servlet3 映射到 /abc
Servlet4 映射到 *.do
当请求 URL 为/abc/a.html
,“/abc/”和“/”都匹配,Servlet1 响应
当请求 URL 为/abc
时,“/abc/*”和“/abc”都匹配,Servlet3 响应
当请求 URL 为/abc/a.do
时,“/abc/”和“.do”都匹配,Servlet1 响应
当请求 URL 为/a.do
时,“/”和“.do”都匹配,Servlet2 响应
当请求 URL 为/xxx/yyy/a.do
时,“/”和“.do”都匹配,Servlet2 响应
如果每个 Servlet 的映射路径仅仅是一个正斜线(/),那么这个 Servlet 就是当前 Web 应用 的默认 Servlet,默认 Servlet 用于处理其它 Servlet 都不处理的访问请求。
- 如下配置,Servlet 服务器在接收访问请求时,如果再 web.xml 文件中找不到匹配的 元素的 URL,就会将访问请求交给默认 Servlet 处理
DefaultServlet
com.guo.srevlet.DefaultServlet
DefaultServlet
/
Servlet 的多重映射指的是同一个 Servlet 可以被映射成多个虚拟路径。也就是说客户端可以 通过多个路径实现对同一个 Servlet 的访问。配置方式有两种
如下代码,HttpServletDemo 被映射到两个路径中,分别为:httpservletdemo1、 httpservletdemo2
HttpServletDemo
/httpservletdemo1
HttpServletDemo
/httpservletdemo2
HttpServletDemo
/httpservletdemo1
/httpservletdemo2