1. Servlet 核心技术
- Servlet-Api 的 maven 配置
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>compile</scope>
</dependency>
1.1 创建HelloServlet
- 创建 HelloServlet类,并继承 HttpServlet 类, 重写 Service 和 doGet 方法
package cn.knightzz.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 王天赐
* @title: HelloServlet
* @projectName lg-java-train
* @description:
* @website http://knightzz.cn/
* @github https://github.com/knightzz1998
* @date 2021/12/30 14:20
*/
public class HelloServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("begin =====> HelloServlet doGet");
super.doGet(req, resp);
System.out.println("end =====> doGet");
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("begin =====> HelloServlet ServletRequest");
super.service(req, res);
System.out.println("end =====> HelloServlet ServletRequest");
}
}
- 在 web.xml 中配置
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 配置ServletName 和 ServletClass 的映射-->
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>cn.knightzz.servlet.HelloServlet</servlet-class>
</servlet>
<!-- 配置Servlet访问地址-->
<servlet-mapping>
<!-- HelloServlet是Servlet类的别名,与上述名称必须相同 -->
<servlet-name>HelloServlet</servlet-name>
<!--在浏览器中访问的地址-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
-
运行以后 在浏览器输入 http://localhost:8080/web-servlet-01/hello 即可
-
这里需要注意的是 : web-servlet-01 是我自己 配置的 Application context 路径
-
访问 /hello 路径后 会出现如下界面
-
我们可以在控制台看到打印的数据表示实际访问到了 HelloServlet

1.2 Servlet接口
1.2.1 Servlet基本概念
1.2.2 Servlet通用方法
1.2.3 GenericServlet类
public abstract class GenericServlet
implements Servlet, ServletConfig, java.io.Serializable
-
javax.servlet.GenericServlet类主要用于定义一个通用的、与协议无关的servlet,该类实现了Servlet接口。
-
若编写通用servlet,只需重写service抽象方法即可
-
常用的方法
public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
1.3 HttpServlet类
1.3.1 基本概念
- javax.servlet.http.HttpServlet类是个抽象类并继承了GenericServlet类。
- 用于创建适用于网站的HTTP Servlet,该类的子类必须至少重写一个方法
1.3.2 常用方法
1.4 Servlet生命周期
-
构造方法只被调用一次,当第一次请求 Servlet 时调用构造方法来创建 Servlet 的实例。
-
init() 方法只被调用一次,当创建好 Servlet 实例后立即调用该方法实现 Servlet 的初始化。
-
service() 方法被多次调用,每当有请求时都会调用 service() 方法来用于请求的响应。
-
destroy() 方法只被调用一次,当该 Servlet 实例所在的 Web 应用被卸载前调用该方法来释放当前占用的资源
1.4.1 实现Servlet接口
package cn.knightzz.servlet;
import javax.servlet.*;
import java.io.IOException;
/**
* @author 王天赐
* @title: MyServlet
* @projectName lg-java-train
* @description: 直接实现Servlet接口
* @website http://knightzz.cn/
* @github https://github.com/knightzz1998
* @date 2022/1/1 20:43
*/
public class MyServlet implements Servlet {
public MyServlet() {
System.out.println("=======> MyServlet create Object");
}
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("=======> MyServlet init");
}
@Override
public ServletConfig getServletConfig() {
return this.getServletConfig();
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("=======> MyServlet service be visited");
}
@Override
public String getServletInfo() {
return this.getServletInfo();
}
@Override
public void destroy() {
System.out.println("=======> MyServlet destroy");
}
}
如下: 可以看到在启动Tomact服务器后, tomcat 容器会自动实例化 Servlet类,
- Tomact容器创建Servlet实例
- Servlet初始化
- Servlet接收请求,反复调用 service() 方法
- Tomact服务器关闭,调用 destroy() 销毁实例
=======> MyServlet create Object
=======> MyServlet init
=======> MyServlet service be visited
C:\Dev\apache-tomcat-8.5.57\bin\catalina.bat stop
Using CATALINA_BASE: "C:\Users\wangtianci\AppData\Local\JetBrains\IntelliJIdea2021.3\tomcat\21aec25b-5b21-4d35-831c-70b66daff382"
Using CATALINA_HOME: "C:\Dev\apache-tomcat-8.5.57"
Using CATALINA_TMPDIR: "C:\Dev\apache-tomcat-8.5.57\temp"
Using JRE_HOME: "C:\Dev\jdk8"
Using CLASSPATH: "C:\Dev\apache-tomcat-8.5.57\bin\bootstrap.jar;C:\Dev\apache-tomcat-8.5.57\bin\tomcat-juli.jar"
01-Jan-2022 21:42:06.996 信息 [main] org.apache.catalina.core.StandardServer.await 通过关闭端口接收到有效的关闭命令。正在停止服务器实例。
01-Jan-2022 21:42:06.996 信息 [main] org.apache.coyote.AbstractProtocol.pause 暂停ProtocolHandler["http-nio-8080"]
01-Jan-2022 21:42:07.502 信息 [main] org.apache.catalina.core.StandardService.stopInternal 正在停止服务[Catalina]
01-Jan-2022 21:42:07.515 信息 [main] org.apache.coyote.AbstractProtocol.stop 正在停止ProtocolHandler ["http-nio-8080"]
01-Jan-2022 21:42:07.517 信息 [main] org.apache.coyote.AbstractProtocol.destroy 正在摧毁协议处理器 ["http-nio-8080"]
=======> MyServlet destroy
Disconnected from server
1.5 Servlet注解写法
- 我们可以使用注解 @WebServlet(“URL”) 去简化Servlet, 这样不需要再 web.xml 中配置
- **这里需要特别注意 urlPatterns 一定要加 / **
@WebServlet(name = "MyWebServlet", urlPatterns = "/my-web-servlet")
- name 等价于
servlet-name
urlPatterns 等价于url-pattern
- name 等价于
package cn.knightzz.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;
/**
* @author 王天赐
* @title: MyWebServlet
* @projectName lg-java-train
* @description: 使用注解简化Servlet配置
* @website http://knightzz.cn/
* @github https://github.com/knightzz1998
* @date 2022/1/2 14:14
*/
@WebServlet(name = "MyWebServlet", urlPatterns = "/my-web-servlet")
public class MyWebServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("==================> MyWebServlet doGet Be Visited");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("==================> MyWebServlet doPost Be Visited");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("==================> MyWebServlet Service Be Visited");
super.service(req, resp);
}
}
- 直接访问
http://localhost:8080/web-servlet-01/my-web-servlet
即可 - 这里需要注意
service
方法作用是决定请求是由doGet
处理还是doPost
处理
1.6 POST和GET请求
1.6.1 POST请求和GET请求的基本使用
-
GET请求特点: 会将请求数据添加到请求URL地址的后面,只能提交少量的数据、不安全
-
如果需要处理POST请求则需要重写
doPost
方法
package cn.knightzz.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;
/**
* @author 王天赐
* @title: MyWebServlet
* @projectName lg-java-train
* @description: 使用注解简化Servlet配置
* @website http://knightzz.cn/
* @github https://github.com/knightzz1998
* @date 2022/1/2 14:14
*/
@WebServlet(name = "MyWebServlet", urlPatterns = "/my-web-servlet")
public class MyWebServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("==================> MyWebServlet doGet Be Visited");
// 可以直接让Get请求让Post处理
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("==================> MyWebServlet doPost Be Visited");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("==================> MyWebServlet Service Be Visited");
// 获取请求方法类型
String method = req.getMethod();
System.out.println("method = " + method);
switch (method) {
case "GET":
doGet(req, resp);
break;
case "POST":
doPost(req, resp);
break;
}
}
}
- 在
webapp
目录下面创建request.html
分别添加链接和表单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>POST和GET请求</title>
</head>
<body>
<a href="my-web-servlet">GET请求</a>
<hr/>
<form action="my-web-servlet" method="post">
<input type="submit" />
</form>
</body>
</html>
- 访问
http://localhost:8080/web-servlet-01/request.html
即可查看GET请求
和POST请求
1.6.2 ServletRequest接口
-
javax.servlet.ServletRequest
接口主要用于向servlet
提供客户端请求信息,可以从中获取到任何请求信息。 -
Servlet
容器创建一个ServletRequest
对象,并将其作为参数传递给 Servlet 的service
方法 -
常用方法
String getParameter(Stringname)
以字符串形式返回请求参数的值,如果该参数不存在,则返回值String[] getParameterValues(String name)
返回一个字符串对象数组,其中包含给定请求参数所具有的所有值,如果该参数不存在,则返回空值Enumeration getParameterNames()
返回包含此请求中包含的参数名称的字符串对象的枚举。如果请
求没有参数,则方法返回空枚举Map<String, String[]> getParameterMap()
返回请求参数的键值对,一个键可以对应多个值String getRemoteAddr()
返回发送请求的客户端或最后一个代理的IP地址int getRemotePort()
返回发送请求的客户端或最后一个代理的端口号
1.6.3 HttpServletRequest接口
-
javax.servlet.http.HttpServletRequest
接口是ServletRequest
接口的子接口,主要用于提供HTTP
请求信息的功能。 -
不同于表单数据,在发送HTTP请求时,HTTP请求头直接由浏览器设置。
-
可直接通过
HttpServletRequest
对象提供的一系列get方法获取请求头数据 -
常用方法
String getRequestURI()
返回此请求的资源路径信息StringBuffer getRequestURL()
返回此请求的完整路径信息String getMethod()
返回发出此请求的HTTP方法的名称,例如GET、POSTString getQueryString()
返回路径后面请求中附带的参数String getServletPath()
返回此请求中调用 servlet 的路径部分
-
代码演示
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("MyParams doPost ====>"); // 获取请求资源路径 System.out.println("req.getRequestURI() = " + req.getRequestURI()); // 获取请求的完整路径 System.out.println("req.getRequestURL() = " + req.getRequestURL()); // 获取HTTP请求方式 System.out.println("req.getMethod() = " + req.getMethod()); }
结果如下 :
req.getRequestURI() = /web-servlet-01/my-params req.getRequestURL() = http://localhost:8080/web-servlet-01/my-params req.getMethod() = GET
#### 1.6.4 ServletResponse接口
-
javax.servlet.ServletResponse
接口用于定义一个对象来帮助Servlet
向客户端发送响应。 -
Servlet容器创建
ServletResponse
对象,并将其作为参数传递给servlet
的service
方法。 -
常用方法
1.6.5 HttpServletResponse接口
-
javax.servlet.http.HttpServletResponse
接口继承ServletResponse
接口,以便在发送响应时提供特定于HTTP的功能。
-
常用方法
-
使用示例
@WebServlet(name = "MyResponseServlet", urlPatterns = "/response") public class MyResponseServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置响应码 resp.setContentType("text/html;charset=utf-8"); // 获取响应输出流 PrintWriter writer = resp.getWriter(); // 利用输出流输出信息 writer.println("<html><body>" + "Hello Servlet" + "</body></html>"); // 关闭流 writer.close(); } }
如下图所示, 直接在页面输出
Hello Servlet