Servlet
实现 Servlet 规范
该类必须实现 Servlet 规范,即继承 HttpServlet 类(这个类需要jar包支持,这个jar包在哪里?在tomcatl-ib下的servlet-api.jar中),后续只需要进行业务的实现即可。
package com.study.testservlet;
public class Servlet01 extends HttpServlet {
}
重写 service 方法
满足 Servlet 规范只是让我们的类能够满足接收请求的要求,接收到请求后需要对请求进行分析,以及进行业务逻辑处理,计算出结果,则需要添加代码,在规范中有一个叫做 service的方法,专门用来做请求处理的操作,我们要重写service方法,业务代码则可以写在该方法中。
package com.study.testservlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 控制台打印一句话
System.out.println("hi servlet");
// 响应一句话给浏览器
resp.getWriter().write("hi servlet");
}
}
设置注解
在完成好了一切代码的编写后,还需要向服务器说明,特定请求对应特定资源。
开发servlet项目,使用@WebServlet将一个继承于javax.servlet.http.HttpServlet 的类定义为Servlet组件。在Servlet3.0中 , 可以使用@WebServlet注解将一个继承于javax.servlet.http.HttpServlet的类标注为可以处理用户请求的 Servlet。
package com.study.testservlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/s01")
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 控制台打印一句话
System.out.println("hi servlet");
// 响应一句话给浏览器
resp.getWriter().write("hi servlet");
}
}
还可以用其它写法配置 Servlet:
@WebServlet(name="Servlet01",value="/ser01")
@WebServlet(name="Servlet01",urlPatterns = "/ser01")
也可以配置多个访问路径
@WebServlet(name="Servlet01",value={"/ser01",'/ser001'})
@WebServlet(name="Servlet01",urlPatterns={"/ser01",'/ser001'})
Servlet的其它实现方式
方式1:extends HttpServlet 类
方式2:extends GenericServlet抽象类
方式1代码:
package com.study.testservlet;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/s01")
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 控制台打印一句话
System.out.println("hi servlet");
// 响应一句话给浏览器
resp.getWriter().write("hi servlet");
}
}
方式2代码:
package com.study.testservlet;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/s02")
public class Servlet02 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet02...");
}
}
方式3代码:
package com.study.testservlet;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/s03")
public class Servlet03 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet03...");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
启动服务器,依次访问Servlet测试即可。
Servlet中方法的其它实现方式:
父类HttpServlet的service方法中会对请求做分发处理:
所以子类 Servlet01中可以不用重写service方法,直接写doGet和doPost方法,被父类的service方法调用即可:(不推荐)
package com.study.testservlet;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/s01")
public class Servlet01 extends HttpServlet {
//@Override
/*protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 控制台打印一句话
System.out.println("hi servlet");
// 响应一句话给浏览器
resp.getWriter().write("hi servlet");
}*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("get...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//System.out.println("post....");
this.doGet(req,resp);//无论get请求和post请求都会走同一套业务逻辑。
}
}
方式3:implements Servlet接口
用的最多:方式1
Servlet的生命周期
Servlet没有 main()方法,不能独立运行,它的运行完全由 Servlet 引擎来控制和调度。 所谓生命周期,指的是 servlet 容器何时创建 servlet 实例、何时调用其方法进行请求的处理、 何时并销毁其实例的整个过程。
-
实例和初始化时机
当请求到达容器时,容器查找该 servlet 对象是否存在,如果不存在,则会创建实例(通过反射)并进行初始化。
-
就绪/调用/服务阶段
有请求到达容器,容器调用 servlet 对象的 service()方法,处理请求的方法在整个生命周期中可以被多次调用; HttpServlet 的 service()方法,会依据请求方式来调用 doGet()或者 doPost()方法。但是, 这两个 do 方法默认情况下,会抛出异常,需要子类去 override。
-
销毁时机
当容器关闭时(应用程序停止时),会将程序中的 Servlet 实例进行销毁。
上述的生命周期可以通过 Servlet 中的生命周期方法来观察。在 Servlet 中有三个生命周 期方法,不由用户手动调用,而是在特定的时机有容器自动调用,观察这三个生命周期方法 即可观察到 Servlet 的生命周期。
测试:定义一个Servlet,继承HttpServlet后重写如下三个方法:
init 初始化方法,在 Servlet 实例创建之后执行(证明该 Servlet 有实例创建了),系统方法服务器自动调用。
public void init(ServletConfig config) throws ServletException {
System.out.println("实例创建了...");
}
service 就绪/调用/服务方法,每次有请求到达某个 Servlet 方法时执行,用来处理请求(证明该Servlet 进行服务了),系统方法服务器自动调用。
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("服务调用了...");
}
destroy 销毁方法,Servlet 实例销毁时执行(证明该 Servlet 的实例被销毁了),系统方法服务器自动调用。
public void destroy() {
System.out.println("实例销毁了...");
}
除了上述三个方法外,再加入Servlet的构造方法,即可看到创建对象时机:
public Servlet04() {
System.out.println("构造方法调用...");
}
完整代码:
package com.study.testservlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/s05")
public class Servlet05 extends HttpServlet {
public Servlet05(){
System.out.println("构造器被调用了");
}
@Override
public void init() throws ServletException {
System.out.println("Servlet-init");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("处理业务 ");
}
@Override
public void destroy() {
System.out.println("Servlet对象被销毁");
}
}
Servlet 的生命周期:
-
Web Client 向 Servlet 容器(Tomcat)发出 Http 请求
-
Servlet 容器接收 Web Client 的请求
-
根据反射构建Servlet对象(第一次请求会构建,之后不会重复创建对象,直到服务器关闭才会被销毁)
-
会构建HttpServletRequest 实现类对象、HttpServletResponse 实现类对象 ,处理请求和响应
-
Servlet 容器调Servlet 对象的service 方法,把HttpServletRequest 实现类对象 与 HttpServletResponse 实现类对象 作为service的参数,供给方法内部使用
-
Servlet 对象调用 HttpServletRequest 实现类对象的有关方法,获取 Http 请求信息
-
Servlet 对象调用 HttpServletResponse实现类 对象的有关方法,生成响应数据
-
Servlet 容器把 Servlet对象 的响应结果传给 Web Client
评论区