转发和重定向

本文详细介绍了SpringMVC中的转发和重定向概念及应用。转发发生在服务端,用于内部资源之间的调用,地址栏不变;重定向发生在客户端,涉及两次请求,地址栏会更新。文章通过实例代码对比了两者的不同,包括数据处理、参数传递和session数据的处理。

转发发生在服务端,重定向发生在客户端
Spring MVC 转发和重定向

1. 常规用法,返回一个view

这种十分常见,我们在Controller中处理相关数据之后会直接返回到对应的页面,将数据直接放在Model中然后直接返回字符串,然后经过视图解析器进行解析映射到对应的页面

 @RequestMapping("/login")
    public String login(@RequestParam String username,
                        @RequestParam String password,
                        Model model){
        System.out.println(username);
        System.out.println(password);
        model.setAttribute ("username",username);
        model.setAttribute("password",password);
        return "admin";
    }

在这里只是一次请求,发送/login请求,然后根据返回的字符串去查找相应的页面进行渲染
但是为什么放在session里的数据会失效?

2. springmvc请求重定向

有些时候我们需要在Controller中处理完数据之后,需要跳转到另一个Controller中进行相关操作,这个时候可以用请求转发和请求重定向

2.1 重定向

一个web资源收到客户端请求后,通知客户端(浏览器)去访问另外一个web资源,这称之为请求重定向。
是两次请求,浏览器地址栏会发生变化
在这里插入图片描述
基本使用

@PostMapping("/login")
    public String login(@RequestParam String username,
                        @RequestParam String password,
                        RedirectAttributes redirectAttributes){
        System.out.println(username);
        System.out.println(password);
        User user = userService.checkUser(username, password);
        if(user!=null){
            user.setPassword(null);
            session.setAttribute("user",user);
            System.out.println("true");
            return "adminindex";
        }else {
            redirectAttributes.addFlashAttribute("message","用户名或密码错误");
            return "redirect:/admin";
        }
    }

对于重定向时传递参数可以使用modelAndView来传递参数或者直接拼接Url进行带参重定向跳转,但是传递的参数会直接暴露在浏览器的链接地址上

return "redirect:/redirectController/redirectTest?name"+"aiqinhai"

所以通常是使用RedirectAttributes来进行重定向传参

redirectAttributes.addFlashAttribute("message","用户名或密码错误");
return "redirect:/admin";

session数据丢失

重定向是让浏览器发送新的请求到另一个controller进行执行,所以浏览器的地址会变化

2.2 请求转发

指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理
在这里插入图片描述
一次请求,地址栏不会变,Request是共享的
正是因为地址不会变化,所以表单提交后刷新页面会出现重复提交的现象

@RequestMapping(value="/testa", method=RequestMethod.GET)
public String inputData(){
    return "testa"; //Spring框架找到对应的View并渲染
}

@RequestMapping(value="/testa", method=RequestMethod.POST)
public String outputData(HttpServletRequest request){
    String userName = request.getParameter("name");
    String password = request.getParameter("pwd");
    request.setAttribute("name", userName);
    request.setAttribute("pwd", password);
    //转发到 /testb 的Controller方法(即outputDataX)上
    return "forward:/testb"; 
}

@RequestMapping(value="/testb", method=RequestMethod.POST)
public String outputDataX(HttpServletRequest request){
    return "testb";
}

打开testa网页:
在这里插入图片描述
输入用户名:spring,密码:spring:
在这里插入图片描述
点击登陆按钮,页面变为如下,浏览器的URL不变。
在这里插入图片描述
再次刷新,谷歌浏览器提示重新提交表单。
在这里插入图片描述

### ### 概念区别 在 HTTP 协议中,**转发(Forward)****重定向(Redirect)**是两种不同的请求处理机制。它们的主要区别在于请求的处理流程、客户端是否感知以及数据传递方式等方面。 转发是一种服务器内部的操作,指服务器接收到请求后,将该请求委托给其他资源(如 Servlet、JSP 等)进行处理,整个过程在服务器端完成。对于客户端而言,这一操作是透明的,客户端并不知道请求被转发到了其他资源。这种机制通常使用 `RequestDispatcher` 的 `forward()` 方法实现,在 Java Web 应用中较为常见[^4]。 与之不同的是,重定向是服务器通过发送特定的 HTTP 响应码(如 301、302)响应头中的 `Location` 字段,告知客户端需要重新发起一个新的请求到另一个 URL。客户端会收到重定向的指令,并根据新的 URL 再次发送请求。因此,重定向涉及两次独立的 HTTP 请求/响应交互。 ### ### 实现原理对比 在转发过程中,服务器将原始请求响应对象传递给目标资源,目标资源处理完成后将结果返回给服务器,再由服务器将响应返回给客户端。由于整个过程是在服务器端完成的,客户端浏览器地址栏显示的 URL 不会发生变化。 而重定向则是基于客户端行为实现的。当服务器决定执行重定向时,它不会直接返回最终内容,而是返回一个状态码新 URL。客户端浏览器接收到响应后,会自动向新的 URL 发起第二次请求,此时浏览器地址栏会更新为重定向后的 URL[^4]。 ### ### 数据传递方式 转发可以通过 `request` 对象携带属性信息,这些信息在整个请求范围内有效,因此目标资源可以获取到转发前设置的数据。这种方式适用于需要多个组件协作处理同一个请求的场景,例如权限验证之后转发到业务逻辑页面[^4]。 相比之下,重定向无法直接通过 `request` 对象传递数据,因为它是两个独立的请求。为了在重定向前后传递信息,通常采用 URL 参数、Cookie 或者 Session 的方式进行数据交换。例如,在 OAuth 授权流程中,服务端常常使用 `state` 参数来防止 CSRF 攻击,并确保请求来自原始发起方[^1]。 ### ### 用户体验差异 转发对用户是不可见的,浏览器地址栏始终显示最初请求的 URL,因此用户感知不到服务器内部的处理流程。而重定向会导致浏览器地址栏发生变化,用户可以看到跳转的过程,并且可以根据新 URL 直接访问目标资源。这也意味着重定向具有更强的可书签性(bookmarkable),适合用于资源移动或页面跳转等场景。 ### ### 使用场景示例 转发常用于将一个请求分发给不同的组件进行处理。例如在一个 Web 应用中,将用户登录请求先由一个 Servlet 进行初步验证,然后转发给另一个 Servlet 进行具体的业务逻辑处理,这样可以保持 URL 的一致性并减少网络往返次数。 重定向则多用于用户登录成功后跳转到首页、资源移动到新的 URL 后需要引导用户访问新地址等场景。例如,用户注册成功后,重定向到登录页面让用户进行登录操作,或者在支付完成后跳转至订单详情页。此外,重定向也常用于防止表单重复提交,通过 PRG(Post/Redirect/Get)模式实现幂等性[^4]。 ### 示例代码 以下是一个简单的 Java Servlet 示例,展示转发重定向的不同效果: ```java // 转发示例 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("message", "This is a forwarded message."); RequestDispatcher dispatcher = request.getRequestDispatcher("/target.jsp"); dispatcher.forward(request, response); } // 重定向示例 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { String redirectUrl = "https://example.com/new-location"; response.sendRedirect(redirectUrl); } ``` 在上述代码中,转发使用了 `RequestDispatcher.forward()` 方法,保留了原始请求上下文;而重定向通过 `HttpServletResponse.sendRedirect()` 方法触发客户端的新请求。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值