Java Web-Request与Response

在 Java Web 开发中,Request 和 Response 是两个非常重要的对象,用于在客户端和服务器之间进行请求和响应的处理,以下是详细介绍:

Request(请求对象)

Request继承体系

在 Java Web 开发中,通常涉及到的 request 对象主要是指 HttpServletRequest继承体系如下:

顶层接口:java.util.EventListener

虽然它不是直接与 HttpServletRequest 功能相关的父类,但从 Java 事件监听体系角度来说,它是很多相关类间接实现的接口。EventListener 是所有事件监听器接口必须实现的标记接口,不过在 HttpServletRequest 的直接继承体系中并不直接体现它的影响。

直接相关继承体系

  1. javax.servlet.ServletRequest 接口
    • 这是一个核心的基础接口,定义了所有 Servlet 请求对象必须实现的基本方法。这些方法提供了获取请求参数、属性、请求输入流等通用功能,使得 Servlet 能够处理客户端的请求数据。例如,getParameter(String name) 方法用于获取请求中的参数值。
  2. javax.servlet.http.HttpServletRequest 接口
    • 继承自 ServletRequest 接口,专门针对 HTTP 请求进行扩展。由于 HTTP 协议是 Web 应用中最常用的协议,HttpServletRequest 接口添加了许多与 HTTP 协议相关的方法。比如,getMethod() 可以获取 HTTP 请求的方法(如 GET、POST 等);getHeader(String name) 用于获取 HTTP 请求头信息。
  3. 具体实现类
    • 在不同的 Servlet 容器(如 Tomcat、Jetty 等)中,会有具体的 HttpServletRequest 实现类。以 Tomcat 为例,它的实现类是 org.apache.catalina.connector.RequestFacade。这些实现类会实现 HttpServletRequest 接口定义的所有方法,完成具体的请求处理逻辑。当客户端发起请求时,Servlet 容器会创建该实现类的对象,并将其作为参数传递给 Servlet 的处理方法(如 doGetdoPost),让开发者可以通过这个对象来处理请求。

需要注意的是,从 Servlet 4.0 开始,包名从 javax.servlet 变更为 jakarta.servlet,所以对应的接口变为 jakarta.servlet.ServletRequest 和 jakarta.servlet.http.HttpServletRequest,但继承体系的逻辑结构保持不变。

  • 概念Request 对象封装了客户端发送给服务器的请求信息,包括请求头、请求参数、请求方法等。在 Servlet 开发中,常见的实现类是 HttpServletRequest它提供了一系列方法来获取请求相关的数据。
  • 主要方法及作用
    • 获取请求参数
      • getParameter(String name):根据参数名获取单个参数值,如 String username = request.getParameter("username");,常用于获取表单提交的单个数据。
      • getParameterValues(String name):获取指定参数名的所有值(适用于复选框等会提交多个值的情况),返回一个字符串数组。
      • getParameterMap():获取所有请求参数,返回一个 Map<String, String[]>,其中键是参数名,值是参数值数组。
    • 获取请求头信息getHeader(String name) 用于根据头名称获取请求头的值,例如 String userAgent = request.getHeader("User - Agent"); 可获取客户端浏览器信息。
    • 获取请求方法getMethod() 方法返回客户端发送请求的 HTTP 方法,如 "GET"、"POST" 等。
    • 解决乱码问题:对于 POST 请求,可通过 setCharacterEncoding("UTF - 8"); 设置字符编码来解决参数乱码问题。对于 GET 请求,有时需要额外的编码转换操作。
    • 请求转发getRequestDispatcher(String path).forward(request, response); 可实现请求转发,将当前请求转发到另一个资源(Servlet、JSP 等),转发过程在服务器端完成,客户端地址栏不变。
    • package com.itheima.web;
      
      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.BufferedReader;
      import java.io.IOException;
      
      import static javax.servlet.http.HttpUtils.getRequestURL;
      
      @WebServlet("/req1")
      public class RequestDemo1 extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //String getMethod()  获取请求方式:GET
              String method = req.getMethod();
              System.out.println("method:" + method);//GET
              //String getContextPath():获取虚拟目录(项目访问路径):/webDemo
              String contextPath = req.getContextPath();
              System.out.println(contextPath);
              //StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/webDemo/req1
              StringBuffer requestURL = req.getRequestURL();
              System.out.println(requestURL.toString());
              //String getReQuestURI():获取URI(统一资源标识符):/webDemo/req1
              String requestURI = req.getRequestURI();
              System.out.println(requestURI);
              //String getQueryString():获取请求参数(GET方式):username=zhangsan
              String queryString = req.getQueryString();
              System.out.println(queryString);
      
      
              //-----------
              //获取请求头:user-agent:浏览器的版本信息
              String agent = req.getHeader("user-agent");
              System.out.println(agent);
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              
              // 获取Post请求信息用的是IO流,最后打印信息
              BufferedReader reader = req.getReader();
              String line = reader.readLine();
              System.out.println(line);
          }
      
      }
      

Response(响应对象)

  • 概念Response 对象用于封装服务器对客户端请求的响应信息,服务器通过它向客户端发送响应状态码、响应头和响应体等内容。在 Servlet 开发中,常见的实现类是 HttpServletResponse
  • 主要方法及作用
    • 设置响应状态码setStatus(int sc) 用于设置 HTTP 响应状态码,如 response.setStatus(200); 表示请求成功,response.setStatus(404); 表示资源未找到。
    • 设置响应头setHeader(String name, String value) 用于设置响应头字段,如 response.setHeader("Content - Type", "text/html;charset=UTF - 8"); 设置响应内容类型和字符编码;response.setHeader("Location", "new - url"); 配合 302 状态码用于重定向。
    • 重定向sendRedirect(String location) 方法可实现重定向功能,它会设置状态码为 302,并设置 Location 响应头,让客户端重新请求指定的 URL,客户端地址栏会改变。
    • 获取输出流
      • getWriter():获取字符输出流 PrintWriter,用于向客户端输出文本数据,如 HTML、JSON 等。
      • getOutputStream():获取字节输出流 ServletOutputStream,用于输出二进制数据,如图片、文件等。但要注意,getWriter() 和 getOutputStream() 不能同时使用。

 如何使用Request和Response对象

在 Java Web 开发中,HttpServletRequest 和 HttpServletResponse 对象是处理客户端请求和发送服务器响应的核心工具。以下详细介绍它们的常见使用场景和示例代码:

1. 获取请求参数

使用 HttpServletRequest 对象可以方便地获取客户端请求中携带的参数。

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;

@WebServlet("/paramDemo")
public class ParamDemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取单个参数
        String username = request.getParameter("username");
        // 获取多个参数(如复选框)
        String[] hobbies = request.getParameterValues("hobby");

        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().println("用户名: " + username);
        if (hobbies != null) {
            response.getWriter().println("爱好: ");
            for (String hobby : hobbies) {
                response.getWriter().println(hobby);
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 解决POST请求中文乱码问题
        request.setCharacterEncoding("UTF-8");
        doGet(request, response);
    }
}

2. 获取请求头信息

可以使用 HttpServletRequest 对象获取客户端请求头中的各种信息。

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;

@WebServlet("/headerDemo")
public class HeaderDemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取指定请求头
        String userAgent = request.getHeader("User-Agent");
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().println("User-Agent: " + userAgent);
    }
}

3. 请求转发

请求转发是服务器内部的一种资源跳转方式,使用 RequestDispatcher 实现。

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;

@WebServlet("/forwardDemo")
public class ForwardDemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置请求属性
        request.setAttribute("message", "这是转发传递的消息");
        // 获取RequestDispatcher对象
        request.getRequestDispatcher("/targetServlet").forward(request, response);
    }
}

@WebServlet("/targetServlet")
public class TargetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取请求属性
        String message = (String) request.getAttribute("message");
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().println("接收到的消息: " + message);
    }
}

4. 重定向

重定向会让客户端重新向新的 URL 发送请求,使用 HttpServletResponse 的 sendRedirect 方法。

package com.itheima.web;

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;

//本类演示重定向

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("resp1...");

        // 重定向

//第一种方法
    //1. 设置响应状态码 302
        resp.setStatus (302);
    //2. 设置响应头 Location
        resp.setHeader ("Location","/webDemo/resp2");
//第二种方法
  // 简化方式完成重定向
        resp.sendRedirect ("/webDemo/resp2");
    }
}

5. 设置响应头和响应体

使用 HttpServletResponse 对象可以设置响应头信息和向客户端输出响应体内容。

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;

@WebServlet("/responseDemo")
public class ResponseDemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应头
        response.setContentType("text/html;charset=UTF-8");
        response.setHeader("Cache-Control", "no-cache");

        // 获取字符输出流,输出响应体
        response.getWriter().println("<html><body>");
        response.getWriter().println("<h1>这是一个响应示例</h1>");
        response.getWriter().println("</body></html>");
    }
}

Response响应字节数据

发送字节数据

当需要发送二进制数据,如图片、音频、视频等时,使用 ServletOutputStream 来发送字节数据。以下是一个简单的示例,展示如何从服务器读取图片文件并将其作为字节数据发送给客户端:

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.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

@WebServlet("/sendByteData")
public class SendByteDataServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应内容类型为图片类型
        response.setContentType("image/jpeg");

        // 获取要发送的图片文件的输入流
        InputStream inputStream = new FileInputStream("path/to/your/image.jpg");

        // 获取响应的输出流
        OutputStream outputStream = response.getOutputStream();

        // 定义缓冲区
        byte[] buffer = new byte[1024];
        int bytesRead;
        // 从输入流读取数据并写入输出流
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }

        // 关闭输入流
        inputStream.close();
    }
}

代码解释

  1. 设置响应内容类型:通过 response.setContentType("image/jpeg") 设置响应内容类型为 JPEG 图片类型,让客户端知道接收到的是图片数据。
  2. 获取输入流和输出流:使用 FileInputStream 打开要发送的图片文件,获取文件的输入流;通过 response.getOutputStream() 获取响应的输出流,用于将数据发送给客户端。
  3. 数据传输:使用一个缓冲区 byte[] buffer 从输入流读取数据,并将其写入输出流,直到文件读取完毕。
  4. 关闭输入流:操作完成后,关闭输入流以释放资源。

Response响应字符数据

发送字符数据

当需要发送文本数据,如 HTML、JSON、纯文本等时,使用 PrintWriter 来发送字符数据。以下是一个示例,展示如何向客户端发送一段 HTML 内容:

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.io.PrintWriter;

@WebServlet("/sendCharData")
public class SendCharDataServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应内容类型和字符编码
        response.setContentType("text/html;charset=UTF-8");

        // 获取响应的字符输出流
        PrintWriter writer = response.getWriter();

        // 向输出流写入 HTML 内容
        writer.println("<html>");
        writer.println("<head><title>字符数据响应示例</title></head>");
        writer.println("<body>");
        writer.println("<h1>这是一段 HTML 内容</h1>");
        writer.println("</body>");
        writer.println("</html>");

        // 刷新输出流
        writer.flush();

        // 关闭输出流
        writer.close();
    }
}

代码解释

  1. 设置响应内容类型和字符编码:通过 response.setContentType("text/html;charset=UTF-8") 设置响应内容类型为 HTML 文本,并指定字符编码为 UTF - 8,确保中文等字符能正确显示。
  2. 获取字符输出流:使用 response.getWriter() 获取响应的字符输出流 PrintWriter
  3. 写入数据:使用 writer.println() 方法向输出流写入 HTML 内容。
  4. 刷新和关闭输出流:调用 writer.flush() 方法将缓冲区的数据刷新到客户端,最后关闭输出流以释放资源。

需要注意的是,getOutputStream() 和 getWriter() 方法不能同时使用,否则会抛出 IllegalStateException 异常。

通过以上示例,你可以了解到 HttpServletRequest 和 HttpServletResponse 在不同场景下的基本使用方法,它们是 Java Web 开发中处理请求和响应的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/959601.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql 学习2 MYSQL数据模型,mysql内部可以创建多个数据库,一个数据库中有多个表;表是真正放数据的地方,关系型数据库 。

在第一章中安装 &#xff0c;启动mysql80 服务后&#xff0c;连接上了mysql&#xff0c;那么就要 使用 SQL语句来 操作mysql数据库了。那么在学习 SQL语言操作 mysql 数据库 之前&#xff0c;要对于 mysql数据模型有一个了解。 MYSQL数据模型 在下图中 客户端 将 SQL语言&…

微信小程序date picker的一些说明

微信小程序的picker是一个功能强大的组件&#xff0c;它可以是一个普通选择器&#xff0c;也可以是多项选择器&#xff0c;也可以是时间、日期、省市区选择器。 官方文档在这里 这里讲一下date picker的用法。 <view class"section"><view class"se…

【学习笔记】计算机网络(二)

第2章 物理层 文章目录 第2章 物理层2.1物理层的基本概念2.2 数据通信的基础知识2.2.1 数据通信系统的模型2.2.2 有关信道的几个基本概念2.2.3 信道的极限容量 2.3物理层下面的传输媒体2.3.1 导引型传输媒体2.3.2 非导引型传输媒体 2.4 信道复用技术2.4.1 频分复用、时分复用和…

总结8..

#include <stdio.h> // 定义结构体表示二叉树节点&#xff0c;包含左右子节点编号 struct node { int l; int r; } tree[100000]; // 全局变量记录二叉树最大深度&#xff0c;初始为0 int ans 0; // 深度优先搜索函数 // pos: 当前节点在数组中的位置&#xff0c…

多智能体中的理论与传统智能体理论有何异同?

多智能体系统与传统单智能体理论在多个方面存在异同&#xff0c;多智能体系统在理论上扩展了单智能体系统的研究范畴&#xff0c;强调智能体之间的交互和协作。随着人工智能、人机智能、人机环境系统智能的发展&#xff0c;多智能体系统在机器人群体、分布式计算、资源管理等领…

RKNN_C++版本-YOLOV5

1.背景 为了实现低延时&#xff0c;所以开始看看C版本的rknn的使用&#xff0c;确实有不足的地方&#xff0c;请指正&#xff08;代码借鉴了rk官方的仓库文件&#xff09;。 2.基本的操作流程 1.读取模型初始化 // 设置基本信息 // 在postprocess.h文件中定义&#xff0c;详见…

FlinkSql使用中rank/dense_rank函数报错空指针

问题描述 在flink1.16(甚至以前的版本)中&#xff0c;使用rank()或者dense_rank()进行排序时&#xff0c;某些场景会导致报错空指针NPE(NullPointerError) 报错内容如下 该报错没有行号/错误位置&#xff0c;无法排查 现状 目前已经确认为bug&#xff0c;根据github上的PR日…

csapp2.4节——浮点数

目录 二进制小数 十进制小数转二进制小数 IEEE浮点表示 规格化表示 非规格化表示 特殊值 舍入 浮点运算 二进制小数 类比十进制中的小数&#xff0c;可定义出二进制小数 例如1010.0101 小数点后的权重从-1开始递减。 十进制小数转二进制小数 整数部分使用辗转相除…

【2024年华为OD机试】 (A卷,200分)- 开放日活动、取出尽量少的球(JavaScriptJava PythonC/C++)

一、问题描述 题目描述 某部门开展Family Day开放日活动,其中有个从桶里取球的游戏,游戏规则如下: 有N个容量一样的小桶等距排开。每个小桶默认装了数量不等的小球,记录在数组 bucketBallNums 中。游戏开始时,要求所有桶的小球总数不能超过 SUM。如果小球总数超过 SUM,…

《安富莱嵌入式周报》第349期:VSCode正式支持Matlab调试,DIY录音室级麦克风,开源流体吊坠,物联网在军工领域的应用,Unicode字符压缩解压

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; 《安富莱嵌入式周报》第349期&#xff1a;VSCode正式支持Matlab调试&#xff0c;DIY录音室级麦克风…

nacos(基于docker最详细安装)

1、什么是Spring Cloud Spring Cloud是一系列框架的集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发&#xff0c;如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等&#xff0c;都可以用Spring Boot的开发风格做到一键启动和部署。…

李沐vscode配置+github管理+FFmpeg视频搬运+百度API添加翻译字幕

终端输入nvidia-smi查看cuda版本 我的是12.5&#xff0c;在网上没有找到12.5的torch&#xff0c;就安装12.1的。torch&#xff0c;torchvision&#xff0c;torchaudio版本以及python版本要对应 参考&#xff1a;https://blog.csdn.net/FengHanI/article/details/135116114 创…

Java Web-Tomcat Servlet

Web服务器-Tomcat Web服务器简介 Web 服务器是一种软件程序&#xff0c;它主要用于在网络上接收和处理客户端&#xff08;如浏览器&#xff09;发送的 HTTP 请求&#xff0c;并返回相应的网页内容或数据。以下是关于 Web 服务器的详细介绍&#xff1a; 功能 接收请求&#…

An OpenGL Toolbox

3.An OpenGL Toolbox 声明&#xff1a;该代码来自&#xff1a;Computer Graphics Through OpenGL From Theory to Experiments&#xff0c;仅用作学习参考 3.1 Vertex Arrays and Their Drawing Commands 顶点数组及其绘制命令&#xff1a;将几何数据存储在一个位置&#xff0c…

GCC之编译(8)AR打包命令

GCC之(8)AR二进制打包命令 Author: Once Day Date: 2025年1月23日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章请查看专栏: Linux实践记录_Once-Day的博客-C…

【miniconda】:langraph的windows构建

langraph需要python3.11 langraph强烈建议使用py3.11 默认是3.12 官方 下载仓库 下载老版本的python (后续发现新版miniconda也能安装老版本的python) 在这里

微信小程序中常见的 跳转方式 及其特点的表格总结(wx.navigateTo 适合需要返回上一页的场景)

文章目录 详细说明总结wx.navigateTo 的特点为什么 wx.navigateTo 最常用&#xff1f;其他跳转方式的使用频率总结 以下是微信小程序中常见的跳转方式及其特点的表格总结&#xff1a; 跳转方式API 方法特点适用场景wx.navigateTowx.navigateTo({ url: 路径 })保留当前页面&…

python3+TensorFlow 2.x(四)反向传播

目录 反向传播算法 反向传播算法基本步骤&#xff1a; 反向中的参数变化 总结 反向传播算法 反向传播算法&#xff08;Backpropagation&#xff09;是训练人工神经网络时使用的一个重要算法&#xff0c;它是通过计算梯度并优化神经网络的权重来最小化误差。反向传播算法的核…

深度学习 Pytorch 单层神经网络

神经网络是模仿人类大脑结构所构建的算法&#xff0c;在人脑里&#xff0c;我们有轴突连接神经元&#xff0c;在算法中&#xff0c;我们用圆表示神经元&#xff0c;用线表示神经元之间的连接&#xff0c;数据从神经网络的左侧输入&#xff0c;让神经元处理之后&#xff0c;从右…

使用vscode + Roo Code (prev. Roo Cline)+DeepSeek-R1使用一句话需求做了个实验

摘要 使用vscode、Roo Code和deepseek-reasoner进行了一个实验&#xff0c;尝试使用一句话需求来生成小红书封面图片。工具根据需求提供了详细的架构方案&#xff0c;包括技术栈选择、核心模块划分、目录结构建议等。然后&#xff0c;工具自动化地完成了开发和测试&#xff0c;…