005-spring mvc 请求转发和重定向
一、转发和重定向
1.1、转发
服务内部请求转发,直接调用跳转的页面,让它返回,,对于浏览器来说,它无法感觉服务器有没有forward。地址栏不变
1.2、重定向
请求重定向,重定向是发一个302的状态码给浏览器,浏览器自己去请求跳转的网页,url改变,request数据不带到重定向的方法中
1.3、示例
基础POM
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.0.4.RELEASE</version> <exclusions> <exclusion> <artifactId>logback-classic</artifactId> <groupId>ch.qos.logback</groupId> </exclusion> <exclusion> <artifactId>spring-boot-starter-logging</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.0.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> <version>2.0.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>2.0.4.RELEASE</version> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>2.0.4.RELEASE</version> </dependency> </dependencies>
appli配置
server.port=8080
logging.config=classpath:log4j2-spring-prod.xml
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
页面 WEB-INF/view/model.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> 我是 forwardModel.jsp <br /> 转发标记:${flag} ;或者:${requestScope.flag} </body> </html>
controller代码
@Controller @RequestMapping(value = {"open/"}) public class ModelViewController { // 转发示例1、返回ModelAndView // 访问地址:http://localhost:8080/open/mv // 直接打开具体页面 @RequestMapping(value = "/mv", method = RequestMethod.GET) public ModelAndView opmodel(@RequestParam(value = "flag", defaultValue = "1", required = false) String flag) { ModelAndView model = new ModelAndView(); model.addObject("flag", "1".equalsIgnoreCase(flag) ? "opend mv" : flag); model.setViewName("model"); System.out.println("opmodel"); return model; } // 转发示例2、返回ModelAndView // 访问地址:http://localhost:8080/open/forward/model // 通过内部关键字 forward 转发到 /open/mv 的action @RequestMapping(value = "/forward/model", method = RequestMethod.GET) public ModelAndView testForwardModel(@RequestParam(value = "flag", defaultValue = "1", required = false) String flag) { ModelAndView model = new ModelAndView(); model.addObject("flag", "1".equalsIgnoreCase(flag) ? "forwardModel" : flag); model.setViewName("forward:/open/mv"); System.out.println("testForwardModel"); return model; } // 转发示例3、返回字符串 // 访问地址:http://localhost:8080/open/forward/string // 通过内部关键字 forward 转发到 /open/forward/model 的action @RequestMapping(value = "/forward/string", method = RequestMethod.GET) public String testForwardString() { System.out.println("testForwardString"); return "forward:/open/forward/model?flag=forwardString"; } //重定向示例1、带参数 //访问地址:http://localhost:8080/open/re/hasParams 浏览器会跳转至:http://localhost:8080/open/mv?flag=redirect @RequestMapping(value="/re/hasParams",method=RequestMethod.GET) public String hasParams(RedirectAttributes attr){ attr.addAttribute("flag", "redirect"); attr.addFlashAttribute("flagSessionParam", "flagSessionParamAAA"); return "redirect:/open/mv"; } //重定向示例1、带参数 //返回字符串 //将请求转发给上一个action, //访问:http://localhost:8080/open/re/forwardString 浏览器会跳转至:http://localhost:8080/open/mv?flag=redirect @RequestMapping(value = "/re/forwardString", method = RequestMethod.GET) public String testForward() { return "redirect:/open/mv?flag=forwardString"; } }
带参数可使用RedirectAttributes参数进行传递:
注意:
1. 使用RedirectAttributes的addAttribute方法传递参数会跟随在URL后面 ,如上代码即为http:/index.action?a=a
2. 使用addFlashAttribute不会跟随在URL后面,会把该参数值暂时保存于session,待重定向url获取该参数后从session中移除,这里的redirect必须是方法映射路径,jsp无效。你会发现redirect后的jsp页面中b只会出现一次,刷新后b再也不会出现了,这验证了上面说的,b被访问后就会从session中移除。对于重复提交可以使用此来完成。
另外,如果使用了RedirectAttributes作为参数,但是没有进行redirect呢?这种情况下不会将RedirectAttributes参数传递过去,默认传forward对应的model,官方的建议是:
p:ignoreDefaultModelOnRedirect="true" />1
设置下RequestMappingHandlerAdapter 的ignoreDefaultModelOnRedirect属性,这样可以提高效率,避免不必要的检索。