Servlet的快速入门,请求和响应

Servlet 核心笔记整理

一、Servlet 是什么

全称:Servlet = Server Applet(运行在服务器端的小程序)

本质:是一个接口,定义了 Java 类被浏览器访问(Tomcat 识别)的规则

核心特征:

运行在服务器端,依赖于服务器(如 Tomcat)才能运行

属于动态资源,由 Java 代码实现,无主方法

需遵循特定规则,才能被 Tomcat 识别并处理

二、快速入门步骤

  1. 创建 Java EE 项目

  2. 定义一个类,实现 Servlet 接口

java

public class ServletDemo implements Servlet { ... }

  1. 实现接口中的抽象方法(核心: init() 、 service() 、 destroy() )

  2. 配置 Servlet(通过 URL 访问)

在 web.xml 中配置:

xml

<servlet>

<servlet-name>demo1</servlet-name>

<servlet-class>全类名</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>demo1</servlet-name>

<url-pattern>/demo1</url-pattern>

</servlet-mapping>

作用:建立 URL 路径与 Servlet 类的映射关系

  1. 增加虚拟目录,部署到 Tomcat 后即可通过 URL 访问

三、执行原理

以访问 http://localhost:8080/项目名/demo1 为例:

  1. 解析 URL:Tomcat 接收客户端请求,解析出访问的 Servlet 资源路径 /demo1

  2. 查找映射:在 web.xml 中查找匹配的 <url-pattern>

  3. 定位类:通过 <servlet-name> 找到对应的 <servlet-class> (全类名)

  4. 加载创建:

  • 将对应字节码文件加载到内存( Class.forName() )

  • Tomcat 通过反射创建该 Servlet 对象( cls.newInstance() )

  1. 调用方法:执行 service() 方法处理请求

四、Servlet 生命周期

  1. 核心方法

方法名 执行时机 执行次数 作用

init() Servlet 被创建时 1 次 初始化资源

service() 每次客户端访问时 多次 处理请求、提供服务

destroy() Servlet 正常销毁(服务器关闭)时 1 次 释放资源

  1. 创建时机

默认情况:第一次被访问时创建

可配置:在 <servlet> 标签下添加 <load-on-startup>

负数:第一次访问时创建(默认行为)

正数:服务器启动时创建,数字越小优先级越高

单例特性:一个 Servlet 在内存中只存在一个对象,是单例模式,多个用户共享同一个对象

  1. 线程安全问题

多个用户同时访问同一个 Servlet 对象时,可能存在线程安全问题

注意:尽量不要在 Servlet 中定义可修改的成员变量

-------------请求和响应

一、Tomcat请求响应基础

  1. Web服务器接收到客户端HTTP请求后,会为**每一次请求**单独创建`HttpServletRequest`(请求对象)和`HttpServletResponse`(响应对象)。

  2. `request`对象封装了客户端的请求数据,获取客户端提交数据需通过该对象实现。

  3. `response`对象封装了服务器对客户端的响应数据,向客户端输出数据需通过该对象实现。

二、HttpServletRequest核心功能

`HttpServletRequest`是Servlet的`service()`方法参数之一,核心功能为封装请求数据、作为域对象存储数据、实现请求转发,其功能可分为四大类:封装请求头数据、封装请求正文数据、作为域对象、请求转发。

  1. 获取请求头数据

  2. 核心方法由Tomcat封装到`request`中,可在`service()`方法直接调用:

`String getHeader(String name)`:根据指定请求头名称获取对应值。

`Enumeration getHeaderNames()`:获取所有请求头的名称,可遍历获取所有请求头的键值对。

  1. 遍历示例:通过`getHeaderNames()`获取所有请求头名称,再通过`getHeader(name)`逐个获取值,可打印到控制台或响应到页面。

  2. 获取请求相关的其他核心方法

此类方法用于便捷获取请求头、请求URL相关数据,部分方法区分GET/POST请求(GET无正文,部分方法返回null/-1):

  1. `int getContentLength()`:获取请求正文字节数,GET请求返回-1。

  2. `String getContentType()`:获取请求类型,GET返回null,POST默认返回`application/x-www-form-urlencoded`。

  3. `String getMethod()`:返回请求方法,如GET、POST、DELETE、PUT等。

  4. `Locale getLocale()`:返回客户端浏览器支持的区域信息,用于国际化开发。

  5. `String getCharacterEncoding()`:获取请求编码,未设置时返回null(默认ISO-8859-1)。

  6. `void setCharacterEncoding(String code)`:设置请求编码,**仅对POST请求正文有效**,需在调用`getParameter()`前执行。

  7. 与请求URL相关方法(以`http://localhost:8080/hello/oneServlet?name=zhangSan\`为例):

  • `String getContextPath()`:返回项目上下文路径,例:`/hello`。

  • `String getQueryString()`:返回URL中的参数部分,例:`name=zhangSan`。

  • `String getRequestURI()`:返回请求URI路径,例:`/hello/oneServlet`。

  • `StringBuffer getRequestURL()`:返回完整请求URL(无参数),例:`http://localhost/hello/oneServlet\`。

  • `String getServletPath()`:返回Servlet访问路径,例:`/oneServlet`。

  1. 与客户端/服务器相关方法:
  • `String getRemoteAddr()`:返回客户端IP地址。

  • `String getRemoteHost()`:返回客户端主机名(实际仍获取IP)。

  • `int getRemotePort()`:返回客户端端口号(每次请求随机变化)。

  • `String getScheme()`:返回请求协议,例:`http`。

`String getServerName()`:返回服务器主机名,例:`localhost`。

`int getServerPort()`:返回服务器端口号,例:`8080`。

  1. 获取客户端请求参数(精通)

(1)参数传递的两种方式

  1. GET方式:地址栏直接拼接、超链接拼接、表单`method="GET"`提交,参数在URL的queryString中,有长度限制。

  2. POST方式:表单`method="POST"`提交,参数在请求正文中,无长度限制,更安全。

(2)获取参数的核心方法

无论GET/POST,获取参数的方法一致,方法适用于不同参数类型(单值/多值):

  1. `String getParameter(String name)`:通过参数名获取**单值参数**,如文本框、单选框、隐藏域。

  2. `String\[\] getParameterValues(String name)`:通过参数名获取**多值参数**数组,如复选框(同一name对应多个value)。

  3. `Enumeration getParameterNames()`:获取所有请求参数的名称,可遍历获取所有单值/多值参数。

  4. `Map<String, String\[\]> getParameterMap()`:获取所有参数的键值对Map,key为参数名,value为参数值数组(统一处理单/多值参数)。

(3)单值参数接收

  1. 前台:表单/超链接传递单值参数,如`<input type="text" name="p1">`。

  2. 后台:通过`getParameter(name)`直接获取,可结合`getParameterNames()`/`getParameterMap()`遍历所有参数。

(4)多值参数接收

  1. 前台:复选框使用同一name,如`<input type="checkbox" name="hobby" value="netplay">`。

  2. 后台:通过`getParameterValues(name)`获取字符串数组,或通过`getParameterMap()`遍历获取。

  3. 中文乱码处理(熟练)

request接收参数的乱码根源为**编码不统一**(默认ISO-8859-1,不支持中文),GET/POST请求处理方式不同,项目中通常统一使用UTF-8编码。

(1)POST请求中文乱码

POST参数在请求正文中,有两种处理方式,**推荐第二种**:

  1. 手动转码:先通过ISO-8859-1获取字节数组,再通过UTF-8重新编码为字符串。

示例:`name = new String(name.getBytes("ISO-8859-1"),"UTF-8");`

  1. 统一设置请求编码:在调用所有`getParameter()`前执行`request.setCharacterEncoding("UTF-8")`,一次设置全局生效,仅对POST正文有效。

(2)GET请求中文乱码

GET参数在URL中,无请求正文,`setCharacterEncoding()`无效,有两种处理方式:

  1. 手动转码:与POST手动转码方式一致,对每个中文参数单独处理。

  2. 配置服务器编码:修改Tomcat的`/conf/server.xml`,在`<Connector>`标签添加`URIEncoding="UTF-8"`,对整个Tomcat的GET请求生效。

  3. 注意:Tomcat8.5及以上版本已默认支持URL中文UTF-8编码,无需手动配置;**不建议使用GET请求传递中文参数**。

5. 请求转发与request作用域

(1)请求转发

  1. 概念:也叫**服务器端跳转**,Servlet处理完业务逻辑后,通过`request`跳转到目标资源(静态页面/Servlet/JSP),地址栏**不发生变化**。

  2. 核心方法:`request.getRequestDispatcher("资源路径").forward(request, response);`

  3. 特点:跳转过程中可通过`request`传递数据,目标资源能获取传递的属性值。

(2)request作用域

  1. `request`是域对象,作用范围**仅在一次请求-响应过程中**,每一次请求都会创建新的`request`对象,请求结束后对象销毁。

  2. 数据操作方法:

  • `void setAttribute(String name, Object value)`:向request域中存入键值对数据。

  • `Object getAttribute(String name)`:从request域中根据键获取数据。

  1. 与ServletContext对比:ServletContext是全局域对象(服务器启动创建,关闭销毁),request是局部域对象(一次请求有效),request存数据更安全,不会造成数据共享冲突。

三、HttpServletResponse核心功能

`HttpServletResponse`是Servlet的`service()`方法参数之一,核心作用是**响应客户端请求,向客户端输出信息**,封装了服务器的响应数据(响应头、状态码、响应正文),核心功能分为四类:设置响应头、发送状态码、设置响应正文、实现重定向。

  1. 核心功能分类

  2. 设置响应头信息:如设置编码、刷新、重定向等响应头。

  3. 发送状态码:如200(成功)、404(资源不存在)、500(服务器错误)。

  4. 设置响应正文:向客户端输出文本、HTML等内容。

  5. 重定向:实现客户端跳转,地址栏发生变化。

  6. 设置状态码和基础编码方法

  7. `response.setContentType("text/html;charset=utf-8")`:**核心方法**,同时设置响应内容类型为HTML、响应编码为UTF-8,解决响应页面中文乱码,需在输出内容前执行。

  8. `response.setCharacterEncoding("utf-8")`:单独设置响应正文的编码,若未设置`contentType`,浏览器默认按ISO-8859-1解析,仍会乱码,通常与`setContentType`配合使用。

  9. `response.setStatus(int sc)`:设置响应状态码,如`response.setStatus(200)`。

  10. `response.sendError(int sc, String msg)`:发送错误状态码并携带提示信息,如`response.sendError(404, "您要查找的资源不存在")`,Tomcat会跳转到对应错误页面并显示提示。

  11. 设置响应头信息

  12. `response.setHeader(String name, String value)`:设置自定义响应头,与`setContentType()`功能一致(`setContentType`是便捷方法),例:`response.setHeader("contentType", "text/html;charset=utf-8")`。

  13. 定时刷新/重定向:`response.setHeader("Refresh", "5; URL=http://www.baidu.com")`,表示5秒后自动跳转到指定URL。

  14. 响应中文乱码处理

向客户端输出中文时,需**先设置编码,再输出内容**,核心代码:

```java

response.setContentType("text/html;charset=utf-8");

response.setCharacterEncoding("UTF-8");

response.getWriter().write("中文内容");

  1. 重定向

  2. 概念:也叫**客户端跳转**,Servlet处理完业务逻辑后,通过`response`告诉客户端跳转到新的资源地址,客户端会重新发送请求,地址栏**发生变化**。

  3. 核心方法:`response.sendRedirect("资源路径")`。

  4. 特点:重定向后原`request`域中的数据全部失效,会创建新的`request`对象;支持跨域跳转(跳转到其他服务器的资源)。

四、请求转发(forward)与重定向(redirect)的区别(核心面试题)

  1. 处理流程不同

  2. 请求转发:客户端发送1次请求 → 服务器Servlet处理业务 → 服务器内部跳转到目标资源 → 服务器将目标资源结果返回客户端(**全程1次请求**)。

  3. 重定向:客户端发送1次请求 → 服务器Servlet处理业务 → 服务器返回跳转地址给客户端 → 客户端重新发送2次请求到新地址 → 服务器返回新资源结果(**全程2次请求**)。

  4. 地址栏表现不同

  5. 请求转发:**地址栏不变**,始终显示第一次请求的地址(服务器端内部跳转,客户端无感知)。

  6. 重定向:**地址栏变为新资源地址**,客户端能看到跳转后的地址。

3. 绝对路径中"/"的含义不同

  1. 请求转发:服务器内部跳转,`/`代表**当前Web应用的根目录**,例:`/success.jsp`(直接指向项目下的success.jsp)。

  2. 重定向:客户端重新请求,`/`代表**Tomcat服务器的根目录**,例:需写`/项目名/资源名`(`/param_demo/success.html`)。

  3. 相对路径:两者使用无区别,均基于当前页面路径解析。

  4. 数据传递不同

  5. 请求转发:属于同一次请求,可通过`request.setAttribute()`/`getAttribute()`传递数据(request作用域有效)。

  6. 重定向:属于两次不同请求,原request域数据失效,无法通过request传递数据,需使用session或URL拼接参数。

  7. 跳转范围不同

  8. 请求转发:**仅能跳转到当前Web应用内部的资源**,无法跨域(如跳转到百度)。

  9. 重定向:**支持跨域跳转**,可跳转到任意服务器的资源(如百度、其他项目)。

相关推荐
我登哥MVP1 小时前
HDFS硬核拆解-读写Pipeline与Java实战
java·hadoop·hdfs·云原生·云计算
ljs6482739512 小时前
VMware 中部署 HDFS 集群环境(Hadoop 3.4.3)完整指南
大数据·hadoop·hdfs
斯文的八宝粥18 小时前
WPF企业内训全程实录(下)
大数据·hadoop·wpf
Zhu75820 小时前
使用腾讯CNB构建Hadoop定制容器镜像
大数据·hadoop·分布式
TTBIGDATA21 小时前
【Ambari Plus】13.Spark 安装
大数据·hadoop·分布式·spark·ambari·sqoop·ambari plus
sunxunyong1 天前
Hadoop租户创建
大数据·hadoop·分布式
AllData公司负责人1 天前
数据集成管理|AIIData数据中台实现MySQL、Hive、Oracle一键接入Doris
大数据·数据库·人工智能·hive·mysql·oracle·数据分析
泰克教育官方账号1 天前
泰涨知识 | Hive集群环境部署
数据仓库·hive·hadoop
婉然从物1 天前
Flink SQL 元数据持久化实战:从“每次重启表消失”到“Hive Metastore 永久存储”
hive·sql·flink
龙石数据2 天前
MySQL 全量同步到 Hive 怎么做?三步配置教程
数据库·hive·mysql·数据治理·数据中台