一、体系结构
我们通过一张图来了解一下 Servlet 的体系结构:
可以看到,抽象类GenericServlet
实现了 Servlet 接口,而抽象类HttpServlet
则继承了抽象类GenericServlet
,下面我们将对这两个类进行详细介绍。
1、GenericServlet
GenericServlet
类将 Servlet 接口中的其他方法做了默认空实现,只将 service 方法作为抽象方法。我们在自定义 Servlet 类时,可以继承GenericServlet
类,实现其中的 service 方法即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package cn.frankfang.servlet;
import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException;
public class ServletDemo extends GenericServlet { @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { } }
|
不过一般在实际应用中并不是继承GenericServlet
类,而是继承它的子类HttpServlet
,下面我们将对HttpServlet
类进行详细介绍。
2、HttpServlet
抽象类HttpServlet
继承了抽象类GenericServlet
,复写了 service 方法且根据请求方式添加了doGet
、doPost
等方法并进行了默认实现。因此当自定义的 Servlet 继承HttpServlet
之后,只需根据需求来复习doGet
、doPost
方法即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package cn.frankfang.servlet;
import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;
public class ServletDemo4 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
|
二、ServletContext
1、基本概念
代表整个Web应用,可以和Web容器(如Tomcat)来通信。
2、获取方式
(1)通过request对象获取
1 2 3 4 5
| @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context1 = req.getServletContext(); }
|
(2)通过HttpServlet来获取
1 2 3 4 5
| @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context2 = this.getServletContext(); }
|
3、功能
(1)获取MIME类型
MIME类型:在互联网通信过程中定义的一种文件数据类型,若需获取更多关于MIME的内容,请参阅:W3school - MIME 参考手册。
下面将举例说明如何通过 ServletContext 获取MIME类型:
1 2 3 4 5 6 7 8 9
| @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String mimeType = context.getMimeType("a.jpg"); System.out.println(mimeType); }
|
当该方法被调用之后,控制台会打印出image/jpeg
。
(2)共享数据
ServletContext 对象范围包括所有用户所有请求的数据,因此我们可以通过 ServletContext来共享数据,下面我们将举例说明如何通过 ServletContext 来共享数据。
首先在其中一个 HttpServlet 的子类中添加以下内容:
1 2 3 4
| ServletContext context = this.getServletContext();
context.setAttribute("msg", "hello");
|
之后在另一个 HttpServlet 的子类中添加以下内容:
1 2 3 4 5 6
| ServletContext context = this.getServletContext();
Object msg = context.getAttribute("msg");
System.out.println(msg);
|
启动服务器,首先访问第一个 Servlet,之后再访问第二个 Servlet,此时就可在控制台中看到打印出来的共享数据。
(3)获取文件的真实(服务器)路径
ServletContext 除了能获取MIME类型和共享数据之外,还可以获取文件的真实路径。下面将通过举例来说明如何使用 ServletContext 来获取文件的真实路径:
1 2 3 4 5 6
| String realPath = context1.getRealPath("/a.txt"); String realPath1 = context1.getRealPath("/WEB-INF/b.txt"); String realPath2 = context1.getRealPath("/WEB-INF/classes/c.txt");
System.out.println(realPath);
|
启动服务器,当该 Servlet 被访问时即可在控制台中看到文件的真实路径,尤其要注意/WEB-INF
目录下和/src
路径下的资源访问方式。