请求对象和响应对象

devtools/2025/3/1 11:17:56/

目录

一、Tomcat 请求响应

定义

二、HttpServletRequest基本功能

1.重要性

2.功能分类

3.获取请求头数据

方法

示例

结果:

4.其他请求相关方法

e.g

示例

结果:

三、HttpServletRequest获取参数

1.传递参数的方式

示例1

示例2(功能极为类似示例1)

 2.获取参数的方法

单值参数接收

多值参数接收

3.中文乱码处理

四、请求转发重定向示例

1.向客户端响应数据(基础)

2.请求转发

3.利用重定向实现向客户端相应数据(两种方式:临时重定向&重定向)

 五、高频面试题

转发和重定向的区别

1. 定义

请求转发(Forward)

重定向(Redirect)

2. 处理流程

3. 路径使用

相对路径

绝对路径

4. 其他区别


先前已经对请求转发和重定向(参见博客:请求转发和重定向_请求转发和重定向的代码-CSDN博客)有了核心基础的理解,而无论是请求转发还是重定向,它们都是基于请求响应模型的,所以这篇文章着重于请求对象和响应对象来做系统的梳理和示例演示。

一、Tomcat 请求响应

定义

Web服务器收到客户端的HTTP请求后,会为每次请求创建一个request对象和一个response对象。

request对象用于获取客户端提交的数据,response对象用于向客户端输出数据。

二、HttpServletRequest基本功能

1.重要性

HttpServletRequest是JavaWeb中非常重要的类,是Servlet的service()方法的参数之一。

2.功能分类

封装请求头数据(如获取请求头名称和值)。

封装请求正文数据(GET请求无正文)。

作为域对象,可以存储和获取数据。

支持请求转发和重定向。

3.获取请求头数据

方法

getHeader(String name):获取指定名称的请求头。

getHeaderNames():获取所有请求头名称。

示例

通过getHeaderNames()getHeader()遍历并输出所有请求头。

【注意:这里的项目用的是普通JavaWeb项目(不含maven的基础款),在这里我用的idea版本是2021版本,配置普通版本的JavaWeb项目需要创建普通Java项目后配置成JavaWeb项目(具体操作可以搜索相关文章),如果是用的2017版本的idea,那么配置JavaWeb基础项目有相关的选项,相较更为简单,但是2017版本的idea并没有自动导包的功能。】

java">package com.qcby.test;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;
/*** request对象的相关方法*/
@WebServlet(name = "Demo1Servlet",urlPatterns ="/demo1Servlet")
public class Demo1Servlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("doget.....");//获得请求头信息String  accept = request.getHeader("Accept");System.out.println("Accept:"+accept );String ua = request.getHeader("User-Agent");System.out.println("User-Agent:"+ua);System.out.println("=====================================");//获取所有头信息Enumeration<String> names = request.getHeaderNames();while(names.hasMoreElements()){String name = names.nextElement();String value = request.getHeader(name);System.out.println(name+":"+value);}}
}
结果:

 其实这里的结果就是请求标头里的内容:

4.其他请求相关方法

方法描述返回类型
getContentLength()获取请求正文的字节数(GET请求无正文,返回-1)。int
getContentType()获取请求的类型(如application/x-www-form-urlencoded)。String
getMethod()获取请求方法(如GETPOSTPUTDELETE等)。String
getLocale()获取客户端浏览器支持的语言环境(java.util.Locale对象)。Locale
getCharacterEncoding()获取请求的编码(默认为ISO-8859-1,未设置时返回null)。String
setCharacterEncoding(String code)设置请求的编码(仅对POST请求的正文有效)。void
getContextPath()获取上下文路径(如/项目名称)。String
getQueryString()获取请求URL中的参数部分(如name=zhangSan)。String
getRequestURI()获取请求的URI路径(如/hello/oneServlet)。String
getRequestURL()获取完整的请求URL路径(不包括参数部分)。StringBuffer
getServletPath()获取Servlet的路径(如/oneServlet)。String
getRemoteAddr()获取客户端的IP地址。String
getRemoteHost()获取客户端的主机名(通常返回IP地址)。String
getRemotePort()获取客户端的端口号。int
getScheme()获取请求协议(如httphttps)。String
getServerName()获取服务器的主机名(如localhost)。String
getServerPort()获取服务器的端口号(如808080)。int

e.g

示例

获取HTTP请求的各种信息

java">package com.qcby.test;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(name = "Demo2Servlet",urlPatterns = "/demo2Servlet")
public class Demo2Servlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().write("request.getContentLength(): " + request.getContentLength());response.getWriter().write("request.getContentType(): " + request.getContentType());response.getWriter().write("request.getContextPath(): " + request.getContextPath());response.getWriter().write("request.getMethod(): " + request.getMethod());response.getWriter().write("request.getLocale(): " + request.getLocale());response.getWriter().write("request.getQueryString(): " + request.getQueryString());response.getWriter().write("request.getRequestURI(): " + request.getRequestURI());response.getWriter().write("request.getRequestURL(): " + request.getRequestURL());response.getWriter().write("request.getServletPath(): " + request.getServletPath());response.getWriter().write("request.getRemoteAddr(): " + request.getRemoteAddr());response.getWriter().write("request.getRemoteHost(): " + request.getRemoteHost());response.getWriter().write("request.getRemotePort(): " + request.getRemotePort());response.getWriter().write("request.getScheme(): " + request.getScheme());response.getWriter().write("request.getServerName(): " + request.getServerName());response.getWriter().write("request.getServerPort(): " + request.getServerPort());}
}

结果:

三、HttpServletRequest获取参数

1.传递参数的方式

GET请求

  • 地址栏传递参数。

  • 超链接传递参数。

  • 表单传递参数。

POST请求

  • 表单传递参数。

示例1

获取和打印通过GET和POST方法发送的HTTP请求参数

java">package com.qcby.test;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.Arrays;
import java.util.Enumeration;
import java.util.Map;/*** request对象获取请求参数*/
@WebServlet(name = "Demo3Servlet",urlPatterns = "/demo3Servlet")
public class Demo3Servlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取get请求的参数String username = request.getParameter("username");String passsword = request.getParameter("password");System.out.println(username+" : "+passsword);Enumeration<String> names = request.getParameterNames();while(names.hasMoreElements()){String name = names.nextElement();String value = request.getParameter(name);System.out.println(name+":"+value);}}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");//前端传过来的都是String类型0String password = request.getParameter("password");System.out.println(username+" : "+password);String[] happy = request.getParameterValues("happy");System.out.println("happy:"+ Arrays.toString(happy));//第二种方式  获得到请求参数k和vMap<String, String[]> map = request.getParameterMap();//遍历所有键值对的键keyfor (String key : map.keySet()) {String[] values = map.get(key);System.out.println(key+":"+Arrays.toString(values));}}
}

假设有一个表单(可以将它写在JavaWeb项目运行后默认打开的index.jsp文件的<body>部分):

<form action="/项目名/demo3Servlet" method="post"><input type="text" name="username" value="user1"><input type="password" name="password" value="pass123"><input type="checkbox" name="happy" value="yes">Happy<input type="checkbox" name="happy" value="no">No Happy<input type="submit" value="Submit">
</form>

即:

当用户填写表单并提交时,

doPost方法会被触发,打印出以下内容:

但是普通情况下输入“localhost:8080/requestDemo/demo3Servlet?username=user1&password=pass123”(即走doGet()方法实现)

得到结果:

示例2(功能极为类似示例1)

java">package com.qcby.test;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.Arrays;
import java.util.Enumeration;
import java.util.Map;/*** request对象获取请求参数*/
@WebServlet(name = "Demo4Servlet",urlPatterns = "/demo4Servlet")
public class Demo4Servlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//post请求解决乱码request.setCharacterEncoding("UTF-8");String username = request.getParameter("username");//传统解决乱码问题//username=new String(username.getBytes("ISO-8859-1"),"UTF-8");System.out.println(username);System.out.println("================================================");//第二种方式  获得到请求参数k和vMap<String, String[]> map = request.getParameterMap();//遍历所有键值对的键keyfor (String key : map.keySet()) {String[] values = map.get(key);System.out.println(key+":"+Arrays.toString(values));}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取get请求的参数//get请求在tomcat8.5以上不会乱码,7.0以下需要使用传统方式解码String username = request.getParameter("username");System.out.println(username);System.out.println("=====================================");Enumeration<String> names = request.getParameterNames();while(names.hasMoreElements()){String name = names.nextElement();String value = request.getParameter(name);System.out.println(name+":"+value);}}
}

结果:

 2.获取参数的方法

getParameter(String name):获取单个参数值。

getParameterValues(String name):获取多个参数值。

getParameterNames():获取所有参数名称。

getParameterMap():获取所有参数的Map。

单值参数接收

通过getParameter()获取表单提交的单值参数。

多值参数接收

通过getParameterValues()获取表单提交的多值参数(如复选框)。

3.中文乱码处理

POST请求

  • 手动转码:先使用ISO-8859-1获取字节数组,再用UTF-8解码。

  • 设置编码:调用setCharacterEncoding("UTF-8")

GET请求

  • 手动转码:与POST请求类似。

  • 服务器配置:在Tomcat的server.xml中设置URIEncoding="UTF-8"

  • 注意:Tomcat 8.5及以上版本默认支持URL传递中文。

四、请求转发重定向示例

1.向客户端响应数据(基础)

java">package com.qcby.test;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(name = "RedpondrServlet1",urlPatterns = "/redpondrServlet1")
public class RedpondrServlet1 extends HttpServlet {//父类HttpServlet是抽象类并且包含抽象方法,那么继承该抽象类的子类必须实现父类中的所有抽象方法,否则子类也必须被声明为抽象类。protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");//用字符的方式响应数据   字符流  中文出现乱码response.getWriter().write("<h3>你好,世界!!</h3>"); //响应附带格式response.getWriter().write("你好,世界!!");}
}

得到结果:

2.请求转发

java">package com.qcby.test;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;/*** request对象获取请求参数*/
@WebServlet(name = "Demo5Servlet",urlPatterns = "/demo5Servlet")
public class Demo5Servlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");System.out.println(username);request.setAttribute("username","haha");request.getRequestDispatcher("/index.jsp").forward(request,response);System.out.println("========================================");}
}

 请求转发可以转发到任意的内部类(具体转发到哪里可以自行更改选择一个内部界面或其他)。

3.利用重定向实现向客户端相应数据(两种方式:临时重定向&重定向)

java">package com.qcby.test;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(name = "RedpondrServlet2",urlPatterns = "/redpondrServlet2")
public class RedpondrServlet2 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {/*** 第一种原理方式* 1,设置状态码  setStatus(302);* 2,设置响应头,重定向的请求地址  setHeader(location,/success.html)* 注意:地址的写法与请求转发不同因为重定向可以跨项目  地址两种写法1,绝对路径2,相对路径* 第二种方法* 重定向方式第二种自动设置状态码和头* response.sendRedirect("/success.html");*/response.setStatus(302);  //状态码 302:告诉客户端这是一个临时重定向。response.setHeader("location","http://www.chaoxing.com"); //响应头 Location:告诉客户端跳转到 http://www.chaoxing.com。//重定向方式第二种自动设置状态码和头//response.sendRedirect("/success.html");
//        response.sendRedirect("http://www.chaoxing.com");  //普通重定向}
}

结果(跳转超星平台):

 五、高频面试题

转发和重定向的区别

1. 定义

请求转发(Forward)
  • 在服务器内部将请求从一个Servlet转发到另一个Servlet或JSP页面。

  • 是服务器端的跳转,客户端浏览器地址栏不会发生变化。

重定向(Redirect)
  • 服务器通知客户端浏览器访问另一个地址,客户端浏览器重新发起请求

  • 是客户端的跳转,地址栏会显示新的地址。

2. 处理流程

流程请求转发重定向
客户端发送请求客户端发送请求到Servlet A客户端发送请求到Servlet A
Servlet处理Servlet A 调用request.getRequestDispatcher().forward(request, response)Servlet A 调用response.sendRedirect("目标地址")
服务器操作服务器内部将请求转发到目标资源(Servlet B或JSP页面)服务器返回一个302状态码和目标地址给客户端
客户端操作客户端浏览器地址栏不变,显示目标资源内容客户端浏览器根据目标地址重新发起请求,地址栏更新为新地址

3. 路径使用

相对路径
  • 转发和重定向中,相对路径的使用没有区别。

绝对路径

重定向

  • /表示服务器的根目录(如Tomcat的根目录)。

  • 示例:response.sendRedirect("/WebModule/login.jsp"),表示访问http://[hostname]:[port]/WebModule/login.jsp

请求转发

  • /表示当前Web应用程序的根目录。

  • 示例:request.getRequestDispatcher("/login.jsp").forward(request, response),表示访问当前应用下的/login.jsp

4. 其他区别

区别点请求转发重定向
地址栏变化地址栏不变地址栏更新为新地址
请求次数整个过程属于同一个请求客户端会向服务器发送两个请求
数据共享可以通过request作用域传递数据(request.setAttribute()无法使用request作用域,只能通过sessioncookie传递数据
效率更高效,因为只涉及一次请求相对低效,因为需要两次请求
跨域访问不能跨域,仅限于当前Web服务器内部可以跨域访问,客户端可以访问其他服务器
方法调用使用RequestDispatcher.forward(),属于HttpServletRequest使用response.sendRedirect(),属于HttpServletResponse
同源策略不涉及同源策略问题可能涉及同源策略问题(如跨域访问)

http://www.ppmy.cn/devtools/163601.html

相关文章

【jira】用到几张表

jira用到的几张表 测试计划&#xff0c;测试周期&#xff0c;测试用例&#xff0c;问题记录 1. 测试计划 # 记录表&#xff0c;查计划详情 SELECT ID,issuenum,SUMMARY FROM jiraissue where issuenum 22871# 测试计划下&#xff0c;测试周期&#xff0c;查测试周期id&…

RabbitMQ 集群部署方案

RabbitMQ 一、安装 RabbitMQ 二、更改配置文件 三、配置集群 四、测试 环境准备&#xff1a;三台服务器&#xff0c;系统是 CentOS7 IP地址分别是&#xff1a; rabbitmq1&#xff1a;192.168.152.71rabbitmq2&#xff1a;192.168.152.72rabbitmq3&#xff1a;192.168.152.…

微信小程序读取写入NFC文本,以及NFC直接启动小程序指定页面

一、微信小程序读取NFC文本(yyy优译小程序实现),网上有很多通过wx.getNFCAdapter方法来监听读取NFC卡信息,但怎么处理读取的message文本比较难找,现用下面方法来实现,同时还解决几个问题,1、在回调方法中this.setData不更新信息,因为this的指向问题,2、在退出页面时,…

GCN从理论到实践——基于PyTorch的图卷积网络层实现

Hi&#xff0c;大家好&#xff0c;我是半亩花海。图卷积网络&#xff08;Graph Convolutional Network, GCN&#xff09;是一种处理图结构数据的深度学习模型。它通过聚合邻居节点的信息来更新每个节点的特征表示&#xff0c;广泛应用于社交网络分析、推荐系统和生物信息学等领…

记一次生成core_dump文件的调查记录

1. 启用 core dump 在默认情况下&#xff0c;Linux 可能不生成 core dump 文件。要启用它&#xff0c;需要调整 shell 的 core dump 限制&#xff1a; 查看当前限制&#xff0c;执行命令&#xff1a; ulimit -c如果返回值为 0&#xff0c;则表示禁用了 core dump。 启用 co…

快速列出MS Word中所有可用字体

Word中有很多字体&#xff0c;虽然在字体下拉列表中提供了字体的样例&#xff0c;但是并不全面&#xff0c;例如使用Batang字体的话&#xff0c;数字会显示成什么效果&#xff0c;就无法直观的看到。 打开Word应用程序&#xff0c;新建一个空白文档&#xff0c;按AltF11打开VBE…

汽车悬架系统技术演进:从被动到全主动的革新之路(主动悬架类型对比)

在汽车工业的百年发展史中&#xff0c;悬架系统始终是平衡车辆性能与舒适性的关键战场。随着消费者对驾乘体验要求的不断提升&#xff0c;传统被动悬架已难以满足中高端车型的需求&#xff0c;而半主动与全主动悬架技术的崛起&#xff0c;正在重塑行业格局。本文将深入解析三大…

C++和OpenGL实现3D游戏编程【连载23】——几何着色器和法线可视化

欢迎来到zhooyu的C++和OpenGL游戏专栏,专栏连载的所有精彩内容目录详见下边链接: 🔥C++和OpenGL实现3D游戏编程【总览】 1、本节实现的内容 上一节课,我们在Blend软件中导出经纬球模型时,遇到了经纬球法线导致我们在游戏中模型光照显示问题,我们在Blender软件中可以通过…