基础内容:
页面跳转的两种实现方式:请求转发
和重定向
;
请求转发:
客户首先发送一个请求到服务器端,服务器端发现匹配的servlet,并指定它去执行,当这个servlet执行完之后,它要调用getRequestDispacther()方法
,把请求转发给指定的student_list.jsp,整个流程都是在服务器端完成的,而且是在同一个请求里面完成的,因此servlet和jsp共享的是同一个request,在servlet里面放的所有东西,在student_list中都能取出来,因此,student_list能把结果getAttribute()
出来,getAttribute()
出来后执行完把结果返回给客户端。整个过程是一个请求,一个响应。
重定向:
客户发送一个请求到服务器,服务器匹配servlet,servlet处理完之后调用了sendRedirect()方法
,立即向客户端返回这个响应,响应行告诉客户端你必须要再发送一个请求,去访问student_list.jsp,紧接着客户端收到这个请求后,立刻发出一个新的请求,去请求student_list.jsp,这里两个请求互不干扰,相互独立,在前面request里面setAttribute()的任何东西,在后面的request里面都获得不了。可见,在sendRedirect()里面是两个请求,两个响应。(服务器向浏览器发送一个302状态码以及一个location消息头,浏览器收到请求后会向再次根据重定向地址发出请求)
请求转发:request.getRequestDispatcher("/test.jsp").forword(request,response);
重定向:response.sendRedirect("/test.jsp");
区别:
1、请求次数:重定向是浏览器向服务器发送一个请求并收到响应后再次向一个新地址发出请求,转发是服务器收到请求后为了完成响应跳转到一个新的地址;重定向至少请求两次,转发请求一次;
2、地址栏不同:重定向地址栏会发生变化,转发地址栏不会发生变化;
3、是否共享数据:重定向两次请求不共享数据,转发一次请求共享数据(在request级别使用信息共享,使用重定向必然出错);
4、跳转限制:重定向可以跳转到任意URL,转发只能跳转本站点资源;
5、发生行为不同:重定向是客户端行为,转发是服务器端行为;
使用:
1、可以利用request的域对象的特点,由源组件向其中存放写数据;
2、可以让用户访问到存放在WEB-INF目录中的目标资源;
3、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,所以如果在使用转发和重定向都无所谓的时候建议使用转发;
4、因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。
讲正经的了:
一.返回ModelAndView时的请求转发
当controller中的方法返回ModelAndView
的时候,默认是使用的转发
。当然,我们也可以显式的指出要使用转发,此时,需在 setViewName()
指定的视图前添加forward:
,此时springmvc.xml文件中配置的视图解析器将会失效,即需要在setViewName中写上jsp相对于项目根的路径。
1:转发到页面
/**
* 转发返回ModelAndView对象
* @return
* @throws Exception
*/
@RequestMapping("/forwardMAV.do")
public ModelAndView forwardMAV()throws Exception{
ModelAndView mv = new ModelAndView();
mv.addObject("type", "转发返回ModelAndView");
//默认情况下使用转发
//mv.setViewName("/result");
//手动显式指定使用转发,此时springmvc.xml配置文件中的视图解析器将会失效
mv.setViewName("forward:/jsp/result.jsp");
return mv;
}
需要在webapp目录下添加jsp/result.jsp文件:
2:转发到controller
@RequestMapping("/forwardMAV.do")
public ModelAndView forwardMAV()throws Exception{
ModelAndView mv = new ModelAndView();
//手动显式指定使用转发,此时springmvc.xml配置文件中的视图解析器将会失效
mv.setViewName("forward:other.do");
return mv;
}
创建OtherController:
/**
* 被跳转的controller
*/
@Controller
public class OtherController {
/**
* 被跳转的controller返回result.jsp
* @return
* @throws Exception
*/
@RequestMapping("/other.do")
public ModelAndView other()throws Exception{
ModelAndView mv = new ModelAndView();
mv.addObject("type", "被跳转的controller");
mv.setViewName("result");
return mv;
}
}
二.返回ModelAndView时的重定向:发送的get请求,参数在url后面
如果要实现重定向,则需在setViewName()指定的视图前添加redirect
:,
此时springmvc.xml文件中配置的视图解析器将会失效,即需要在setViewName中写上jsp相对于项目根的路径。
重定向的方式在request域中的数据会失效,此时可以通过ModelAndView
来传递数据,但是只能传递基本数据类型和String类型,因为spring mvc会将传递的数据以请求参数的方式放到url的后面,此时任何数据类型都会被转换为普通的字符串。另外,我们在jsp中取值的时候需要使用 EL 表达式中的请求参数param读取。
除此之外,你还可以将数据放到HttpSession域中,这里就不演示了。
1.重定向到页面
/**
* 重定向返回ModelAndView对象
* @return
* @throws Exception
*/
@RequestMapping("/redirectMAV.do")
public ModelAndView redirectMAV(School school,String name)throws Exception{
ModelAndView mv = new ModelAndView();
//在重定向中可以使用ModelAndView传递数据,但是只能传递基本数据类型和String类型
mv.addObject("school",school);
mv.addObject("name", name);
//使用重定向,此时springmvc.xml配置文件中的视图解析器将会失效
mv.setViewName("redirect:/jsp/result.jsp");
return mv;
result.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${school.schoolName}<br>
${param.school.address}<br>
${param.name}
</body>
</html>
2.重定向到controller
在重定向到其他controller中的方法的时候,只要保证两者的参数名一致即可实现数据的传递。
@RequestMapping("/redirectMAV.do")
public ModelAndView redirectMAV(School school,String name)throws Exception{
ModelAndView mv = new ModelAndView();
mv.addObject("name", name);
mv.addObject("schoolName", school.getSchoolName());
mv.addObject("address", school.getAddress());
System.out.println(school.getAddress());
//使用重定向,此时springmvc.xml配置文件中的视图解析器将会失效
mv.setViewName("redirect:other.do");
return mv;
}
RequestMapping("/other.do")
public ModelAndView other(String name, School school)throws Exception{
ModelAndView mv = new ModelAndView();
//单个接收
mv.addObject("name", name);
//通过javabean对象接收
mv.addObject("school", school);
System.out.println(school.getAddress());
mv.setViewName("result");
return mv;
}
返回String类型的转发
这个整体上跟之前ModelAndView差不多,只不过在controller中的方法参数会被自动的放到request域中。
@RequestMapping("/forwardStr.do")
public String forwardStr(School school)throws Exception{
//默认会使用转发
//return "result";
//显式的使用转发
return "forward:/jsp/result.jsp";
}
result.jsp中直接通过request域获取数据,以下两种方式均可。
${requestScope.school.schoolName}
${school.schoolName}
返回String类型的重定向
这里要想传递数据的话,需要使用之前介绍过的Model实现,这里的数据同样会放在url中,所以只能传递基本数据类型和String类型。
@RequestMapping("/redirectStr.do")
public String redirectStr(School school, Model model)throws Exception{
//这里的数据同样会放在url中,所以只能传递基本数据类型和String类型
model.addAttribute("schoolName", school.getSchoolName());
model.addAttribute("address", school.getAddress());
return "redirect:/jsp/result.jsp";
}
result.jsp中需要通过param来获取数据:
${param.schoolName}
${param.address}