认识HttpServletRequest和HttpServletResponse

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 认识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~~~

相关文章
|
存储 监控 网络协议
5张图,带你了解微服务架构治理
5张图,带你了解微服务架构治理
1122 0
5张图,带你了解微服务架构治理
|
消息中间件 SQL 存储
超详细的RabbitMQ入门,看这篇就够了!
RabbitMQ入门,看这篇就够了
188146 59
|
缓存 Java 应用服务中间件
一文带你使用xxl-job定时任务
将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。 将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。 因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性;
1723 0
一文带你使用xxl-job定时任务
|
2月前
|
Java 应用服务中间件 Maven
springboot整合websocket后启动报错:javax.websocket.server.ServerContainer not available
springboot整合websocket后启动报错:javax.websocket.server.ServerContainer not available
979 1
|
11月前
|
SQL Java 数据处理
Java中的HttpServletRequest:解析与处理HTTP请求
在现代的Java Web应用开发中,与客户端的数据交互是至关重要的一部分。Spring框架中的`HttpServletRequest`对象为我们提供了处理和解析HTTP请求的能力。本文将引导您深入了解`HttpServletRequest`对象,探讨其特点、用法、实现方式以及在实际应用中的优势。
|
存储 弹性计算 缓存
阿里云Intel Xeon(Sapphire Rapids) Platinum 8475B处理器CPU
阿里云Intel Xeon(Sapphire Rapids) Platinum 8475B处理器CPU,阿里云服务器ECS通用型实例规格族g8i采用2.7 GHz主频的Intel Xeon(Sapphire Rapids) Platinum 8475B处理器,3.2 GHz睿频,g8i实例采用阿里云全新CIPU架构,可提供稳定的算力输出、更强劲的I/O引擎以及芯片级的安全加固
936 0
|
缓存 固态存储 测试技术
这里有一款非常优秀,而且很有上进心的SSD
这里有一款非常优秀,而且很有上进心的SSD
|
消息中间件 网络协议 Java
Springboot 整合RabbitMq ,用心看完这一篇就够了
Springboot 整合RabbitMq ,用心看完这一篇就够了
1563 0
Springboot 整合RabbitMq ,用心看完这一篇就够了
|
消息中间件 算法 JavaScript
从 Java 8 升级到 Java 17 全过程,贼特么坑!
从 Java 8 升级到 Java 17 全过程,贼特么坑!
|
弹性计算 Cloud Native Linux
ECS的初体验
阿里云,阿里巴巴集团旗下云计算品牌,作为全球卓越的云计算技术和服务提供商,不仅为许多企业提供了便利,还专门为学生高校准备了飞天加速计划,让更多学生能解除云、了解云、运用云。推出的学生机适合广大在校大学生、高中生甚至初中生进行学习,只需几步,就能在家轻松搭建一个属于自己的网站,简直是广大TI热爱者的福利