HttpServletRequest 如何读取JSON请求体

适用场景:用于 Java Web / SpringBoot 项目中,读取客户端(前端、接口调用方)发送的 POST / PUT 请求体数据(JSON、纯文本、XML 等)。

1. 核心代码

1.1. 原生一行读取代码

java 复制代码
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.stream.Collectors;

// 读取请求体全部内容,拼接为完整字符串
String postData = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

1.2. 封装工具方法(推荐生产使用)

java 复制代码
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.Reader;
import java.util.stream.Collectors;

/**
 * 工具类:读取 HTTP 请求体
 * @param request 请求对象
 * @return 请求体字符串
 */
public static String getRequestBody(HttpServletRequest request) throws IOException {
    // 设置UTF-8编码,防止中文乱码(必须在getReader前执行)
    request.setCharacterEncoding("UTF-8");
    try (Reader reader = request.getReader()) {
        return reader.lines().collect(Collectors.joining(System.lineSeparator()));
    }
}

2. 支持的数据格式

支持

  • JSON 字符串(最常用,如 {"username":"admin","pwd":"123"}

  • 纯文本

  • XML 格式

  • 自定义文本报文

不支持

  • application/x\-www\-form\-urlencoded(表单默认格式,用 getParameter

  • multipart/form\-data(文件上传,用文件解析工具)

  • 图片、文件等二进制数据

3. 使用规则

3.1. 绝对不能混用的方法

以下方法一旦调用,getReader() 就会读不到数据!

  • request.getParameter("xxx")

  • request.getParameterMap()

  • request.getParameterNames()

  • request.getParameterValues()

原理:这些方法会一次性读完请求体并关闭流,getReader() 无法重复读取。

3.2. 只能读取一次

request.getReader() 全局只能调用一次,第二次调用会报错 / 读空。

3.3. 必须处理异常

getReader() 会抛出 IOException,必须捕获或抛出。

4. 正确使用示例

4.1.读取 JSON 请求体

java 复制代码
@PostMapping("/login")
public void login(HttpServletRequest request) throws IOException {
    // 读取JSON请求体 {"username":"admin","pwd":"123"}
    String jsonStr = getJsonRequestBody(request);
    System.out.println("接收JSON报文:" + jsonStr);
}

4.2.普通 Servlet 中使用

java 复制代码
@WebServlet("/api/test")
public class TestServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 读取请求体
        String body = getRequestBody(request);
        System.out.println("接收到数据:" + body);
        
        response.getWriter().write("success");
    }
}
相关推荐
郑州光合科技余经理1 小时前
代驾系统架构拆解:订单链路、权限组织与私有化源码交付
开发语言·后端·算法·架构·系统架构·uni-app·php
hboot4 小时前
AI工程师第六课 - RAG检索增强生成
后端·langchain·llm
mldong4 小时前
jeeflow:98KB 的工作流引擎长什么样
后端
paopaokaka_luck5 小时前
基于springboot3+vue3的企业考勤管理系统(部门树递归、Echarts图形化分析)
开发语言·spring boot·学习·echarts·mybatis·需求分析·代码规范
程序员cxuan7 小时前
速度太快了!本地可以跑 DeepSeek-V4-Flash 了
人工智能·后端·程序员
阿祖zu8 小时前
芝士就是力量!开源私有化部署与 GitHub 双向同步的个人知识笔记 App
前端·后端·ios
不才不才不不才8 小时前
Spring 源码系列(16): doDispatch 全流程——一次请求的主干链路
java·后端·spring
IT_陈寒9 小时前
SpringBoot自动配置失效?这个隐藏配置坑了我一整晚
前端·人工智能·后端
搜狐技术产品小编20239 小时前
告别“黑盒”与误判:如何用“多智能体对抗辩论”重构内容安全审核系统
后端·多agent
DantyWei9 小时前
controller注册及调用时机
后端