Springboot redirect重定向传递参数

参考资料

  1. 【转载】关于重定向RedirectAttributes的用法
  2. RedirectAttributes 的使用
  3. 详解Spring中FlashMap


一. RedirecAtrributes传参

  • redirectAttributes.addAttributie("key", value);
    这种方法相当于在重定向链接地址追加传递的参数。
    以上重定向的方法等同于 return "redirect:/重定向目标页面url?key=value" ,注意这种方法直接将传递的参数暴露在链接地址上,非常的不安全,慎用。

  • redirectAttributes.addFlashAttributie("key", value);
    这种方法是隐藏了参数,链接地址上不直接暴露,但是能且只能在重定向的 “页面” 获取 param 参数值。其原理就是将设置的属性放到 session 中,session中的属性在重定向到目标页面后马上销毁。

1.1 前期准备

⏹配置文件

server:
  servlet:
    context-path: /jmw

⏹访问url

http://localhost:8080/jmw/test16/init?name=贾飞天&age=18

⏹test16.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <!--
        因为我们配置了 server.servlet.context-path 来指定项目路径,
        而使用 @{}的方式可以自动添加项目路径
        size=${param.size()},name=${param.name} 会渲染为 ?size=xxx&name=xxx
    -->
    <a th:href="@{/test16/changeView(size=${param.size()},name=${param.name})}">页面重定向</a>
</div>
</body>

⏹Thymeleaf渲染之后的效果

<a href="/jmw/test16/changeView?size=2&name=%E8%B4%BE%E9%A3%9E%E5%A4%A9">页面重定向</a>

⏹通过RedirectAttributes在重定向之前的页面放入要传递的数据

import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@GetMapping("/changeView")
public String changeView(@RequestParam String name, RedirectAttributes redirectAttributes) {

    System.out.println(name);  // 贾飞天
	
	// 准备重定向要传递的参数
    Map<String, String> mapParam = new HashMap<>();
    mapParam.put("key1", "110");
    mapParam.put("key2", "120");

    // 在重定向时,会将值放入session中,重定向到目标页面之后,会从session中清除
    redirectAttributes.addFlashAttribute("mapParam1", mapParam);
    // 相当于拼参数放在url后面
    redirectAttributes.addAttribute("param2", name);

    return "redirect:/test17/init";
}

1.2 重定向目标页面接收参数

  • 使用ModelMap来接收 redirectAttributes.addFlashAttribute() 中放入的数据
  • 也可以使用ModelAttribute来接收 redirectAttributes.addFlashAttribute() 中放入的数据
  • 使用@RequestParam来接收 redirectAttributes.addAttribute() 中放入的数据
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@Controller
@RequestMapping("/test17")
public class Test17Controller {

    @Resource
    private HttpServletRequest request;

    @GetMapping("/init")
    public ModelAndView init(
            // 使用ModelMap来接收 redirectAttributes.addFlashAttribute() 中放入的数据
            ModelMap mapParam1,
            // 也可以使用ModelAttribute来接收 redirectAttributes.addFlashAttribute() 中放入的数据
            @ModelAttribute("mapParam1") Map<String, String> mapParam2,
            // 使用@RequestParam来接收 redirectAttributes.addAttribute() 中放入的数据
            @RequestParam(value = "param2" ,required = false) String param2
    ) {

        System.out.println(mapParam1);  // {mapParam1={key1=110, key2=120}}
        System.out.println(param2);  // 贾飞天

        Map<String, String[]> parameterMap = request.getParameterMap();
        System.out.println(parameterMap);
        /*
        	param2=["贾飞天"]
		*/

        // 如果不为空,说明是从其他页面重定向过来的
        if (!mapParam1.isEmpty()) {

            // 两种获取方式相同
            Map mapParam_1 = (Map)mapParam1.getAttribute("mapParam1");
            System.out.println(mapParam_1.get("key1"));  // 110
            Map mapParam_2 = (Map)mapParam1.get("mapParam1");
            System.out.println(mapParam_2.get("key2"));  // 120
			
			// 将map放入request的Attribute中
            request.setAttribute("testMap", mapParam2);
        }

        // 指定跳转的页面
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("test17");
        return modelAndView;
    }
}

⏹前台页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <div>[[${param.param2}]]</div>

    <!--如果map中有值,才进行渲染-->
    <th:block th:if="${not #maps.isEmpty(testMap)}">
        <div>[[${testMap.key1}]]</div>
        <div>[[${testMap.key2}]]</div>
    </th:block>

</div>
</body>
<script th:inline="javascript">
    const testMap = [[${testMap}]];
    console.log(testMap);
</script>
</html>

在这里插入图片描述

二. FlashMap传参

  • 请求转发前后的request是同一个,所以可以在转发后通过request.getAttribute()拿到转发前通过request.setAttribute()放入的信息。
  • 重定向之后的request是新的,转发前通过request.setAttribute()放入的信息,转发后无法通过request.getAttribute()获取到。
  • FlashMap借助 session,重定向前通过 FlashMapManager 将信息放入FlashMap,
    重定向后 再借助 FlashMapManager 从 session中找到重定向后需要的 FalshMap,
    从而进行数据传递。
  • 重定向前通过FlashMap传参的页面,重定向后通过 Model 来获取数据。

2.1 DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE

在正常的request转发中,无法使用request携带参数。
所以Spring为了解决这个问题,FlashMap主要用于Redirect转发时的参数传递
我们只需要在redirect之前将需要传递的参数写入OUTPUT_FLASH_MAP_ATTRIBUTE中。
这样在redirect之后的handler中Spring会自动的设置到Model中。
然后就可以通过Model来获取重定向前页面设置的数据。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@Controller
@RequestMapping("/test22")
public class Test22Controller {

    @Resource
    private HttpServletRequest request;

    @GetMapping("/init")
    public ModelAndView init() {
    	
    	// 准备转发的数据
        Map<String, Integer> ageMap = Map.of("age", 28);
        FlashMap attribute = (FlashMap) request.getAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE);
        attribute.putAll(ageMap);
		
		// 转发
        RedirectView redirectView = new RedirectView("/test23/init");
        return new ModelAndView(redirectView);
    }
}

⏹转发后的效果

在这里插入图片描述


2.2 RequestContextUtils.getOutputFlashMap

  • RequestContextUtils是
    request.getAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE)的简单写法。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.view.RedirectView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@Controller
@RequestMapping("/test22")
public class Test22Controller {

    @Resource
    private HttpServletRequest request;

    @GetMapping("/init")
    public ModelAndView init() {
    	
    	// 准备转发的数据
        Map<String, String> nameMap = Map.of("name", "贾飞天");
        FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
        outputFlashMap.putAll(nameMap);
		
		// 转发
        RedirectView redirectView = new RedirectView("/test23/init");
        return new ModelAndView(redirectView);
    }
}

⏹转发后的效果

在这里插入图片描述

2.3 FlashMapManager

  • FlashMapManager是一个接口,定义了保存FlashMap和获取FlashMap的方法。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.SessionFlashMapManager;
import org.springframework.web.servlet.view.RedirectView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@RequestMapping("/test22")
public class Test22Controller {

    @Resource
    private HttpServletRequest request;

    @Resource
    private HttpServletResponse response;

    @GetMapping("/init")
    public ModelAndView init() {
    	
    	// 准备转发的数据
        FlashMap flashMap = new FlashMap();
        flashMap.put("address", "地球");
        FlashMapManager flashMapManager = new SessionFlashMapManager();
        flashMapManager.saveOutputFlashMap(flashMap, request, response);
        
        // 转发
        RedirectView redirectView = new RedirectView("/test23/init");
        return new ModelAndView(redirectView);
    }
}

⏹转发后的效果

在这里插入图片描述

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值