HttpServletRequest 和 HttpServletResponse 区别和作用

发布于:2025-03-10 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、核心作用对比

对象 HttpServletRequest(请求对象) HttpServletResponse(响应对象)
本质 客户端发给服务器的 HTTP 请求信息(输入) 服务器返回客户端的 HTTP 响应信息(输出)
生命周期 一次 HTTP 请求中创建,请求处理完成后销毁 同左
获取方式 由 Servlet 容器自动注入(如 doGet(request, response) 同左
核心功能 读取请求参数、头信息、会话数据等 设置响应状态、头信息、返回内容等

二、关键方法与示例

(一)HttpServletRequest - 请求信息读取器

(一)HttpServletRequest - 请求信息读取器

主要方法及使用场景:

方法 作用 示例场景
String getParameter(String name) 获取 URL参数 或 表单参数 用户注册表单的 username 字段
Enumeration<String> getParameterNames() 获取所有请求参数名 调试时打印全部参数
String[] getParameterValues(String name) 获取同名参数的多个值(复选框等) 多选的兴趣爱好
String getHeader(String name) 获取请求头信息 获取设备类型 User-Agent
Cookie[] getCookies() 获取客户端的 Cookies 自动登录功能
HttpSession getSession() 获取或创建会话对象 保存用户登录状态
String getRequestURI() 获取请求路径(不包含协议和域名) 记录请求日志
StringBuffer getRequestURL() 获取完整请求 URL 生成重定向地址

代码示例 - 传统 Servlet 中读取请求参数:

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    // 获取单个参数
    String username = request.getParameter("username");
    
    // 获取多选参数
    String[] hobbies = request.getParameterValues("hobby");
    
    // 获取请求头
    String userAgent = request.getHeader("User-Agent");
    
    // 获取所有参数名(调试用)
    Enumeration<String> params = request.getParameterNames();
    while (params.hasMoreElements()) {
        String paramName = params.nextElement();
        System.out.println(paramName);
    }
}

(二)HttpServletResponse - 响应信息控制器

主要方法及使用场景:

方法 作用 示例场景
void setStatus(int sc) 设置 HTTP 状态码 返回错误码 404
void sendError(int sc, String msg) 发送错误状态码及描述信息 参数校验失败时返回 400
void setHeader(String name, String value) 设置响应头信息 跨域支持(CORS)
void addCookie(Cookie cookie) 添加 Cookie 记住用户语言偏好
PrintWriter getWriter() 获取文本输出流 返回 JSON/HTML 内容
ServletOutputStream getOutputStream() 获取二进制输出流 返回图片/文件下载
void sendRedirect(String location) 重定向到新 URL 登录成功后跳转首页
void setContentType(String type) 设置内容类型(MIME 类型) application/json 或 image/png

代码示例 - 自定义响应头和返回二进制内容:

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    // 设置响应类型为图片
    response.setContentType("image/png");
    
    // 设置缓存头(缓存1小时)
    response.setHeader("Cache-Control", "max-age=3600");
    
    // 返回二维码图片字节流
    try (OutputStream out = response.getOutputStream()) {
        byte[] qrCode = generateQRCode("https://example.com");
        out.write(qrCode);
    } catch (IOException e) {
        response.sendError(500, "生成二维码失败");
    }
}

三、Spring MVC 中的实际应用

示例 1:RESTful API 参数接收

@RestController
@RequestMapping("/api")
public class UserApiController {
    
    // 获取查询参数和请求头
    @GetMapping("/user")
    public ResponseEntity<User> getUser(
            @RequestParam("id") Long userId,
            @RequestHeader("Authorization") String token) {
        
        // 验证Token逻辑
        if (!validateToken(token)) {
            return ResponseEntity.status(401).build();
        }
        
        User user = userService.findById(userId);
        return ResponseEntity.ok(user);
    }
}

示例 2:文件上传与重定向

@Controller
public class FileUploadController {
    
    @PostMapping("/upload")
    public String uploadFile(
            @RequestParam("file") MultipartFile file,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        
        // 检查文件大小
        if (file.getSize() > 10_000_000) { 
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return "error/400"; 
        }
        
        fileService.save(file);
        // 重定向到结果页
        response.sendRedirect("/upload-success");
        return null;
    }
}

四、关键差异总结

对比维度 HttpServletRequest HttpServletResponse
数据流向 服务器接收客户端数据 服务器向客户端发送数据
操作方法 信息读取类方法(getXxx) 数据写入类方法(setXxx/sendXxx)
内容处理 解析请求 URL、参数、头信息 设置响应状态、头信息、写入正文内容
生命周期 请求到达时创建,响应结束后销毁 同左

五、常见问题解答

问题 1:为何要同时使用这两个对象?

在一个完整的 HTTP 交互中:

  • HttpServletRequest: 了解客户端的请求细节(要什么)
  • HttpServletResponse: 构建服务器返回的响应(给什么)

协作流程示例

protected void doPost(HttpServletRequest request, HttpServletResponse response) {
    // 1. 通过request获取数据
    String input = request.getParameter("input");

    // 2. 业务处理
    String result = process(input);

    // 3. 通过response返回结果
    response.setContentType("text/plain");
    response.getWriter().write(result);
}

问题 2:如何在 Spring 中优雅地使用它们?

  • 最佳实践原则:优先使用 Spring 的抽象方式(如 @RequestParam@ResponseBody),必要时再直接操作原生对象。
@RestController
public class ModernController {
    // 通过注解自动映射参数
    @GetMapping("/search")
    public List<Product> searchProducts(
            @RequestParam String keyword,  // 自动从请求参数获取
            @CookieValue("sessionId") String sessionId,
            HttpServletResponse response) { // 需要设置Cookie时使用
        
        response.addCookie(new Cookie("lastSearch", keyword));
        return productService.search(keyword); // 自动转JSON
    }
}

总结

  • HttpServletRequest:客户端 → 服务器的信息桥梁,用于读取请求数据。
  • HttpServletResponse:服务器 → 客户端的信息出口,用于构造响应。
  • 核心技巧:在传统 Servlet 开发中直接使用它们,在 Spring 开发中优先通过注解简化操作,必要时才直接操作原生对象。