1. Servlet
简述
Servlet
是运行在实现了 Java Servlet
规范的服务器端一个小程序,是 Java Web
的三大组件之一(Servlet
、Listener
监听器、Filter
过滤器),它属于动态资源,能够动态的根据请求的信息返回不同的响应
Servlet
是我们深入学习 SpringMVC
框架的基础
2. Servlet
接口
javax.serlvet.Servlet
接口是 Servlet
规范中最顶级的接口。此接口定义了初始化 Servlet
、为请求提供服务以及从服务器中删除 Servlet
的方法。这些方法称为 Servlet
的生命周期方法,它们按照一定顺序调用
public interface Servlet {
// servlet 容器在实例化 servlet 后调用 init 方法一次进行初始化。只有完成该方法(不抛出异常),然后servlet才能接收任何请求
public void init(ServletConfig config) throws ServletException;
/**
* 返回一个 ServletConfig 对象,该对象包含此servlet的初始化和启动参数,返回的ServletConfig对象是传递给init方法的参数对象
* 此接口的实现负责存储ServletConfig对象,以便此方法可以返回它,实现此接口的 GenericServlet 类已经执行了此操作
*/
public ServletConfig getServletConfig();
// 由 servlet容器(Web 服务器)调用,以允许servlet处理和响应请求。
// 只有在 servlet 的 init() 方法成功完成后,才能调用此方法
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
// 返回有关 servlet 的信息,如作者、版本和版权
public String getServletInfo();
/**
* 由 servlet(Web 服务器)容器调用,以指示 servlet 正在停用
* 当服务器正常关闭时会调用此方法,使servlet有机会清理正在保留的任何资源(例如, 内存、文件句柄、线程)
* 在 servlet 容器调用此方法后,它将不会再在此 servlet 上调用service方法
*/
public void destroy();
}
上面的 Servlet
实例和方法都是由 Servlet
容器(如 Tomcat
服务器)调用的,因此我们的项目不需要任何 main
方法,也不需要创建任何 Servlet
实例
3. Servlet
的生命周期和请求处理逻辑
Web
服务器接收到HTTP
请求,将请求转发给Servlet
容器- 如果
Servlet
实例还未创建,那么就创建一个Servlet
实例,然后调用Servlet
的init()
方法进行初始化(该方法只会在Servlet
第一次被载入时调用)。被创建的Servlet
实例会被保留在容器中,当后续有同样的请求到来时可以直接处理,不再需要重新创建和初始化 Servlet
容器会解析到来的HTTP
请求,调用该Servlet
实例的service()
方法,执行方法中的业务逻辑。service()
方法就是我们要重点开发的方法- 如果
Servlet
实例被销毁,那么将会由Servlet
容器执行destory()
方法,通常都是在服务器关闭时Servlet
才会销毁
4. 使用 Servlet
的方法
我们使用 Servlet
时,需要对 Servlet
进行实现。一般来说,实现方式有 3
种
- 实现
javax.servlet.Servlet
接口 - 继承
javax.servlet.GenericServlet
抽象类 - 继承
javax.servlet.http.HttpServlet
抽象类
4.1. 实现 Servlet
接口
@WebServlet("/first-servlet")
public class FirstServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) {
System.out.println("---------------");
System.out.println("servletConfig: " + servletConfig);
System.out.println("init");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("---------------");
System.out.println("getServletConfig");
return null;
}
/**
* 我们主要开发的方法
*
* @param servletRequest 请求对象
* @param servletResponse 响应对象
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
//获取请求的数据
String message = servletRequest.getParameter("xx");
//封装响应数据
servletResponse.setContentType("text/html");
// Hello
PrintWriter out = servletResponse.getWriter();
out.println("<html><body>");
out.println("<h1>" + message + "</h1>");
out.println("</body></html>");
}
@Override
public String getServletInfo() {
System.out.println("getServletInfo");
return null;
}
@Override
public void destroy() {
System.out.println("destroy");
}
}
想要成功运行 servlet
还要进行 servlet
的路径配置。这里,我们使用 servlet 3.0
开始提供的 @WebServlet
注解来配置 servlet
的路径。当然也可以使用 web.xml
来配置,但是这比较麻烦。这里的路径必须使用 “/” 开头,并且相对的是当前应用根目录
如果是配置 web.xml
,那么可以这样配置
<servlet>
<!--3、 servlet的内部名称-->
<servlet-name>firstServlt</servlet-name>
<!--4、 servlet的类全路径名-->
<servlet-class>com.example.servlet_01.FirstServlet</servlet-class>