springboot 里做重定向,最核心的就是在 controller 方法里返回以 redirect: 开头的字符串,告诉浏览器去访问新的地址。默认是 302 临时重定向,浏览器地址栏会变成新地址。
⚙️ 基本用法
- 最简写法:返回
"redirect:/new-url",spring mvc 会识别这个前缀并生成 302 响应。 - 注意注解:类上必须用
@controller,不能用@restcontroller。因为@restcontroller会把返回的字符串当数据直接返回,不会触发重定向。
🔀 重定向 vs 转发
两者经常一起说,但完全是两回事:
- 重定向(redirect):服务端告诉浏览器“你去另一个地址”,浏览器会重新发起一次请求,共 2 次请求,地址栏会变化,可以跳到任意 url(包括外部链接)。
- 转发(forward):服务端内部把请求转给另一个资源处理,浏览器全程只发 1 次请求,地址栏不变,只能转发到本站点资源。
简单记:重定向是“客户重新排队”,转发是“服务端内部换人处理”。
🚀 常用实现方式
- 返回字符串(最常用):
return "redirect:/target"; - redirectview:需要更灵活控制时用,比如设置 301 状态码。
- httpservletresponse:在拦截器或过滤器里用
response.sendredirect("/target")比较直接。 - modelandview:设置
setviewname("redirect:/target")。
📦 重定向时传参
重定向是两次请求,request 域的数据会丢失,需要用下面两种方式:
- url 参数:用
redirectattributes.addattribute(),参数会拼到地址后面,适合分页、查询条件这类需要分享链接的数据。 - flash 属性:用
addflashattribute(),数据存在 session 里,重定向后只取一次自动清除,适合“操作成功”这类一次性提示,不会暴露在地址栏。
⚠️ 常见坑:重定向次数过多
如果出现这个报错,通常是登录拦截器或 spring security 把登录页本身也拦截了,导致 /login 和受保护页面之间来回 302 跳转死循环。
排查方向:
- 检查拦截器是否放行了
/login、静态资源路径。 - 检查 spring security 是否对
/login配置了permitall()。 - 浏览器一般重定向二三十次后会停止并报错,后端日志反而看不出异常,要看完整的 location 跳转链。
spring boot 重定向完全指南:从基础到实战
在 web 开发中,重定向是一种常见的技术手段,用于引导客户端从一个 url 跳转到另一个 url。无论是用户登录后的页面跳转、表单提交后的页面刷新避免重复提交,还是旧链接的迁移,都离不开重定向的支持。作为当前主流的 java 开发框架,spring boot 提供了多种简洁高效的重定向实现方式。本文将从基础概念出发,结合实际案例,全面讲解 spring boot 中重定向的实现方法、使用场景及注意事项,帮助开发者轻松掌握这一核心技能。
一、重定向基础:什么是重定向?为什么需要它?
在深入 spring boot 的具体实现之前,我们首先需要明确重定向的本质和应用场景,这有助于我们在实际开发中正确选择合适的实现方式。
1.1 重定向的定义
重定向(redirect)是指服务器接收客户端请求后,不直接返回请求的资源,而是返回一个特殊的响应(包含新的 url),告诉客户端 “请前往这个新地址获取资源”。客户端收到该响应后,会自动向新 url 发起第二次请求,最终获取目标资源并展示给用户。
从 http 协议角度看,重定向对应两种状态码:
- 302 found:临时重定向,表示目标 url 可能会随时变化,客户端后续请求仍需使用原 url。例如,用户未登录时访问需要权限的页面,临时重定向到登录页。
- 301 moved permanently:永久重定向,表明原 url 已被永久废弃,客户端应更新书签等记录,后续请求直接使用新 url。例如,网站域名变更后,旧域名永久重定向到新域名。
1.2 重定向的核心应用场景
在 spring boot 项目中,重定向的使用场景非常广泛,以下是几个典型案例:
- 用户认证与授权:用户未登录时访问受保护资源,重定向到登录页;登录成功后,重定向到首页或之前访问的页面。
- 表单提交后刷新防护:用户提交表单(如注册、下单)后,若直接返回页面,刷新浏览器会导致表单重复提交。通过重定向到结果页,可避免此问题。
- url 优化与迁移:旧版本的 url(如
/v1/user)需要迁移到新版本(如/v2/user),通过重定向可保证旧链接的可用性,同时引导用户使用新 url。 - 跨域资源访问:在某些跨域场景下,服务器可通过重定向将客户端引导到允许访问的域名下。
二、spring boot 重定向的 4 种实现方式
spring boot 基于 spring mvc,因此继承了 spring mvc 的重定向能力,同时提供了更简洁的配置。以下是 4 种常用的重定向实现方式,涵盖了从简单到复杂的场景。
2.1 方式 1:返回字符串(最简洁)
这是最基础、最常用的方式:在 controller 方法中直接返回以redirect:开头的字符串,后面跟上目标 url。spring mvc 会自动识别该前缀,并将其解析为重定向响应。
代码示例:基础重定向
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;
@restcontroller
public class redirectcontroller {
// 访问 /old-url 时,重定向到 /new-url
@getmapping("/old-url")
public string redirecttonewurl() {
// "redirect:" 是关键前缀,告诉spring这是重定向
return "redirect:/new-url";
}
// 目标url对应的接口
@getmapping("/new-url")
public string newurl() {
return "this is the new url page!";
}
}测试效果:
- 启动 spring boot 项目后,访问
http://localhost:8080/old-url。 - 浏览器地址栏会自动从
/old-url跳转到/new-url,页面显示this is the new url page!。 - 查看浏览器开发者工具(network 标签),可看到第一个请求的响应状态码为 302 found(默认临时重定向)。
扩展:指定重定向状态码
若需要实现永久重定向(301),可在返回字符串时通过redirect:${url};status=$[code]的格式指定状态码:
@getmapping("/permanent-old-url")
public string permanentredirect() {
// 永久重定向到 /permanent-new-url,状态码301
return "redirect:/permanent-new-url;status=301";
}
@getmapping("/permanent-new-url")
public string permanentnewurl() {
return "this is the permanently new url page!";
}2.2 方式 2:使用 redirectview(更灵活的配置)
redirectview是 spring mvc 提供的一个视图类,专门用于处理重定向。相比返回字符串,redirectview支持更灵活的配置,如设置状态码、是否上下文相对路径、是否暴露模型属性等。
代码示例:基于 redirectview 的重定向
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;
import org.springframework.web.servlet.view.redirectview;
@restcontroller
public class redirectviewcontroller {
@getmapping("/view-old")
public redirectview redirectwithview() {
// 1. 创建redirectview对象,指定目标url
redirectview redirectview = new redirectview("/view-new");
// 2. 配置重定向属性(可选)
redirectview.setstatuscode(httpstatus.permanent_redirect); // 设置状态码为301
redirectview.setcontextrelative(true); // 目标url是否为相对于当前上下文的路径(默认true)
redirectview.setexposemodelattributes(false); // 是否将模型属性暴露为查询参数(默认true)
return redirectview;
}
@getmapping("/view-new")
public string viewnew() {
return "this is the page from redirectview!";
}
}核心配置说明:
setstatuscode(httpstatus status):指定重定向状态码,如httpstatus.permanent_redirect(301)、httpstatus.found(302)。setcontextrelative(boolean contextrelative):若为true,目标 url 是相对于当前应用上下文的路径(如应用上下文为/my-app,则/view-new会解析为/my-app/view-new);若为false,则目标 url 是绝对路径。setexposemodelattributes(boolean expose):若为true,controller 中的模型属性会自动作为查询参数附加到目标 url 后(如model.addattribute("id", 1)会生成/view-new?id=1);若为false,则不附加。
2.3 方式 3:通过 httpservletresponse 手动重定向
在某些特殊场景下(如拦截器、过滤器中),我们可能需要直接操作httpservletresponse对象来实现重定向。这种方式更底层,灵活性最高,但需要手动处理响应头和状态码。
代码示例:手动重定向
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
@restcontroller
public class manualredirectcontroller {
@getmapping("/manual-old")
public void manualredirect(httpservletresponse response) throws ioexception {
// 1. 设置重定向状态码(302或301)
response.setstatus(httpservletresponse.sc_moved_temporarily); // 302临时重定向
// response.setstatus(httpservletresponse.sc_moved_permanently); // 301永久重定向
// 2. 设置location响应头,指定目标url
response.setheader("location", "/manual-new");
// 注意:若使用response.sendredirect(),会自动设置状态码和location头,代码更简洁
// response.sendredirect("/manual-new");
}
@getmapping("/manual-new")
public string manualnew() {
return "this is the page from manual redirect!";
}
}简化写法:使用response.sendredirect()
httpservletresponse提供了sendredirect()方法,可自动设置状态码(302)和location头,无需手动配置,代码更简洁:
@getmapping("/simple-manual-old")
public void simplemanualredirect(httpservletresponse response) throws ioexception {
// 直接调用sendredirect(),默认302重定向
response.sendredirect("/manual-new");
}适用场景:
- 拦截器(
handlerinterceptor):在prehandle()方法中,若用户未登录,可通过response.sendredirect()重定向到登录页。 - 过滤器(
filter):在过滤请求时,对不符合条件的请求进行重定向。
2.4 方式 4:重定向到外部 url(跨域名)
除了重定向到项目内部的 url,spring boot 也支持重定向到外部域名(如百度、github 等)。实现方式与内部重定向类似,只需将目标 url 改为完整的外部地址即可。
代码示例:重定向到外部 url
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;
@restcontroller
public class externalredirectcontroller {
// 方式1:返回字符串
@getmapping("/go-to-baidu")
public string gotobaidu() {
// 目标url为完整的外部地址
return "redirect:https://www.baidu.com";
}
// 方式2:使用redirectview
@getmapping("/go-to-github")
public redirectview gotogithub() {
redirectview redirectview = new redirectview("https://github.com");
redirectview.setstatuscode(httpstatus.permanent_redirect); // 301永久重定向
return redirectview;
}
}测试效果:
访问 http://localhost:8080/go-to-baidu,浏览器会自动跳转到百度首页;访问 http://localhost:8080/go-to-github,会跳转到 github 首页。
三、重定向中的参数传递
在实际开发中,重定向时往往需要传递参数(如用户 id、操作结果提示等)。由于重定向会发起第二次请求,请求域(request)中的参数会丢失,因此需要通过其他方式传递参数。以下是 3 种常用的参数传递方式。
3.1 方式 1:url 路径参数(推荐,直观)
将参数作为 url 的一部分(如/user/123),目标接口通过@pathvariable接收参数。这种方式直观、友好,且符合 restful 风格。
代码示例:
@getmapping("/user/old/{id}")
public string redirectwithpathparam(@pathvariable long id) {
// 将id作为路径参数传递到新url
return "redirect:/user/new/" + id;
}
@getmapping("/user/new/{id}")
public string getuserbyid(@pathvariable long id) {
return "user id from redirect: " + id;
}测试效果:
访问 http://localhost:8080/user/old/100,会重定向到 http://localhost:8080/user/new/100,页面显示 user id from redirect: 100。
3.2 方式 2:url 查询参数(简单,适合少量参数)
将参数作为查询参数(如/new-url?id=123&name=test)附加到目标 url 后,目标接口通过@requestparam接收参数。
代码示例:
@getmapping("/query/old")
public string redirectwithqueryparam() {
// 拼接查询参数
string userid = "200";
string username = "alice";
return "redirect:/query/new?id=" + userid + "&name=" + username;
}
@getmapping("/query/new")
public string getwithqueryparam(@requestparam long id, @requestparam string name) {
return "id: " + id + ", name: " + name;
}测试效果:
访问 http://localhost:8080/query/old,会重定向到 http://localhost:8080/query/new?id=200&name=alice,页面显示 id: 200, name: alice。
3.3 方式 3:使用 flash 属性(适合敏感 / 大量参数)
若参数较多或包含敏感信息(如表单数据),不适合通过 url 传递(会暴露在地址栏)。此时可使用 spring mvc 的flash 属性,它将参数存储在服务器端的flashmap中,仅在重定向的一次请求中有效,之后自动清除,安全性更高。
代码示例:
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.restcontroller;
import org.springframework.web.servlet.mvc.support.redirectattributes;
@restcontroller
@requestmapping("/flash")
public class flashattributecontroller {
// 重定向时设置flash属性
@getmapping("/old")
public string redirectwithflashattribute(
@requestparam string message,
redirectattributes redirectattributes) { // 注入redirectattributes
// 添加flash属性,参数仅在重定向的下一次请求中有效
redirectattributes.addflashattribute("successmessage", message);
return "redirect:/flash/new";
}
// 接收flash属性
@getmapping("/new")
public string getflashattribute(
// 通过@modelattribute接收flash属性
@org.springframework.web.bind.annotation.modelattribute("successmessage") string message) {
return "flash message from redirect: " + message;
}
}核心说明:
redirectattributes:spring 提供的专门用于重定向时传递属性的接口,addflashattribute()方法添加的属性会被存储在flashmap中,而非 url。@modelattribute:目标接口通过该注解接收 flash 属性,若属性不存在,会抛出bindexception,可通过@modelattribute(required = false)设置为非必需。
测试效果:
访问 http://localhost:8080/flash/old?message=operation+success,会重定向到 http://localhost:8080/flash/new,页面显示 flash message from redirect: operation success,且地址栏中无message参数。
四、常见问题与解决方案
在使用 spring boot 重定向时,开发者可能会遇到一些问题,以下是 3 个典型问题及对应的解决方案。
4.1 问题 1:重定向后参数丢失
现象:重定向时通过request.setattribute()设置的参数,在目标接口中无法获取。
原因:重定向会发起第二次请求,而request域的生命周期仅在一次请求中有效,第二次请求无法访问第一次请求的request域数据。
解决方案:
- 若参数较少,使用 url 路径参数或查询参数。
- 若参数较多或敏感,使用 flash 属性(
redirectattributes)。
4.2 问题 2:重定向到外部 url 时出现 404
现象:配置重定向到外部 url(如redirect:https://www.baidu.com)时,浏览器提示 404 错误。
原因:可能误将外部 url 写为相对路径(如redirect:www.baidu.com,缺少http://或https://),spring 会将其解析为项目内部的 url(如http://localhost:8080/www.baidu.com),导致 404。
解决方案:确保外部 url 是完整的绝对路径,包含http://或https://。
4.3 问题 3:flash 属性无法接收
现象:使用redirectattributes.addflashattribute()设置属性后,目标接口无法获取到该属性。
原因:
- 目标接口未使用
@modelattribute注解接收属性。 - 重定向后又发起了第三次请求(如刷新页面),flash 属性已被清除。
- 解决方案:
- 在目标接口中通过
@modelattribute("属性名")接收 flash 属性。 - 若需要参数长期有效,改用
session存储,而非 flash 属性。
五、总结
重定向是 spring boot web 开发中的核心技术之一,本文从基础概念到实战案例,详细讲解了 4 种重定向实现方式、3 种参数传递方法及常见问题解决方案。以下是关键知识点的总结:
- 实现方式选择:
- 简单场景:优先使用 “返回字符串”(
redirect:/url)。 - 需灵活配置(如状态码、模型属性):使用
redirectview。 - 拦截器 / 过滤器中:使用
httpservletresponse.sendredirect()。 - 跨域名跳转:使用完整外部 url(
redirect:https://xxx)。
- 参数传递选择:
- 少量、非敏感参数:url 路径参数或查询参数。
- 大量、敏感参数:flash 属性
到此这篇关于spring boot 重定向从基础到实战完全指南的文章就介绍到这了,更多相关springboot 重定向内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论