有些时候我们需要在Controller中处理完数据之后,需要跳转到另一个Controller中进行相关操作,这个时候可以用请求转发和请求重定向
重定向
一个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进行执行,所以浏览器的地址会变化
请求转发
指一个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不变。
再次刷新,谷歌浏览器提示重新提交表单。
由于学艺不精遇到的问题
有下面SprigBoot程序,我希望再登陆页面登陆成后跳转到后台页面,html文件都放在templates
下
我第一版是这样写的
前端发送用户名和密码到后端,后端进行验证,验证结束用户名和密码正确就重定向到dashboard页面
然而出现了第一个问题
① 404找不到dashboard
这个时候观察一下地址栏,发现地址并不是我所想的直接请求http://localhost:8080/dashboard
这是由于再重定向的时候地址写的不对,对于后台地址来说
- 当页面跳转路径加/时,表示是绝对路径
- 当页面跳转路径不加/时,表示是相对路径
所以将代码改成下面这样
这个时候又有问题了
② 访问不到我的静态资源
这是由于对于DispatchServlet
默认配置的是/,也就是拦截所有包括css,js等,我们重定向让浏览器发送请求访问静态资源当然访问不到
这个时候我才用下面的解决方式
重定向到另外一条请求返回页面
而是是不是这样问题就解决了?TOO YOUNG TOO SIMPLE
如果我这个时候直接而访问http://localhost:8080/user/dashboard
,那么是可以直接进入后台的,登陆就没有意义了
③ 登陆失效
对于这个问题的解决方法是加一个拦截器,把用户的登陆信息存在session域中,在拦截器中判断是否登陆而决定是否放行
拦截器
配置拦截器
搞定