当前位置: 首页 > news >正文

Response对象

一、 Response设置响应数据

二、Response实现重定向

这会导致浏览器重新发起一次新的请求(第二次请求),所以用户能在地址栏看到跳转后的新地址。 


1、语法

response.sendRedirect("目标地址");

这个方法会返回一个状态码 302 Found,并在响应头中设置 Location

或者(比较麻烦的写法):

 


2、例子

示例1:重定向到同一个项目中的页面

response.sendRedirect("/myapp/login.jsp");

注意:这里的路径是以Web应用的根路径为起点,所以建议这样写:

response.sendRedirect(request.getContextPath() + "/login.jsp");

确保无论项目部署在哪,路径都能正确跳转


示例2:重定向到外部网站

response.sendRedirect("https://www.baidu.com");

3、和请求转发的区别

特性请求转发 forward()重定向 sendRedirect()
发出请求次数1 次2 次(浏览器又请求一次)
地址栏是否变化❌ 不变✅ 会变
是否共享 request 数据✅ 可以❌ 不可以(因为是两个请求)
是否只能跳转本项目✅ 是❌ 否,可以跳转外部网址
性能较高略低(多一次网络请求)
是否可以跳转到 WEB-INF✅ 可以❌ 不可以(浏览器无法访问 WEB-INF)

4、重定向过程图解

1. 浏览器请求 A↓
2. Servlet A 执行:response.sendRedirect("/home.jsp")↓
3. 服务器响应状态码 302,响应头 Location: /home.jsp↓
4. 浏览器再次请求 /home.jsp↓
5. 返回最终页面

重定向有两种:

        一种是302响应,称为临时重定向;

        一种是301响应,称为永久重定向。

两者的区别是,如果服务器发送301永久重定向响应,浏览器会缓存/hi/hello这个重定向的关联,下次请求/hi的时候,浏览器就直接发送/hello请求了。 

如果要实现301永久重定向,可以这么写:

resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); // 301
resp.setHeader("Location", "/hello");

5、重定向的常见使用场景

场景原因
登录成功后跳转主页避免表单重复提交
未登录用户跳转登录页地址栏要变
完成注册后跳到成功页显式通知用户新页面
跳转到外部页面只能用重定向

请求转发的典型重用场景:

场景原因 / 好处
表单提交失败回显可保留 request 中错误信息
Servlet → JSP 显示JSP 放在 WEB-INF 更安全
多 Servlet 组合调用数据共享,模块化开发
页面控制器统一跳转动态页面跳转
错误页面处理web.xml 中统一配置
登录拦截失败 → 登录页路径私有、数据传递

判断标准(记忆口诀):

“数据要共享 → 用转发,地址需变 → 用重定向”


6、注意事项

  • 重定向路径是客户端行为,必须是可被访问的 URL不能是 WEB-INF

  • 路径写法推荐加上 request.getContextPath(),避免部署路径问题

  • 重定向后不能再向浏览器输出内容(比如 response.getWriter().write(...)


7、总结:

response.sendRedirect() 是一种 客户端跳转,浏览器地址栏会改变,适合登录、退出、跳转外部页面等场景,但无法共享请求数据,不能访问 WEB-INF 中的资源

三、路径问题:是否需要加上虚拟目录

 

四、跨域的问题

1、什么是“跨域”?

跨域是指:浏览器中的 JavaScript 代码,请求了一个“不同源”的资源,就会触发浏览器的同源策略限制,从而引发跨域问题。


2、什么算“不同源”?

浏览器认为“源”由 三部分组成

协议(scheme) + 域名(host) + 端口(port)

只要这三者有任何一个不相同,就是跨域!


举例说明:

场景是否跨域原因
http://a.com 请求 http://a.com❌ 否同源
http://a.com 请求 http://a.com:8080✅ 是端口不同
http://a.com 请求 https://a.com✅ 是协议不同
http://a.com 请求 http://b.com✅ 是域名不同
http://localhost 请求 http://127.0.0.1✅ 是域名不同(即使指向同一台机器)

3、什么情况下会遇到跨域问题?

1. 浏览器中用 JavaScript 发请求(XHR、fetch、axios)

// 页面在 http://localhost:3000
fetch("http://localhost:8080/api/user"); // 跨域!不同端口

只有浏览器才有“同源策略”,所以你在:

  • Postman

  • curl

  • 后端服务器之间互相调用

是不会有跨域限制的!


2. 前端单独部署,后端单独部署

典型的开发结构:

  • 前端 Vue/React 项目:http://localhost:3000

  • 后端接口服务:http://localhost:8080

请求时就会报跨域问题(CORS error)。


常见错误提示:

Access to fetch at 'http://localhost:8080/api/user' 
from origin 'http://localhost:3000' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header...

4、跨域如何解决?

方法原理适用场景
✅ 设置响应头 Access-Control-Allow-Origin告诉浏览器:我允许你跨域来推荐方式,标准做法
反向代理由前端服务器转发请求比如用 Nginx 或 Vite 的 devServer.proxy
CORS 中间件后端框架(Spring Boot、Express 等)提供的跨域支持推荐

5、后端怎么设置 CORS(以 Java 为例)

Spring Boot:

@CrossOrigin(origins = "http://localhost:3000")
@RestController
public class MyController {@GetMapping("/api/user")public User getUser() {return new User("Tom");}
}

或全局配置:

@Configuration
public class CorsConfig {@Beanpublic WebMvcConfigurer config() {return new WebMvcConfigurer() {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("http://localhost:3000").allowedMethods("*");}};}
}

6、总结:

只要是浏览器中,JS 请求了一个“协议、域名或端口不同”的地址,就会有跨域问题。

解决跨域问题的根本方式是:后端允许这个请求源(设置 CORS 头),或前端使用代理绕过浏览器限制

五、Response设置响应体

  • 响应字符数据:response.getWriter()
  • 响应字节数据:response.getOutputStream()

 

5-1、响应字符数据

 

1. 设置响应内容类型(MIME)和编码

有时你需要设置额外的响应头,告诉浏览器怎么处理这段响应内容:

response.setContentType("text/html;charset=UTF-8");  // 返回 HTML
// 或者
response.setContentType("application/json;charset=UTF-8"); // 返回 JSON

【注意】:

Servlet 容器(比如 Tomcat)会设置默认Content-Type 响应头为 text/html;charset=ISO-8859-1,而浏览器默认会把响应体当作 HTML 解析。

 

若是不加Content-type的响应头,HTML标签默认会被解析,但是若是有中文会出现乱码!

2. 获取字符输出流并写出内容

PrintWriter writer = response.getWriter();
writer.write("<h1>Hello, Servlet!</h1>");
// 或写 JSON 字符串
writer.write("{\"status\": \"ok\"}");
writer.close();

示例:

@WebServlet("/responseDemo03")
public class ResponseDemo03 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=UTF-8");// // 必须放在 getWriter() 前面PrintWriter writer = resp.getWriter();// 放前了就会默认使用 ISO-8859-1 编码writer.write("<h1>Hello, Servlet!你好,世界</h1>");writer.write("{\"status\": \"ok\"}");writer.close();}
}

 ·

5-2、响应字节数据(如图片、文件下载)

1. 设置响应类型(以图片为例)

response.setContentType("image/png");

2. 获取字节输出流,写出二进制数据

ServletOutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream("d:/image.png");byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {out.write(buffer, 0, len);
}in.close();
out.close();

【注意】:

        写入完毕后调用flush()却是必须的,因为大部分Web服务器都基于HTTP/1.1协议,会复用TCP连接。

        如果没有调用flush(),将导致缓冲区的内容无法及时发送到客户端

        此外,写入完毕后千万不要调用close(),原因同样是因为会复用TCP连接,如果关闭写入流,将关闭TCP连接,使得Web服务器无法复用此TCP连接。 

六、IOUtils工具类

这个工具类在 Java 中做 IO 流操作非常方便和常用,尤其是你处理 Servlet 请求/响应、上传下载文件时,非常好用。


1、什么是 IOUtils?

IOUtils 是 Apache Commons IO 库中的一个工具类:

org.apache.commons.io.IOUtils

它封装了大量操作 InputStream、OutputStream、Reader、Writer 的静态方法,大大简化了 Java 原本冗长的 IO 操作。


2、常用功能(核心方法)

方法名作用
copy(InputStream in, OutputStream out)复制数据流
toString(InputStream in, Charset encoding)把流转为字符串
toByteArray(InputStream in)把流转为 byte[]
closeQuietly(...)安全关闭流,不抛异常
write(String str, OutputStream out, Charset encoding)写字符串到字节输出流
readLines(InputStream in, Charset encoding)一行一行读取流
contentEquals(InputStream a, InputStream b)比较两个流的内容是否一样

3、使用场景举例


1. Servlet 中读取请求体字符串

String jsonBody = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);

2. 下载文件(把文件流写到响应里)

InputStream in = new FileInputStream("d:/logo.png");
ServletOutputStream out = response.getOutputStream();
IOUtils.copy(in, out);
in.close();
out.close();

3. 上传文件:保存上传的 InputStream 到硬盘

InputStream fileStream = uploadedPart.getInputStream();
FileOutputStream out = new FileOutputStream("upload/xxx.jpg");
IOUtils.copy(fileStream, out);

4. 安全关闭流(避免 try-catch-finally)

IOUtils.closeQuietly(inputStream);  // 不会抛出 IOException

4、引入方式(依赖)

它属于 Apache 的 commons-io 工具包:

<!-- Maven 依赖 -->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version> <!-- 或最新版 -->
</dependency>
http://www.xdnf.cn/news/1080649.html

相关文章:

  • Excel 如何处理更复杂的嵌套逻辑判断?
  • 网安系列【4】之OWASP与OWASP Top 10:Web安全入门指南
  • Flink Vitess CDC 环境配置与验证
  • QString 转 varchar
  • 【网络与系统安全】域类实施模型DTE
  • 数字资产革命中的信任之锚:RWA法律架构的隐形密码
  • ORACLE 日常查询
  • 浏览器(Chrome /Edge)高效使用 - 内部命令/快捷键/启动参数
  • vue3 el-table 行筛选 设置为单选
  • python打卡day57@浙大疏锦行
  • C#引用类型
  • 代码随想录算法训练营第四十六天|动态规划part13
  • WPF_Reactive_控件调试方法
  • PortSwigger Labs SQLInjection LAB6-7
  • Golang 运算符
  • 3D建模公司的能力与技术
  • 【Spring Boot】Druid 连接池 YAML 配置详解
  • 三、docker软件安装:gitlab,nexus,mysql8,redis,nacos,nginx
  • Apache RocketMQ进阶之路阅读笔记和疑问
  • 高职院校“赛岗课”一体化网络安全实战类人才培养方案
  • python -二叉树路径和为指定的值(根节点到叶子节点)
  • 译码器Multisim电路仿真汇总——硬件工程师笔记
  • 【机器学习深度学习】什么是下游任务模型?
  • 【STM32实践篇】:I2C驱动编写
  • 【模糊集合】示例
  • 【机器学习深度学习】AI 项目开发流程:从需求到部署的五大阶段
  • 机器学习安装使用教程
  • Python训练营打卡Day59(2025.7.3)
  • java教程——初识guava(2)
  • 这才叫窗口查询!TDEngine官方文档没讲透的实战玩法