Servlet详解(下)

简介: Servlet详解

三. Servlet常用API


3.1 HttpServlet

HttpServlet是Servlet接口的一个实现类,并且它是一个抽象类,servlet.http包中定义了采用HTTP通信协议(一个无状态协议)的HttpServlet类;

核心方法:

方法名称

调用时机

init

在 HttpServlet 实例化之后被调用一次
destory

在 HttpServlet 实例不再使用的时候调用一次

service 收到 HTTP 请求的时候调用
doGet 收到 GET 请求的时候调用(由 service 方法调用)
doPost 收到 POST 请求的时候调用(由 service 方法调用)
doPut/doDelete/doOptions/...

收到其他请求的时候调用(由 service 方法调用)


1)关于 init 方法:


HttpServlet被实例化之后,当首次收到匹配的请求的时候,才会调用到,一般使用这个方法来做一些初始化相关的工作,init只会调用一次;


2)关于 destroy 方法:


这个方法是webapp被销毁前执行一次,用来做一些收尾工作(不建议使用);


3)关于 servlet 方法:


每次收到路径匹配的请求调用一次;


✅常见面试题:让你说一说Servlet的生命周期?

  1. init 是初始情况下调用一次;
  2. destroy 是结束之前调用一次;
  3. service 是每次收到路径匹配的请求调用一次;


3.2 HttpServletRequest

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息;


核心方法:


方法 描述
String getProtocol() 返回请求协议的名称和版本。
String getMethod() 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
String getRequestURI()

从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请

求的 URL 的一部分。

String getQueryString() 返回指示请求上下文的请求 URI 部分。
Enumeration
getParameterNames()
返回一个 String 对象的枚举,包含在该请求中包含的参数的名
称。
String getParameter(String
name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回
null。
String[]
getParameterValues(String
name)
返回一个字符串对象的数组,包含所有给定的请求参数的值,如
果参数不存在则返回 null。
Enumeration
getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
String getHeader(String
name)
以字符串形式返回指定的请求头的值。
String
getCharacterEncoding()
返回请求主体中使用的字符编码的名称。
String getContentType() 返回请求主体的 MIME 类型,如果不知道类型则返回 null。
int getContentLength() 以字节为单位返回请求主体的长度,并提供输入流,或者如果长
度未知则返回 -1
InputStream
getInputStream()
用于读取请求的 body 内容. 返回一个 InputStream 对象
@WebServlet("/ServletRequest")
public class ServletRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        StringBuilder stringBuilder = new StringBuilder();
        // 返回请求协议的名称和版本
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        // 返回请求的 HTTP 方法的名称
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        // 返回URI
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        // 返回在路径后的请求 URL 中的查询字符串
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
        // 在响应中设置body的类型
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write(stringBuilder.toString());
    }
}

603b4a4a30d44f0989d79f8831f57903.png


这里介绍一个最常用的API,就是getParameter,我们在开发的需求中,前端给后端传递数据时是非常常见的需求,假设这里我们把前端的姓名和密码传到后端,就可以这样写:


1)通过 query string 传递


@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {
    // 通过 query string 传递
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username == null){
            System.out.println("username 在 query string 中不存在");
        }
        if(password == null){
            System.out.println("password 在 query string 中不存在");
        }
        System.out.println("username = " + username + " ,password = " + password);
        resp.getWriter().write("ok");
    }
}

05528f2b33c44c779385a357c9563970.png

2)通过body传递


@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置编码方式,以防乱码
        req.setCharacterEncoding("utf8");
        // 前端通过body,以form表单的格式,把用户名和密码传给服务器
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username == null){
            System.out.println("username 在 query string 中不存在");
        }
        if(password == null){
            System.out.println("password 在 query string 中不存在");
        }
        System.out.println("username = " + username + " ,password = " + password);
        resp.getWriter().write("ok");
    }

94c7bc38b5e545e08ee6023afecce62b.png

我们通过Postman构造请求可以发现:

8a596e7ee6a64f56bab75b9225ce2216.png

3)通过json传递(最常用的)


 在使用json之前,我们引入一个第三方库,这里可以去Maven中央仓库下载:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.15.0</version>
        </dependency>
class User {
    public String username;
    public String password;
}
@WebServlet("/json")
public class JsonServlet extends HttpServlet {
    // 这个对象可以把 json 格式的字符串解析成 java 对象,同时也可以把 java 对象转化成一个 json 格式字符串
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 通过 post 请求的 body 传递一个 json 格式的字符串
        User user = objectMapper.readValue(req.getInputStream(), User.class);
        System.out.println("username = " + user.username + ", password = " + user.password);
        resp.getWriter().write("ok");
    }
}

通过Postman构造请求可以发现:

0216cbaa5c17448296022895b3c25f72.png

3616d4bb255d4c579433b31d812a8639.png

上述的 readValue 方法主要做的是:


1.解析json字符串,转换成若干个字符串;

2.根据第二个参数类对象(Use.class),去找到 User 里的 public 的属性;

3.遍历属性,根据属性的名字,去查询键值对,看看这个属性的名字是否存在对应的 value,如果存在,就把 value 赋值到该属性中;

3.2 HttpServletResponse

HttpServletResponse表示一个HTTP响应


核心方法:

方法 描述
void setStatus(int sc) 为该响应设置状态码。
void setHeader(String name,
String value)
设置一个带有给定的名称和值的 header. 如果 name 已经存在,
则覆盖旧的值.
void addHeader(String
name, String value)
添加一个带有给定的名称和值的 header. 如果 name 已经存在,
不覆盖旧的值, 并列添加新的键值对
void setContentType(String
type)
设置被发送到客户端的响应的内容类型。
void
setCharacterEncoding(String
charset)
设置被发送到客户端的响应的字符编码(MIME 字符集)例如,
UTF-8。
void sendRedirect(String
location)
使用指定的重定向位置 URL 发送临时重定向响应到客户端。
PrintWriter getWriter() 用于往 body 中写入文本格式数据.
OutputStream
getOutputStream()
用于往 body 中写入二进制格式数据.
@WebServlet("/response")
public class ServletResponse extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("返回200响应");
    }
}

055298edb3a54806805ccf14d009e8c8.png


设置重定向:


@WebServlet("/redirect")
public class ServletRedirect extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置状态码
        resp.setStatus(302);
        // 设置重定向的网页地址
        resp.setHeader("location","https://www.baidu.com");
    }
}

这里就直接跳转到了百度的网页了!

目录
相关文章
|
存储 持续交付 云计算
云计算——云计算关键技术
云计算——云计算关键技术
4935 0
|
2月前
|
缓存 监控 安全
Spring Boot 的执行器注解:@Endpoint、@ReadOperation 等
Spring Boot Actuator 提供多种生产就绪功能,帮助开发者监控和管理应用。通过注解如 `@Endpoint`、`@ReadOperation` 等,可轻松创建自定义端点,实现健康检查、指标收集、环境信息查看等功能,提升应用的可观测性与可管理性。
151 0
Spring Boot 的执行器注解:@Endpoint、@ReadOperation 等
|
2月前
|
安全 Cloud Native Java
Java 模块化系统(JPMS)技术详解与实践指南
本文档全面介绍 Java 平台模块系统(JPMS)的核心概念、架构设计和实践应用。作为 Java 9 引入的最重要特性之一,JPMS 为 Java 应用程序提供了强大的模块化支持,解决了长期存在的 JAR 地狱问题,并改善了应用的安全性和可维护性。本文将深入探讨模块声明、模块路径、访问控制、服务绑定等核心机制,帮助开发者构建更加健壮和可维护的 Java 应用。
232 0
|
Java 应用服务中间件 测试技术
Maven学习笔记(一):Maven基础(基于命令行的学习和应用)
Maven 是一款 Java 项目构建工具,主要用于管理 jar 包及其依赖关系。 本文主要了解Maven基础知识及基础应用,旨在为之后的进一步学习奠定基础。 内容上几近全为学习《尚硅谷2022版Maven教程》整理所得。 仅供参考。
796 81
Maven学习笔记(一):Maven基础(基于命令行的学习和应用)
|
JSON 前端开发 Java
深入SpringMVC聊跨域问题的最佳实践
本文将深度剖析SpringMVC中的跨域问题及其最佳实践,尤其聚焦于Jsonp接口在技术升级中遇到的跨域难题。结合一个具体的案例,展示在技术升级过程中,原有JSONP接口出现跨域问题的表现及原因,以及如何通过自定义SpringMVC的拦截器和MessageConvertor来解决这个问题。
|
消息中间件 Kafka 数据库
微服务架构中,如何确保服务之间的数据一致性
微服务架构中,如何确保服务之间的数据一致性
WK
|
机器学习/深度学习 算法
什么是Sigmoid函数
Sigmoid函数是在机器学习及统计学中广泛应用的一种数学模型,尤其适用于逻辑回归与神经网络中的激活场景。该函数能将任意实数映射至(0,1)区间,象征概率或事件发生可能性。其S型曲线特性使其在二分类问题中表现出色,同时具备连续平滑与中心对称的特点,利于采用如梯度下降等优化算法。然而,Sigmoid函数在极端输入值下会出现梯度消失的问题,影响模型训练效果。尽管有此局限性,它在特定应用场景中依然重要,例如需要输出概率值的情况。
WK
1105 0
|
Java Spring 容器
深入理解@EnableAspectJAutoProxy的力量
深入理解@EnableAspectJAutoProxy的力量
745 0
|
Java Linux API
Java多线程基础-4:详解Thread类及其基本用法 (一)
Java 中的 `Thread` 类是用来管理线程的,每个线程都是通过 `Thread` 类的对象来描述。
610 0
|
XML Java 数据库
springboot集成flowable
springboot集成flowable