Servlet
概述
1、JavaEE 接口 / 规范之一
2、JavaWeb 三大组件:Servlet 程序、Filter 过滤器、Listener 监听器
3、运行在服务器上的一个 Java 小程序,可以接收客户端发送过来的请求,并响应数据给客户端
实现 Servlet 程序
1、编写一个类实现 Servlet 接口(不使用)
(1)实现 service 方法,处理请求,并响应数据
(2)在 web.xml 中配置 Servlet 程序的访问地址
2、编写一个类继承 HttpServlet 类(实际开发中使用)
(1)根据业务需要,重写 doGet 或 doPost 方法
(2)在 web.xml 中配置 Servlet 程序的访问地址
3、IDEA 创建 Servlet 程序
(1)模块(Web 应用程序)-> src 目录 -> 新建 -> Servlet
(2)在 web.xml 中配置 Servlet 程序的访问地址
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 上下文参数属于整个Web工程 -->
<context-param>
<param-name>
<!-- 参数名 -->
</param-name>
<param-value>
<!-- 参数值 -->
</param-value>
</context-param>
<!-- servlet标签:配置Servlet程序 -->
<servlet>
<servlet-name>
<!-- Servlet程序的别名,一般是类名 -->
</servlet-name>
<servlet-class>
<!-- Servlet程序的全类名-->
</servlet-class>
<init-param>
<param-name>
<!-- 参数名 -->
</param-name>
<param-value>
<!-- 参数值 -->
</param-value>
</init-param>
</servlet>
<!-- servlet-mapping标签:配置Servlet程序访问地址 -->
<servlet-mapping>
<servlet-name>
<!-- 如上同 -->
</servlet-name>
<url-pattern>
<!-- /访问地址 -->
</url-pattern>
<!--
服务器解析时
/ 表示:http://ip:port/工程路径
/访问地址 表示:http://ip:port/工程路径/资源路径
-->
</servlet-mapping>
</web-app>
URL 地址定位 Servlet 程序
1、http://服务器ip地址:服务器端口号/工程路径/资源路径
(1)服务器 IP 地址、服务器端口号、工程路径唯一
(2)IP 地址定位服务器,端口号定位 Tomcat,工程路径定位访问工程
2、资源路径定位顺序
(1)<servlet-mapping></servlet-mapping> 标签中
<url-pattern><!-- /访问地址 --></url-pattern>
<servlet-name><!-- Servlet程序的别名,一般是类名 --></servlet-name>
(2)<servlet></servlet> 标签中
<servlet-name><!-- Servlet程序的别名,一般是类名 --></servlet-name>
<servlet-class><!-- Servlet程序的全类名--></servlet-class>
(3)执行 Servelt 程序代码
3、一个 <servlet></servlet> 可以对应多个 <servlet-mapping></servlet-mapping>
Servlet 生命周期
1、执行 Servlet 构造器方法 -> 执行 init 初始化方法
(1)在第一次访问,创建 Servlet 程序时,调用一次
(2)说明 Servlet 程序是单例、线程不安全
(3)加载 Servlet 类及 .class 对应的数据、创建 ServletConfig 对象、创建 Servlet 对象
2、执行 service 方法
(1)每次访问都会调用
(2)Servlet 的核心,负责响应客户的请求
(3)每当一个客户请求一个 HttpServlet 对象,该对象的 Service() 方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数
(4)在 HttpServlet 中已存在 service() 方法,默认的服务功能是调用与 HTTP 请求的方法相应的 doXxx 方法
3、执行 destroy 销毁方法
(1)在 Web 工程停止时调用
(2)仅执行一次,在服务器端停止且卸载 Servlet 时执行该方法
(3)当 Servlet 对象退出生命周期时,负责释放占用的资源
(4)一个 Servlet 在运行 service() 方法时可能会产生其他的线程,因此需要确认在调用 destroy() 方法时,这些线程已经终止或完成
初始化
1、两个方法
public void init() throws ServletException {
// NOOP by default
}
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
2、根据开发需求,在 web.xml 配置 <init-param></init-param>
get、post 请求的分发处理
1、实现 Servlet 接口
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String method = httpServletRequest.getMethod();
if ("get".equalsIgnoreCase(method)) {
System.out.println("处理get请求");
} else if ("post".equalsIgnoreCase(method)) {
System.out.println("处理post请求");
}
}
2、继承 HttpServlet 类,doGet()、doPost() 自动分发处理 get、post 请求
1、Servlet 接口
(1)javax.servlet 包下
(2)只定义 Servlet 程序的访问规范
2、GenericServlet 类
(1)javax.servlet 包下,实现 Servlet 接口
(2)有较多空实现
(3)持有一个 ServletConfig 类的引用,对 ServletConfig 的使用实现一些方法
private transient ServletConfig config;
3、HttpServlet 类
(1)javax.servlet.http 包下,继承 GenericServlet 类
(2)抽象类,实现 service() 方法,并实现了请求的分发处理
(3)doGet()、doPost() 负责抛异常,不支持 GET / POST 请求
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg = lStrings.getString("http.method_get_not_supported");
sendMethodNotAllowed(req, resp, msg);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg = lStrings.getString("http.method_post_not_supported");
sendMethodNotAllowed(req, resp, msg);
}
4、自定义 Servlet 程序
(1)继承 HttpServlet 类
(2)根据业务需要,重写 doGet()、doPost()
ServletConfig 类
1、Servlet 程序的配置信息类
2、作用
(1)获取 Servlet 程序的别名 servlet-name 的值
public String getServletName();
(2)获取 web.xml 配置中,初始化参数 init-param
public String getInitParameter(String name);
(3)获取 ServletContext 对象
public ServletContext getServletContext();
3、事项
(1)Servlet 程序、ServletConfig 对象都是由 Tomcat 负责创建
(2)Servlet 程序默认是第一次访问时创建,每个 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象
ServletContext 接口
1、表示 Servlet 上下文对象
2、一个 Web 工程,只有一个 ServletContext 对象实例
3、在 Web 工程部署启动时创建,在 Web 工程停止时销毁
4、ServletContext 对象是一个域对象
(1)域对象:像 Map 一样存取数据的对象
(2)域:存取数据的操作范围,即整个 Web 工程
(3)存储:setAttribute()、取出:getAttribute()、删除:removeAttribute()
5、获取方式:getServletContext()
(1)初始化 init() 方法中直接调用
(2)使用 Request 对象调用
(3)使用 Session 对象调用
6、作用
(1)获取 web.xml 中配置的上下文参数 context-param
public String getInitParameter(String name);
(2)获取当前的工程路径,格式:工程路径
public String getContextPath();
(3)获取工程部署后在服务器硬盘上的绝对路径
public String getRealPath(String path);
(4)像 Map 一样存取数据
public Object getAttribute(String name);
public void setAttribute(String name, Object object);
public void removeAttribute(String name);
GET 请求的 HTTP 协议内容
1、请求行
(1)请求方式:GET
(2)请求的资源路径
(3)请求协议与版本号:HTTP/1.1
2、请求头:由 key:value 组成,不同 key 表示不同意思
(1)Accept:客户端可以接收的数据类型
(2)Accept-Language:告诉服务器客户端可以接收的语言类型,如:zh_CN:中文中国、en_US:英文美国
(3)User-Agent:所使用的浏览器信息
(4)Accept-Encoding:客户端可以接收的数据编码(压缩)格式
(5)Host:表示请求的服务器 IP 和端口号
(6)Connection:告知服务器处理请求连接的方式,如:Keep-Alive:告知服务器回传数据不要马上关闭,保持一小段时间的连接、Closed:马上关闭
POST 请求的 HTTP 协议内容
1、请求行
(1)请求方式:POST
(2)请求资源路径
(3)请求协议和版本号:HTTP/1.1
2、请求头:由 key:value 组成,不同 key 表示不同意思
(1)Accept:表示客户端可以接收的数据类型
(2)Accept-Language:表示客户端可以接收的语言类型
(3)Referer:表示请求发起时,浏览器地址栏中的地址
(4)User-Agent:表示浏览器的信息
(5)Content-Type:表示发送数据的类型,如:application/x-www-form-urlencoded:表示提交的数据格式是:name=value&name=value,然后对其进行 URL 编码:把非英文内容转换为:%xxx%xxx、multipart/form-data:表示以多段的形式提交数据给服务器,以流的形式提交,用于上传
(6)Content-Lnegth:表示发送数据的长度
(7)Cache-Control:表示如何控制缓存,如:no-cache:不缓存
3、空行
4、请求体:发送给服务器的数据
区分 GET 请求、POST 请求
1、GET 请求
(1)form 标签:method=get
(2)a 标签
(3)link标签引入 CSS
(4)Script 标签引入 JavaScript 文件
(5)img 标签引入图片
(6)iframe 引入 html 页面
(7)在浏览器地址栏中输入地址,然后输入回车
2、POST 请求:form 标签:method=post
Session 会话
1、HTTP 无状态问题:服务器无法判断多个请求之间,是同一客户端,还是不同客户端
2、会话跟踪技术:客户端第一次发送请求到服务器,服务器获取 session,若获取不到,则创建新的 session,然后响应给客户端,下次客户端给服务器发请求时,附带 sessionID 到服务器,那么服务器可以区分不同客户端
3、常用 API
(1)获取当前的会话,若不存在,则创建一个新的会话
public HttpSession getSession();
(2)传入 true,与(1)相同;传入 false,获取当前会话,若不存在,则返回 null,不创建
public HttpSession getSession(boolean create);
(3)获取 sessionID
public String getId();
(4)判断当前 session 是否为新创建的
public boolean isNew();
(5)获取 session 的非激活间隔时长,默认 1800 秒
public int getMaxInactiveInterval();
(6)强制性使会话失效
public void invalidate();
(7)获取会话上一次访问时间
public long getLastAccessedTime();
(8)获取会话创建时间
public long getCreationTime();
3、保存作用域:与具体的 Session 对象对应
(1)常用 API
public Object getAttribute(String name);
public void setAttribute(String name, Object value);
public void removeAttribute(String name);
响应的 HTTP 协议格式
1、响应行
(1)响应协议:HTTP/1.1
(2)响应状态码,如:200:请求成功、302:请求重定向、404:服务器收到请求,但数据不存在(请求地址错误)、500:服务器收到请求,服务器内部错误(代码错误)
(3)响应状态描达符
2、响应头
(1)Server:表示服务器的信息
(2)Content-Type:表示响应体的数据类型
(3)Content-Length:响应体的长度
(4)Date:请求响应的时间(格林时间)
3、空行
4、响应体
MIME 类型
1、Multipurpose lnternet Mail Extensions:多功能 Internet 邮件扩充服务
2、MIME 是 HTTP 协议中数据类型
3、格式:大类型/小类型,并与某一种文件的扩展名相对应
4、常见
(1)超文本标记语言文本 .html、.htm:text/html
(2)普通文本 .txt:text/plain
(3)RTF 文本 .rtf:application/rtf
(4)GIF 图形 .gif:image/gif
(5)JPEG 图形 .jpeg、.jpg:image/jpeg
(6)au 声音文件 .au:audio/basic
(7)MIDI 音乐文件 .mid、.midi:audio/midi、audio/x-midi
(8)RealAudio 音乐文件 .ra、.ram:audio/x-pn-realaudio
(9)MPEG 文件 .mpg、.mpeg:video/mpeg
(10)AVI 文件 .avi:video/x-msvideo
(11)GZIP 文件 .gz:application/x-gzip
(12)TAR 文件 .tar:application/x-tar
HttpServletRequest 接口
1、作用:每次请求进入 Tomcat 服务器,Tomcat 服务器解析请求的 HTTP 协议信息,封装到 Request 对象,传递到 service 方法(doGet 方法、doPost 方法)中使用
(1)可以通过 HttpServletRequest 对象,获取到所有请求的信息
2、常用方法
(1)获取请求的资源路径
public String getRequestURI();
(2)获取请求的统一资源定位符(绝对路径)
public StringBuffer getRequestURL();
(3)获取客户端 IP 地址
public String getRemoteHost();
(4)获取请求头
public String getHeader(String name);
(5)获取请求的参数
public String getParameter(String name);
public String[] getParameterValues(String name);
(6)获取请求的方式
public String getMethod();
(7)设置域数据
public void setAttribute(String name, Object o);
(8)获取域数据
public Object getAttribute(String name);
(9)获取请求转发对象
public RequestDispatcher getRequestDispatcher(String path);
3、解决 POST 请求中文乱码
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
//设置请求体的字符集为UTF-8,该方法必须在获取参数前使用,才会生效
req.setCharacterEncoding("UTF-8");
}
请求转发
1、服务器收到请求后,从一次资源跳转到另一个资源的操作
2、特点
(1)浏览器地址栏没有变化
(2)一次请求
(3)共享 Request 域中的数据
(4)可以转发到 WEB-INF 目录下
(5)不可以访问工程以外的资源
3、服务器内部转发
RequestDispatcher requestDispatcher = req.getRequestDispatcher("资源路径");
requestDispatcher.forward(req,resp);
Web 中 / 的不同意义
1、在 Web 中 / 是一种绝对路径
2、浏览器解析 /,得到地址:http://ip:port/
(1)<a href="/"斜杠</a>
3、服务器解析 /,得到地址:http://ip:port/工程路径
(1)<url-pattern>/资源路径</url-pattern>
(2)servletContext.getRealPath("/")
(3)request.getRequestDispatcher("/")
4、特殊情况:response.sendRediect("/");把 / 发送给浏览器解析,得到地址:http://ip:port/
HttpServletResponse 接口
1、作用:每次请求进入 Tomcat 服务器,Tomcat 服务器解析请求的 HTTP 协议信息,封装到 Response 对象,传递到 Servlet 程序中使用
(1)可以通过 HttpServletResponse 对象,设置所有响应的信息
2、输出流
(1)getOutputStream():字节流,常用于下载,传递二进制数据
(2)getWriter():字符流,常用于回传字符串
(3)两个流同时只能使用一个,使用了字节流,就不能再使用字符流,反之亦然,否则报错
3、解决回传中文字符串乱码
(1)方案一
//设置服务器字符集为UTF-8
resp.setCharacterEncoding("UTF-8");
//通过响应头,设置浏览器字符集为UTF-8
resp.setHeader("Content-Type", "text/html;charset=UTF-8")
(2)方案二:必须在获取流对象之前使用,才生效
//同时设置服务器和客户端都使用UTF-8字符集,并设置了响应头
resp.setContentType("text/html; charset=UTF-8");
请求重定向
1、客户端给服务器发请求,因为之前的地址可能已经被废弃,然后服务器回传给客户端一个新地址,让客户端去访问这个新地址。
2、特点
(1)浏览器地址栏会发生变化
(2)两次请求
(3)不共享 Request 域中数据
(4)不能访问 WEB-INF 下的资源
(5)可以访问工程外的资源
3、实现
(1)方案一
//设置响应状态码302,表示请求重定向
resp.setStatus(302);
//设置响应头,回传新地址
resp.setHeader("Location", "新地址");
(2)方案二 (建议)
resp.setRedirect("新地址");
Thymeleaf
1、视图模板技术
2、使用示例
(1)添加 jar 包
(2)使用 jar 包的源码,新建 ViewBaseServlet 类
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
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 ViewBaseServlet extends HttpServlet {
private TemplateEngine templateEngine;
@Override
public void init() throws ServletException {
//1、获取ServletContext对象
ServletContext servletContext = this.getServletContext();
//2、创建Thymeleaf解析器对象
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
//3、给解析器对象设置参数
//HTML是默认模式,明确设置是为了代码更容易理解
templateResolver.setTemplateMode(TemplateMode.HTML);
//设置前缀
String viewPrefix = servletContext.getInitParameter("view-prefix");
templateResolver.setPrefix(viewPrefix);
//设置后缀
String viewSuffix = servletContext.getInitParameter("view-suffix");
templateResolver.setSuffix(viewSuffix);
//设置缓存过期时间(毫秒)
templateResolver.setCacheTTLMs(60000L);
//设置是否缓存
templateResolver.setCacheable(true);
//设置服务器端编码方式
templateResolver.setCharacterEncoding("utf-8");
//4、创建模板引擎对象
templateEngine = new TemplateEngine();
//5、给模板引擎对象设置模板解析器
templateEngine.setTemplateResolver(templateResolver);
}
protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
//1、设置响应体内容类型和字符集
resp.setContentType("text/html;charset=UTF-8");
//2、创建WebContext对象
WebContext webContext = new WebContext(req, resp, getServletContext());
//3、处理模板数据
templateEngine.process(templateName, webContext, resp.getWriter());
}
}
(3)在 web.xml 文件中添加配置
<!-- 配置上下文参数 -->
<context-param>
<!-- 配置前缀 -->
<param-name>view-prefix</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<!-- 配置后缀 -->
<param-name>view-suffix</param-name>
<param-value>.html</param-value>
</context-param>
(4)自定义的 Servlet 类继承 ViewBaseServlet 类
保存作用域:从上到下作用域依次增大
1、page:页面级别,现在已不使用
2、request:一次请求响应范围有效
3、session:一次会话范围有效,浏览器开启 -> 浏览器关闭
4、application:一次应用程序范围有效,服务器开启 -> 服务器关闭
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战