Java学习笔记-Day72 SpringMVC 框架(四)



一、转发和重定向


加入forward和redirect关键字,视图解析器的前缀和后缀会失效。

1、转发


(1)return “fc1”;(页面会转发到 /WEB-INF/jsp/fc1.jsp)

@Controller
public class ForwardController {
    
    
	@GetMapping("fc1")
	public String fc1() {
    
    
		return "fc1";// /WEB-INF/jsp/fc1.jsp
	}
}

(2)return “forward:fc2”;(页面会转发到 fc1,即/fc1)

@Controller
public class ForwardController {
    
    
	@GetMapping("fc2")
	public String fc2() {
    
    
		return "forward:fc1";// /fc1
	}
}

(3)return “froward:fc3.jsp”;(相对路径,会转发到相对路径下的fc3.jsp)

@Controller
public class ForwardController {
    
    
	@GetMapping("fc3")
	public String fc3() {
    
    
		return "forward:fc3.jsp";//相对路径,转发到 /fc3.jsp
	}
}
@Controller
@RequestMapping("api")
public class ForwardController {
    
    
	@GetMapping("fc3")
	public String fc3() {
    
    
		return "forward:fc3.jsp"; //相对路径,转发到 /api/fc3.jsp
	}
}

(4)return “forward:/fc3.jsp”;(绝对路径,会转发到WebContent目录下的fc3.jsp,即/fc3.jsp)

@Controller
public class ForwardController {
    
    
	@GetMapping("fc3")
	public String fc3() {
    
    
		return "forward:/fc3.jsp"; //绝对路径,转发到 /fc3.jsp
	}
}
@Controller
@RequestMapping("api")
public class ForwardController {
    
    
	@GetMapping("fc3")
	public String fc3() {
    
    
		return "forward:/fc3.jsp"; //绝对路径,转发到 /fc3.jsp
	}
}

2、重定向


(1)return “redirect:/WEB-INF/jsp/hello.jsp”;(无法重定向到该文件,会出现404错误)

@Controller
public class RedirectController {
    
    
	@GetMapping("rc1")
	public String rc1() {
    
    
		return "redirect:/WEB-INF/jsp/rc1.jsp"; // 无法访问/WEB-INF/jsp/rc1.jsp,
	}
}

不能使用redirect重定向到WEB-INF目录下的文件中,这个是web项目的一种安全级别,即WEB-INF目录是受保护的,不能直接通过url访问WEB-INF目录下的数据。可以将后台文件放入WEB-INF目录中。

(2)return “redirect:rc1”;(页面会重定向到 rc1,即/rc1)

@Controller
public class RedirectController {
    
    
	@GetMapping("rc2")
	public String rc2() {
    
    
		return "redirect:rc1";// /rc1
	}
}2return "redirect:rc2.jsp";(相对路径,会重定向到相对路径下的fc3.jsp)
```java
@Controller
public class RedirectController {
    
    
	@GetMapping("rc2")
	public String rc2() {
    
    
		return "redirect:rc2.jsp";//相对路径,重定向到 /rc2.jsp
	}
}
@Controller
@RequestMapping("api")
public class RedirectController {
    
    
	@GetMapping("rc2")
	public String rc2() {
    
    
		return "redirect:rc2.jsp"; //相对路径,重定向到 /api/rc2.jsp
	}
}

(3)return “/redirect:rc2.jsp”;(绝对路径,会重定向到WebContent目录下的rc2.jsp,即/rc2.jsp)

@Controller
public class RedirectController {
    
    
	@GetMapping("rc2")
	public String rc2() {
    
    
		return "redirect:/rc2.jsp"; //绝对路径,重定向到 /rc2.jsp
	}
}
@Controller
@RequestMapping("api")
public class RedirectController {
    
    
	@GetMapping("rc2")
	public String rc2() {
    
    
		return "redirect:/rc2.jsp"; //绝对路径,重定向到 /rc2.jsp
	}
}

二、从控制器传回数据到视图(非ajax请求)


(1)request.setAttribute(键, 值);

@Controller// 转发请求
public class DataTransController {
    
    
	@GetMapping("dc")
	public String dc1(HttpServletRequest request) {
    
    
		request.setAttribute("msg1", "dc1");
		return "dc";
	}	
}

(2)ModelAndView类(写在方法内部,作为返回值)

@Controller // 转发请求
public class DataTransController {
    
    
	@RequestMapping("test1")
	public ModelAndView sayHello() {
    
    
		ModelAndView mv = new ModelAndView("test1");
		mv.addObject("msg2", "Hello");
		return mv; // 转发到/WEB-INF/jsp/test1,jsp
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test1.jsp</title>
</head>
<body>
	<h1>${msg2}</h1>
</body>
</html>

(3)Model、Map或ModelMap。Spring Web MVC 提供Model、Map或ModelMap,能暴露渲染视图需要的模型数据。

ModelMap对象主要用于传递控制方法处理数据到结果页面,也就是说把结果页面上需要的数据放到ModelMap对象中即可,作用类似于request对象的setAttribute方法,用来在一个请求过程中传递处理的数据。

在控制器中通过以下方法向页面传递参数: addAttribute(String key,Object value);

在页面上通过 el变量方式$key 或者 其他的数据展示标签 获取并展示modelmap中的数据。

ModelMap对象本身不能设置页面跳转的url地址别名或者物理跳转地址,那么我们可以通过控制器方法的返回值来设置跳转url地址别名或者物理跳转地址。

@Controller
public class ModelTestController {
    
    
	@GetMapping("tmc2")
	public String tmc2(Model model,Map map,ModelMap modelmap) {
    
    
		// Model、Map、ModelMap使用的都是同一个BindingAwareModelMap实现类的对象
		model.addAttribute("msg1", "model");
		map.put("msg2", "map");
		modelmap.addAttribute("msg3", "modelmap");
		return "tmc1";
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>tmc1.jsp</title>
</head>
<body>
	${msg1}<br/>
	${msg2}<br/>
	${msg3}<br/>
</body>
</html>

(4)@ModelAttribute

1、@ModelAttribute具有如下三个作用:

① 绑定请求参数到命令对象:放在功能处理方法的入参(某个控制器的方法参数)上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定流程,而且自动暴露为模型数据用于视图页面展示时使用。此时,和(Model model) 写法的功能相同。

② 暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping注解的方法)之前,自动添加到模型对象中,用于视图页面展示时使用。

③暴露@RequestMapping方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。

2、在 SpringMVC 的 Controller 中使用 @ModelAttribute 时,应用位置包括下面几种:

① 应用在方法前:在访问GetMapping、PostMapping等映射注解的方法时,会先执行这个方法,会将返回的对象存放在request范围中,从而实现将数据传递到jsp页面。

@Controller
public class ModelAttributeTestController {
    
    	
	// c->v
	@GetMapping("matc1")
	@ModelAttribute("user")
	public User matc1() {
    
    
		User user = new User(1,"小明",10,12);
		return user; //跳转到 /WEB-INF/jsp/matc1.jsp
	}
}

当方法的返回值不是一个字符串,同时是非ajax请求时,则会跳转到一个和映射名相同的视图资源中。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>matc1.jsp</title>
</head>
<body>
	${user}<br/>
</body>
</html>

注意:当调用该控制器类中带有@GetMapping等映射注解的方法时,都会先调用这个方法。

@Controller
public class ModelAttributeTestController {
    
    
	
	@GetMapping("matc1")
	public String matc1() {
    
    
		return "matc1";
	}
	@GetMapping("matc2")
	public String matc2() {
    
    
		return "matc1";
	}
	//当调用以上带有@GetMapping等映射注解的方法时,都会先调用这个方法
	@ModelAttribute("u")
	public User matc4() {
    
    
		User u = new User(4,"小白",10,12);
		return u;
	}
}

② 放在参数前,主要是接收从视图传递过来的数据。如果有传递参数,则会将这个对象放在request范围内,如果没有传递参数,则不会将这个对象存放在request范围内。

@Controller
public class ModelAttributeTestController {
    
    	
	// view -> controller -> view
	@GetMapping("matc2")
	public String matc3(@ModelAttribute("user") User user) {
    
    
		System.out.println("user="+user);
		return "matc2";//跳转到 /WEB-INF/jsp/matc2.jsp
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>matc3.jsp</title>
</head>
<body>
	${user}<br/>
</body>
</html>

三、@SessionAttributes


有时候我们需要在多次请求之间保持数据,一般情况需要我们明确的调用HttpSession的API来存取会话数据。

方式一:request.getSession().setAttribute方法

@Controller
public class SessionTestController {
    
    
	@RequestMapping("hello_session")
	public String sessionTest(HttpServletRequest request) {
    
    
		Users u = new Users(1,"小明");
		request.getSession().setAttribute("u", u);
		return "hello_session";
	}
}

在hello_session.jsp就可以直接访问: ${sessionScope.u.userId}或者${u.userId}

方式二:session.setAttribute方法

@Controller
public class SessionTestController {
    
    
	@RequestMapping("/hello_session2")
	public String sessionTest2(HttpSession session, SessionStatus sta) {
    
    
		// 如果session还在
		if (!sta.isComplete()) {
    
    
			sta.setComplete(); // 让旧的session过期
		}
		Users u = new Users(1,"小明");
		session.setAttribute("u", u);
		return "hello_session2";
	}
}

在hello_session2.jsp就可以直接访问: ${sessionScope.u.userId}或者${u.userId}

方式三:Spring Web MVC提供了@SessionAttributes进行请求间透明的存取会话数据。@SessionAttributes绑定命令对象(@ModelAtrribute)到session,注解的位置在类前面,不能出现在方法前面.。通常与@ModelAttribute组合使用。

@Controller
@SessionAttributes(value= {
    
    "nickname","name"})
public class SessionTestController {
    
    
	
	@GetMapping("stc1")
	public String stc1() {
    
    	
		return "stc1";
	}
	
	@ModelAttribute("nickname")
	public String getModelValue1() {
    
    
		return "小红";
	}
	
	@GetMapping("stc2")
	@ModelAttribute("name")
	public String getModelValue2() {
    
    
		return "小安";
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>stc1.jsp</h1>
	request:${requestScope.nickname}<br/>
	session:${sessionScope.nickname}<br/>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>stc2.jsp</h1>
	request:${requestScope.name}<br/>
	session:${sessionScope.name}<br/>
</body>
</html>

@SessionAttributes基本原理:

首先根据@SessionAttributes注解信息查找会话内的对象放入到模型数据中。执行@ModelAttribute注解的方法:如果模型数据中包含同名的数据,则不执行@ModelAttribute注解方法进行准备表单引用数据,而是使用方式一中的会话数据。如果模型数据中不包含同名的数据,执行@ModelAttribute注解的方法并将返回值添加到模型数据中。

猜你喜欢

转载自blog.csdn.net/qq_42141141/article/details/114190008