前言
对于请求的转发和重定向,想必大家都很熟悉了。转发发生在服务端,重定向发生在客户端。转发属于同一次请求,而重定向属于是客户端重新发送了一次新的请求,以及对于在浏览器上链接地址的显示等等,这些区别大家肯定都很清楚。在日常开发中,由于框架的使用,我们使用的请求转发和请求重定向都是经过框架的封装,封装之后我们使用起来会更加方便,但是由于封装之后,有些小伙伴对封装内部的底层原理就可能有点模糊,导致在日常应用中可能会陷入一些小bug中,这里和大家一起总结一下springmvc的转发和重定向。
springmvc中的转发
对于springmvc中的请求转发,这是在日常开发中运用比较多的,在Controller中,处理完表单传递过来的数据,一般会返回一个字符串,或者是ModelandView,然后经过springmvc的视图解析器进行解析。拼接成返回视图的路径,然后将数据通过model.addAttribute放在model中传递到页面上进行渲染。这里实际的本质还是将要返回的数据保存在response中,然后经过转发的页面能够通过el表达式来获取对应的数据。
在springmvc中,我们可以这样进行转发
ModelAndView mv=new ModelAndView("success");
mv.addObject("name", "爱琴孩");
return mv;
当然也可以将数据直接放在Model中然后直接返回字符串,然后经过视图解析器进行解析映射到对应的页面
//保存数据
model.addAttribute("name", "爱琴孩");
//返回对应视图
return "success";
转发是springmvc中比较基础也比较常见的方式,接下来我们可以看看springmvc中的请求重定向
springmvc请求重定向
一般情况下,我们在Controller中处理相关数据之后会直接返回到对应的页面,但是有些时候我们需要在Controller中处理完数据之后,需要跳转到另一个Controller中进行相关操作,这是我们可能就会用到请求重定向,而这里的重定向可以细分为,无参重定向,通过url拼接带参重定向,和RedirectAttributes带参重定向。下面我们详细介绍一下这几种重定向。
对于无参重定向跳转,直接在返回的字符串中直接跳转就可以,当然这里也可以是用ModelAndView来进行重定向,和直接返回字符串是类似的
return "redirect:/redirectController/redirectTest";
对于拼接Url进行带参重定向跳转,其实就是通过Url传参
return "redirect:/redirectController/redirectTest?name"+"aiqinhai"
这种拼接传参方式对于中文参数会出现中文乱码情况,而且传递的参数会直接暴露在浏览器的链接地址上,这样安全性也是比较低的
对于第三种通过RedirectAttributes来进行重定向传参
@Controller
@RequestMapping(value="/TestController")
public class TestController extends BaseController{
@RequestMapping(value="/test")
public String test(Model model,RedirectAttributes attributes){
attributes.addAttribute("name", "爱琴孩");
return "redirect:/redirectController/redirectTest";
}
}
重定向跳转的Controller
/**
* @ClassName: RedirectController
* @Description: TODO(测试重定向之后的Controller)
* @author 爱琴孩
*/
@Controller
@RequestMapping("/redirectController")
public class RedirectController {
@RequestMapping("/redirectTest")
public String redirectTest(HttpServletRequest httpServletRequest,HttpServletResponse
response,@ModelAttribute("name") String name){
System.out.println("跳转成功!恭喜你"+name);
return "success";
}
}
上面是通过attributes.addAttribute(“name”, “爱琴孩”);来进行传参的,这种方式还是会将传递的参数暴露在浏览器的链接地址上,这个风险就不言而喻了,对于重定向过来的参数,这里需要用@ModelAttribute注解来进行接收,对于@ModelAttribute注解的使用,后续会和大家一起总结!
浏览器上暴露的参数如下
如果不想暴露参数,该怎么办,其实对于RedirectAttributes ,这里还有一个方法是attributes.addFlashAttribute(“name”, “爱琴孩”);这个方式是将要保存的数据保存在session中,重定向之后,获取到session中值,然后将session中保存的值清除,这种能在一定程度上避免表单重复提交。
@Controller
@RequestMapping(value="/TestController")
public class TestController extends BaseController{
@RequestMapping(value="/test")
public String test(Model model,RedirectAttributes attributes){
attributes.addFlashAttribute("name", "爱琴孩");
return "redirect:/redirectController/redirectTest";
}
}
可以看到这时,浏览器上是没有暴露参数的
同时刷新页面,发现重定向传递的参数是不能获取的
这就验证了,再获取session里面的值之后,保存在session中的数据被清空了。
springmvc重定向跳转页面问题
前段时间有个小伙伴问我,他说在springmvc中重定向跳转页面是报404,他能确保路径写的是对的,但是就是报404,但是重定向另外一个页面的时候是可以正常访问的,我让他把页面的路径截图一下看看,后来发现他说报404的那个页面是在WEB-INF目录底下,而这个目录是不能直接请求访问的,而重定向相当于是重新发送了一个新的请求,当然会报404了。
总结
转发和重定向都是一些基础的知识,但是有时候这些小细节往往被忽视了,所以在平时要多注意开发中的小细节,细节决定成败!