认识HttpServletRequest和HttpServletResponse

简介: 认识HttpServletRequest和HttpServletResponse

hi,大家好,上一期我们认识了HttpServlet,这一期我们来认识一下HttpServletRequest和HttpServletResponse

🚀HttpServletRequest


💚1.核心方法介绍


💚2.代码举例展示


🚀HttpServletResponse


💚1.核心方法展示


💚2.代码举例展示


1.HttpServletRequest


一个http请求,在Tomcat收到http请求,就会解析成上述的HttpServletRequest对象,HTTP 请求报文里面有啥,这个类里面就有啥

来看它的核心方法


1691218385568.png

通过上述的方法可以获取一个请求的各个方面的信息

细心的同学可以发现方法都是get类型的,因为请求是服务器获取到的内容,不应该修改,所以都是get方法,没有set

解释一下这个方法里的URI,URI和URL不是一个东西

URL是唯一资源定位符,URI是唯一资源标识符,也可以认为URI包含于URL中,概念非常相似,很多时候就会混着用


注意一下最后一个方法,通过InputSream,进一步读取body的内容,如果确实需要按照字符处理,手动转换即可


我们都知道InputStream是按照字节流读取,为啥不按照字符流嘞?

字节流比字符流更加通用,当前数据如果是文本,那么用字符流或者字节流都行,如果数据是二进制的,那么就只能用字节流


HTTP是超文本协议,但是其实http的body也可以携带二进制数据

比如请求或者响应的body压缩过的的话,此时的body就是二进制的,当然了,大部分的请求的body都不是二进制


==================================================

下面我们用代码来认识一下这些方法

前五个我们已经在之前学习了,这里就不再赘述了~~~


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;
import java.util.Enumeration;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-06-09
 * Time: 16:57
 */
@WebServlet("/showRequest")
public class ShowRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        StringBuilder result=new StringBuilder();
        result.append(req.getProtocol());
        result.append("<br>");
        result.append(req.getMethod());
        result.append("<br>");
        result.append(req.getRequestURI());
        result.append("<br>");
        result.append(req.getQueryString());
        result.append("<br>");
        result.append(req.getContextPath());
        result.append("<br>");
        result.append("=============================");
    /*    Enumeration<String>  headerNames=req.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String headerName=headerNames.nextElement();
            String headerValue=req.getHeader(headerName);
            result.append(headerName+":"+headerValue+"<br>");
        }*/
       //设置响应格式便于让浏览器解析
       resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write(result.toString());//转换成字符串的形式
    }
}


运行代码看看结果

在这里我不小心将result.toString()写成了resp.toString(),就出现了另一个结果

这一段其实就是resp对象的地址了

getParameter是最常用的API之一

前端给后端传递数据,是非常常见的需求


1.通过querystring 传递

2.通过body(form表单的形式)

3.通过body(json格式)

下面我们分别来说

1.通过query string传递

我们约定前端通过query string传递username和password

看后端代码咋写


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;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-06-09
 * Time: 18:16
 */
@WebServlet("/getParameter")
public class GetParameter  extends HttpServlet {
    //前端通过query string传递username和password两个属性
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username=req.getParameter("username");
        if(username==null){
            System.out.println("username这个key在query string不存在");
        }
        String password=req.getParameter("password");
        if(password==null){
            System.out.println("password这个key在query string不存在");
        }
        System.out.println("username="+username+",password="+password);
        resp.getWriter().write("ok");
    }
}


打开浏览器


7bd088e163634c36a1eab2416d4a508d.png


7b71e7d7ca0144fd8d908c11b6eec348.png


2.通过body(form表单形式)


相当于body存的格式和query string一样,但是Content-Type是

application/x-www-form-urlencoded,也是通过getParameter来获取键值对


构造post请求(一般来说都是post请求有body)


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;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-06-09
 * Time: 18:16
 */
@WebServlet("/getParameter")
public class GetParameter  extends HttpServlet {
    //前端通过query string传递username和password两个属性
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username=req.getParameter("username");
        if(username==null){
            System.out.println("username这个key在query string不存在");
        }
        String password=req.getParameter("password");
        if(password==null){
            System.out.println("password这个key在query string不存在");
        }
        System.out.println("username="+username+",password="+password);
        resp.getWriter().write("ok");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //前端通过body,以form表单的格式,将username和password传给服务器
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        if(username==null){
            System.out.println("username这个key在body 不存在");
        }
        if(password==null){
            System.out.println("password这个key在body不存在");
        }
        System.out.println("username"+username+",password"+password);
        resp.getWriter().write("ok");
    }
}


这个请求是一个post请求,我们使用postman构造这个请求

0b73e99c5b83438ca1e70d21213269fd.png


6a00c5cb951b470aa8649177ac92a1ec.png

c9c9459a1cf14427bcc2d2100af3d37d.png


可以看到成功返回结果


有一个问题,键值对的value是否可以是中文呢?


0da0ea0391794d74be1be8e464377a0a.png

1ecb21a4fb9e4199b3b02514320617e8.png

我们看到结果依然返回,但是这其实只是一个巧合


在URL中,如果query string 中包含中文或者特殊字符,必须使用urlencode的方式进行转码.如果直接写中文或者特殊字符,会有风险!

8fcb2b66603342d187ba32dcd3fb04e6.png

21037e05a1e24bcaa82aa5bb907a3512.png

一敲回车

结果显示张三

如果不转码,有些浏览器或者http服务器,对中文支持不好的话,出现问题

一搬来说服务器解码(urldecode),Servlet已经处理好了,前端编码(urlencode)


post请求中

用postman来看更加直观

直接乱码了,为什么会出现乱码呢,前端默认是utf8编码方式,但是后端不知道啊,所以要给请求设置编码方式

f5d21bf7f0cc466e94619b17a69c1d05.png


此时

结果就不会乱码了

3.使用body(json格式)


json也是键值对格式的数据,要拿到key和value,但是Servlet自身没有内置json解析功能,我们拿到的就只是字符串,拿不到key和对应的value,咋办捏

我们采用第三方库,用来处理json的第三方库有很多,我们使用jackson

要引入依赖


94bc1e3bc47c4a7f8d7875143d1f681f.png


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>servlet</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- 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>
    </dependencies>
    <packaging>war</packaging>
    <build>
        <finalName>hello_servlet</finalName>
    </build>
</project>

9f6fadae4f6b40baaa082bba13585b62.png


ab9b5e91faf043eaa318b79a07f00d79.png


下面来解释一下这个代码的执行流程


readvalue的作用(json字符串转换成Java对象)

1.通过readValue解析json字符串转化成若干键值对

2.根据第二个参数User.class找到User里面的public的属性,依次遍历

3.根据属性名字,去准备好的键值对查询是否存在对应的value,然后赋值给该属性


总结:HttpServletRequest,这个类,主要就是用于获取到请求的各个方面的信息,尤其是前端传过来的自定义数据,自定义数据通过query

string,post body (form),post body(json)来体现


2.HttpServletResponse

依旧先来看核心方法


1691218674919.png

面对空的响应对象就需要设置一些属性了

也依然通过代码来看


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;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-06-09
 * Time: 20:46
 */
@WebServlet("/status")
public class StatusServlet 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响应");
    }
}

这个是设置状态码,根据需要自己设置

结果

通过header实现自动刷新效果


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;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-06-09
 * Time: 20:58
 */
@WebServlet("/refresh")
public class RefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //每隔一秒自动刷新一次
        resp.setHeader("Refresh","1");
        resp.getWriter().write("time="+System.currentTimeMillis());
    }
}

41ba85c5fd0d421782dbb82dce7f6dca.png


这个结果是一个动态的,时间一直在变

实现重定向


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;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-06-09
 * Time: 21:03
 */@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //当用户访问这个路径自动重定向到百度
        /*resp.setStatus(302);
        resp.setHeader("Location","https://www.baidu.com");*/
        resp.sendRedirect("https://www.bidu.com");
    }
}

以上就是今天所有的内容,我们下期再见,886~~~

相关文章
|
应用服务中间件 容器
【JavaWeb】知识总结Ⅹ(HttpServletRequest, HttpServletResponse)
请求行信息:可以使用getMethod()方法获取请求方法(如GET、POST等),使用getRequestURI()方法获取请求的URI(统一资源标识符),使用getProtocol()方法获取请求使用的协议(如HTTP/1.1)。 请求头信息:可以使用getHeader(String name)方法获取指定名称的请求头的值,使用getHeaderNames()方法获取所有请求头的名称的枚举。 请求参数:可以使用getParameter(String name)方法获取指定名称的请求参数的值,使用getParameterNames()方法获取所有请求参数的名称的枚举。
|
easyexcel Java Maven
使用EasyExcel实现CSV文件读写功能,
使用EasyExcel实现CSV文件读写功能,顺手使用Idea创建SpringBoot工程集成swagger3
2410 0
使用EasyExcel实现CSV文件读写功能,
|
消息中间件 Java 中间件
秒懂消息队列MQ,万字总结带你全面了解消息队列MQ
消息队列是大型分布式系统不可缺少的中间件,也是高并发系统的基石中间件,所以掌握好消息队列MQ就变得极其重要。接下来我就将从零开始介绍什么是消息队列?消息队列的应用场景?如何进行选型?如何在Spring Boot项目中整合集成消息队列。
23883 10
秒懂消息队列MQ,万字总结带你全面了解消息队列MQ
|
存储
【数据结构】连通图、连通分量与强连通图、强连通分量—区别在于强,强强在哪里?
【数据结构】连通图、连通分量与强连通图、强连通分量—区别在于强,强强在哪里?
7356 1
【数据结构】连通图、连通分量与强连通图、强连通分量—区别在于强,强强在哪里?
|
11月前
|
存储 前端开发 Java
Java后端如何进行文件上传和下载 —— 本地版(文末配绝对能用的源码,超详细,超好用,一看就懂,博主在线解答) 文件如何预览和下载?(超简单教程)
本文详细介绍了在Java后端进行文件上传和下载的实现方法,包括文件上传保存到本地的完整流程、文件下载的代码实现,以及如何处理文件预览、下载大小限制和运行失败的问题,并提供了完整的代码示例。
4087 2
|
9月前
|
供应链 算法 测试技术
基于控制工程的牛鞭效应simulink建模与仿真
本研究基于控制理论,建立了多级线性供应链模型,利用噪声带宽和Matlab/Simulink对牛鞭效应进行建模与仿真。牛鞭效应指需求信息在供应链中逐级放大,导致库存积压、缺货等问题。通过Forrester模型,描述各节点订单量与库存水平的动态变化,采用差分方程模拟多级供应链系统。测试使用MATLAB2022A版本,展示了模型的有效性和可扩展性。
|
安全 Linux 网络安全
【工具使用】几款优秀的SSH连接客户端软件工具推荐FinalShell、Xshell、MobaXterm、OpenSSH、PUTTY、Terminus、mRemoteNG、Terminals等
【工具使用】几款优秀的SSH连接客户端软件工具推荐FinalShell、Xshell、MobaXterm、OpenSSH、PUTTY、Terminus、mRemoteNG、Terminals等
115320 0
|
SQL druid Java
解决 ‘The last packet successfully received from the server was xxx milliseconds ago‘ 问题
解决 ‘The last packet successfully received from the server was xxx milliseconds ago‘ 问题
6325 0
|
IDE Linux 开发工具
IntelliJ IDEA2022破解IDEA2022.2永久破解激活教程
IDEA 目前已经更新到最新的 2022.2.2 版本了,群里的小伙伴私聊问我,为啥之前 2021.3.1 的激活套路对新版本 2022.2.2 不管用了,是个什么情况? 很显然,IDEA 官方发现了这种破解路数,新版本加入了更严厉的反制破解。所以说,小伙伴们破解成功了以后,尽量不要升级 IDEA, 不然大概率又不行了。 好在z大又更新了新的补丁,针对最新版本,这边笔者亲测可行,仅以下文记录本人 IntelliJ IDEA 2022.2.2 版本的激活破解到 2099 年的全过程,步骤非常详细,跟着图文来就行~
62743 3
IntelliJ IDEA2022破解IDEA2022.2永久破解激活教程
|
Java 应用服务中间件
无法解析类型 javax.servlet.http.HttpServletRequest。从必需的 .class 文件间接引用
java.lang.Error: 无法解析的编译问题: 无法解析类型 javax.servlet.http.HttpServletRequest。从必需的 .class 文件间接引用了它 无法解析类型 javax.servlet.http.HttpServletResponse。
3903 0