当前位置 博文首页 > blackball1998的博客:转发和重定向中携带变量

    blackball1998的博客:转发和重定向中携带变量

    作者:[db:作者] 时间:2021-06-19 19:55

    转发和重定向中携带变量

    有时候我们需要在转发中或者重定向中携带变量,并且在转发或者重定向到的请求方法中获取变量,Spring MVC都可以帮我们做到这两点

    转发中携带变量

    当我们需要在转发中携带变量和获取变量时,我们可以使用以下几种方式

    原生HttpServletRequest类

    使用原生的HttpServletRequest类,可以做到在转发中携带变量,也可以使用他来获取变量

    携带变量时,将HttpServletRequest类添加在请求方法的参数列表中,然后调用setAttribute方法就可以将变量以键值对的方式保存在request域中

    @Controller
    public class MyController {
    
        @RequestMapping("/user")
        public String queryUser(HttpServletRequest request) {
            request.setAttribute("name","cong");
            request.setAttribute("age",18);
            return "forward:/other";
        }
    }
    

    获取request域中的变量也是同样的使用方式,将HttpServletRequest类添加在请求方法的参数列表中,然后调用getAttribute方法

    @Controller
    public class MyController {
    
        @RequestMapping("/user")
        public String queryUser(HttpServletRequest request) {
            request.setAttribute("name", "cong");
            request.setAttribute("age", 18);
            return "forward:/other";
        }
    
        @RequestMapping("/other")
        @ResponseBody
        public Map<String, Object> other(HttpServletRequest request) {
            Object name = request.getAttribute("name");
            Object age = request.getAttribute("age");
            HashMap<String, Object> result = new HashMap<>();
            result.put("name", name);
            result.put("age", age);
            return result;
        }
    }
    

    我们将request域中的变量获取到,然后封装成一个Map类返回前端,方便我们测试

    在这里插入图片描述

    测试结果HttpServletRequest类在第一个请求方法中存放了变量,转发到第二个请求方法中可以获取到变量

    使用Map类

    使用一个Map类,也可以将变量保存在request域中携带到转发的页面或请求方法,用法也很简单,只需要将一个Map类添加在请求方法的参数列表中,然后在请求方法中把变量加入Map即可

    @Controller
    public class MyController {
    
        @RequestMapping("/user")
        public String queryUser(Map<String, Object> map) {
            map.put("name", "cong");
            map.put("age", 18);
            return "forward:/other";
        }
    
        @RequestMapping("/other")
        @ResponseBody
        public Map<String, Object> other(HttpServletRequest request) {
            Object name = request.getAttribute("name");
            Object age = request.getAttribute("age");
            HashMap<String, Object> result = new HashMap<>();
            result.put("name", name);
            result.put("age", age);
            return result;
        }
    }
    

    效果是一样的

    使用Model类

    我们还可以使用一个Model类将变量保存在request域中,用法和前面的两种方法一样,只需要将一个Model类添加在请求方法的参数列表中,然后在请求方法中调用addAttribute方法把变量加入Model即可

    @Controller
    public class MyController {
    
        @RequestMapping("/user")
        public String queryUser(Model model) {
            model.addAttribute("name", "cong");
            model.addAttribute("age", 18);
            return "forward:/other";
        }
    
        @RequestMapping("/other")
        @ResponseBody
        public Map<String, Object> other(HttpServletRequest request) {
            Object name = request.getAttribute("name");
            Object age = request.getAttribute("age");
            HashMap<String, Object> result = new HashMap<>();
            result.put("name", name);
            result.put("age", age);
            return result;
        }
    }
    

    还有一个类ModelMap,和Model类是一样的

    @RequestAttribute注解

    在从request域中取出变量时,也可以使用@RequestAttribute注解,只需要将request域中的变量名添加在请求处理方法的参数列表中,然后添加@RequestAttribute注解即可获取到变量的值

    @Controller
    public class MyController {
    
        @RequestMapping("/user")
        public String queryUser(HttpServletRequest request) {
            request.setAttribute("name", "cong");
            request.setAttribute("age", 18);
            return "forward:/other";
        }
    
        @RequestMapping("/other")
        @ResponseBody
        public Map<String, Object> other(@RequestAttribute String name, @RequestAttribute int age) {
            HashMap<String, Object> result = new HashMap<>();
            result.put("name", name);
            result.put("age", age);
            return result;
        }
    }
    

    通过设置注解中的name属性或者value属性,可以在参数名和request域中的变量名不一致时,绑定变量名;设置require属性为false,可以不必须携带这个变量

    重定向中携带变量

    我们知道,在重定向中不可以携带request域中的变量,但是使用RedirectAttributes类,可以解决这个问题,帮助我们在重定向中携带变量

    RedirectAttributes类有addAttribute方法和addFlashAttribute方法,都可以实现在重定向中携带变量,不过实现的原理不同,获取变量的方法也不同

    拼接url携带变量

    使用RedirectAttributes类的addAttribute方法,可以将变量拼接在url中携带到重定向后的页面,在获取变量的时候使用@RequestParam注解获取即可

    @Controller
    public class MyController {
    
        @RequestMapping("/user")
        public String queryUser(RedirectAttributes redirectAttributes) {
            redirectAttributes.addAttribute("name", "cong");
            redirectAttributes.addAttribute("age", 18);
            return "redirect:/other";
        }
    
        @RequestMapping("/other")
        @ResponseBody
        public Map<String, Object> other(@RequestParam String name, @RequestParam int age) {
            HashMap<String, Object> result = new HashMap<>();
            result.put("name", name);
            result.put("age", age);
            return result;
        }
    }
    

    在浏览器中测试效果

    在这里插入图片描述

    可以看到变量拼接到了重定向之后的url后面,url上的参数也可以正常获取到

    模拟Session携带变量

    RedirectAttributes类还有一个addFlashAttribute方法,他是模拟Session的方式携带变量,但是这个变量只能取出一次,获取变量时使用@ModelAttribute注解取出

    @Controller
    public class MyController {
    
        @RequestMapping("/user")
        public String queryUser(RedirectAttributes redirectAttributes) {
            redirectAttributes.addFlashAttribute("name", "cong");
            redirectAttributes.addFlashAttribute("age", 18);
            return "redirect:/other";
        }
    
        @RequestMapping("/other")
        @ResponseBody
        public Map<String, Object> other(@ModelAttribute("name") String name, @ModelAttribute("age") int age) {
            HashMap<String, Object> result = new HashMap<>();
            result.put("name", name);
            result.put("age", age);
            return result;
        }
    }
    

    注意在使用@ModelAttribute注解时,一定要使用name属性或者value属性绑定参数名,否则会报错

    在这里插入图片描述

    下一篇:没有了