SpringMVC中重定向数据转发

大家好,前一段时间,对SpringMVC的源码进行了一段时间的学习,虽然并不深入,但是也略有收获,今天和大家分享一些在学习过程中学习到的实用技巧。首先一点就是SpringMVC如何在进行请求重定向时进行数据传递。
写过网站服务的朋友们,肯定都接触过请求重定向和请求转发,由于今天重点并不是分析这两点,所以并不会进行详细的解释,其中区别呢主要是在请求的方式上,简要来说重定向是客户端行为,而转发是服务器行为,在重定向过程中,客户端进行两次请求,但是在请求转发过程中,客户端进行一次请求,但是在服务器上会进行多次请求,
重定向示意图如下:
这里写图片描述
请求转发示意图如下:
这里写图片描述
很显然,在重定向过程中,客户端发发起了两次请求,也就是两个request,那么问题就来了,在我们使用SpringMVC时,我们的代码通常是如下:

@Controller
@RequestMapping("/bbb")
public class ChartController extends BaseController {
    @RequestMapping("/aaa")
    @ResponseBody
    public void getDepartFlightStatisticShow(int limit) {
       //进行逻辑处理
    }
}

我们可以看到,在方法参数中有一个limit参数,这个参数是随着request请求被封装的,也就是说,这个参数从客户端到服务端,是封装在request中的,当进行请求重定向时,就会因为发起不同的请求而在后面的请求中丢失掉,或者也可以理解为,我们想在方法体中进行重定向,并且将方法中的参数进行传递,那么我们封装在request中是不起作用的,那么问题发现了,有没有什么方法解决呢?当然是有的,那就是把参数放在比request更高一级的对象中,没错,就是session。
关于session我们不做过多的介绍,可以简单理解为客户端和服务器的持续性链接,只要session存活,那么客户端就可以和服务器进行会话。那么SpringMVC是怎么将我们想要转发的对象存在session中的呢?如下代码:


    @RequestMapping("/test")
    public String test(RedirectAttributes attributes) {
        attributes.addFlashAttribute("name", "zonglin.zhang");
        attributes.addAttribute("language", "Chinese");
        return "redirect:/test2";
    }

    @RequestMapping("/test2")
    public void test2(Model model) {
        System.out.println(model.asMap().get("name"));
    }

我们看到,在我们请求test时,在方法中进行了请求转发,但是在这之前,我们在参数中传递了一个RedirectAttributes类型的参数,并且在参数中设置了两个内容:name和language,在转发后的test2中进行了输出,使用这种方法就可以进行重定向时的数据转发。大家可能有疑问,RedirectAttributes类型的参数是怎样传递的,其实这个参数不需要我们在调用test时进行传递,这是SpringMVC自己给我们提供的参数,但是我们也可以发现不同点,就是

  attributes.addFlashAttribute("name", "zonglin.zhang");
  attributes.addAttribute("language", "Chinese");

这两行代码,我们可以看到调用的方法并不相同,有什么区别呢?其实在RedirectAttributes中,存在一个Map类型的对象,SpringMVC中的实现是FlashMap,我们调用addFlashAttribute()时就是将对象存在了这个MAP中,但是在调用addAttribute()方法时,我们并没有对参数进行MAP的存储,而是将对象写在了url中,所以在重定向的过程中,我们看到的就是在url上有language参数。
那么说了这么多,SpringMVC中对这个参数是怎么使用的呢?我们需要看一下SpringMVC中最为核心的一个类DispatcherServlet中的doService()方法:

FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE,Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

由于篇幅限制,我们只写出我们要讲解的部分代码,有兴趣的朋友可以去参看SpringMVC源码。
我们看到我们在这里为Request设置了三个参数,两个是FlashMap,一个是管理类。作用是什么呢?
比如说我们将表单post提交到了一个请求上去,但是为了避免重复提交,我们将求情redirect到了一个GET请求中,但是很显然,我们希望在GET请求中得到表单信息,按照通常的方式,我们可以将请求写到url中,但是url长度存在限制,就会出现问题,所以我们将数据存储在了FlashMap中,INPUT_FLASH_MAP_ATTRIBUTE参数代表我们要接收的重定向FlashMao,而OUTPUT_FLASH_MAP_ATTRIBUTE代表我们要输出的重定向FalshMap,这样就可以进行数据的重定向转发了。当然实际实现要复杂很多,大家可以自行研究。我的分享就只有这些了,如有不妥之处,还请大家多多指教。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值