天天看点

SpringMVC详解二、返回值与数据在域中的保存1、返回值的设置2、数据在域中的保存

1、返回值的设置

1.1、返回String

1.2、返回modelAndView

1.3、返回void

2、数据在域中的保存

2.1、Request对象中保存数据(不推荐)

2.2、Session域中保存数据

2.3、ServletContext域中保存数据

2.4、Map或Model或ModelMap形式保存数据在request域中

2.5、ModelAndView方式保存数据到request域中

2.6、@SessionAttributes保存数据到Session域中(不推荐使用)

2.7、@ModelAttribute注解

1、返回值的设置

1.1、返回String

1.1.1、返回String**默认情况**

@Controller
public class ReturnController {

	@RequestMapping(value = "/return1")
	public String return1() {
		System.out.println("这是return1方法");
		return "return";
	}

}
           

默认情况下,返回return字符串。会经过视图解析器做字符串前后缀拼接的操作。

<!-- 配置Spring的视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- prefix配置返回的视图的前缀 -->
		<property name="prefix" value="/jsp/"/>
		<!-- suffix配置返回的视图的后缀 -->
		<property name="suffix" value=".jsp"/>
	</bean>
           

通过做前后缀拼接操作得:/jsp/return.jsp。

最后做转发操作。

request.getRequestDispatcher(“/jsp/return.jsp”).forward(requst,response);

1.1.2、显示转发

注意:(下面都是)在控制器上面添加 :@RequestMapping(value="/p")进行区分相对与绝对路径

@RequestMapping(value = "/return2")
	public String return2() {
		System.out.println("这是return2方法");
		// 在返回的字符串前面 显示的 标注 forward:表示显示的转发
		// 使用显示的转发,视图解析器就不会工作了
		return "forward:/jsp/return.jsp";
	}
           

 在返回的字符串前面 显示的 标注 forward/redirect:表示显示的转发

注: 使用显示的转发,视图解析器就不会工作了

1、return "forward:/jsp/return.jsp";

这是绝对路径转发

/ 表示绝对路径http://ip:port/工程名/

整个地址表示转发到http://ip:port/工程名/jsp/return.jsp

2、return "forward:jsp/return.jsp";

这是相对路径转发

先执行绝对路径再执行相对路径:

当前浏览器地址栏地址是:http://localhost:8080/mvc_hello/p/return2

相对路径是参数当前浏览器地址栏的地址

得到的转发路径是:http://localhost:8080/mvc_hello/p/jsp/return.jsp

1.1.3、显示重定向

@RequestMapping(value = "/return3")
	public String return3() {
		System.out.println("这是return3方法");
		// 当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向
		// 只要是显示的声明使用转发或重定向,默认视图解析器将不在工作
		return "redirect:/jsp/return.jsp";
	}
           

当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向

return "redirect:/jsp/return.jsp";

是绝对路径

前面这个斜杠表示到http://ip:port/工程名/

那么整个重定向的地址是:http://ip:port/工程名/jsp/return.jsp

return "redirect:jsp/return.jsp";

相对路径

需要参照浏览器地址栏当前的地址:http://localhost:8080/mvc_hello/p/return3

那么整个重定向的地址是:http://localhost:8080/mvc_hello/p/jsp/return.jsp

// 当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向

// 只要是显示的声明使用转发或重定向,默认视图解析器将不在工作

1.2、返回modelAndView

1.2.1、返回modelAndView的**默认情况**

@RequestMapping(value="/return4")
	public ModelAndView return4() {
		System.out.println("这是return4方法");
		// ModelAndView 也可以设置返回的资源
		ModelAndView modelAndView = new ModelAndView();
		// 设置视图名
		modelAndView.setViewName("return");
		return modelAndView;
	}
           

默认的情况我们在ModelAndView中设置的ViewName就是默认转发的视图名。这个视图名会经过视图解析器拼接这符串后再转发。

或直接ModelAndView modelAndView = new ModelAndView("return");

1.2.2、显示转发

@RequestMapping(value="/return5")
	public ModelAndView return5() {
		System.out.println("这是return5方法");
		// ModelAndView 也可以设置返回的资源
		ModelAndView modelAndView = new ModelAndView("forward:/jsp/return.jsp");
		return modelAndView;
	}
           

forward:/jsp/return.jsp

绝对路径

/ 表示绝对路径http://ip:port/工程名/

整个地址表示转发到http://ip:port/工程名/jsp/return.jsp

"forward:jsp/return.jsp";

这是相对路径转发

当前浏览器地址栏地址是:http://localhost:8080/mvc_hello/p/return5

相对路径是参数当前浏览器地址栏的地址

得到的转发路径是:http://localhost:8080/mvc_hello/p/jsp/return.jsp

1.2.3、显示重定向

@RequestMapping(value="/return6")
	public ModelAndView return6() {
		System.out.println("这是return6方法");
		ModelAndView modelAndView = new ModelAndView("redirect:/jsp/return.jsp");
		return modelAndView;
	}
           

return "redirect:/jsp/return.jsp";

是绝对路径

前面这个斜杠表示到http://ip:port/工程名/

那么整个重定向的地址是:http://ip:port/工程名/jsp/return.jsp

return "redirect:jsp/return.jsp";

相对路径

需要参照浏览器地址栏当前的地址:http://localhost:8080/mvc_hello/p/return3

那么整个重定向的地址是:http://localhost:8080/mvc_hello/p/jsp/return.jsp

// 当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向

// 只要是显示的声明使用转发或重定向,默认视图解析器将不在工作

1.3、返回void(不推荐在Controller中直接转发和重定向)

1.3.1、没有返回值的**默认情况**

一般在实际开发中。我们都是禁止使用如以上这种方式。使用默认的请求资源名做为默认转发的逻辑资源名。

如果有需要,都是使用String类型显示标明返回的逻辑名。也就是说以上代码应该写成为:

@RequestMapping(value="/return7")
	public void return7() {
		System.out.println("return7方法");
	}
           

1.3.2、显示转发

@RequestMapping(value = "/return8")
	public void return8(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("这是return8方法");
		try {
			request.getRequestDispatcher("/jsp/return.jsp").forward(request,
					response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
           

1.3.3、显示重定向

@RequestMapping(value="/return9")
	public void return9(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("这是return9方法");
		try {
			response.sendRedirect(request.getContextPath() + "/jsp/return.jsp");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
           

7.3.4、直接输出响应数据

@RequestMapping(value="/return10")
	public void return10(HttpServletResponse response) {
		System.out.println("这是return10方法");
		try {
			response.getWriter().write("this is the content of response!");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
           

2、数据在域中的保存

2.1、Request对象中保存数据(不推荐)

先在Controller的方法中添加一个HttpServletRequest对象

@RequestMapping(value="/requestScope")
	public ModelAndView requestScope(HttpServletRequest request) {
		System.out.println("这是把数据保存到request域中---requestScope");
		request.setAttribute("key1", "value1");
		return new ModelAndView("scope");
	}
           

注:

因为pageContext的作用域只在jsp页面中,所以这不考虑,request的域范围是当前请求,session是一个会话(即页面不关闭的情况下),sevletContext的域是整个web应用,即服务器只要不关闭就一直存在。

在页面中输出数据:

${ requestScope.key1 }<br/>

2.2、Session域中保存数据

在Controller方法中,添加HttpSession对象

@RequestMapping(value="/sessionScope")
	public ModelAndView sessionScope(HttpSession session) {
		System.out.println("这是把数据保存到session域中---sessionScope");
		session.setAttribute("skey1", "svalue1");
		return new ModelAndView("scope");
	}
           

在页面中输出Session的数据:

${ sessionScope.skey1 }<br/>

2.3、ServletContext域中保存数据

在Controller中的代码。在Controller的中获取SerlvetContext对象有两种方法,

一种是@Autowired注入,

一种是通过Session获取。

是通过@Autowired自动注入ServletContext对象

@Controller
public class ScopeController {
	@Autowired
	private ServletContext context;
           

通过HttpSession获取ServletContext对象

@RequestMapping(value = "/applicationScope")
	public ModelAndView applicationScope(HttpSession session) {
		System.out.println("这是把数据保存到ServletContext域中---applicationScope");
		session.getServletContext().setAttribute("appKey1", "appValue1");
		return new ModelAndView("scope");
	}
           

2.4、Map或Model或ModelMap形式保存数据在request域中

在四个域中,我们使用最频繁的域就是request对象。往request域对象中,保存数据,还在以下的几种形式。仅仅直接用request对象存储不推荐

我们可以在Controller的方法中,添加Map类型的参数,或者是Model类型的参数。或者是ModelMap类型的参数。都可以直接用来保存域数据到Request对象中。

Map全类名是: java.util.Map

Model全类名是: org.springframework.ui.Model

ModelMap全类名是: org.springframework.ui.ModelMap

保存到java.util.Map中,也会直接保存到request域中

@RequestMapping("/mapRequest")
	public ModelAndView map(Map<String, Object> map) {
		System.out.println("这是map方法保存到request域中");
		//把数据保存到map中,SpringMVC会自动把这些数据保存到request域中
		map.put("mapKey1", "mapValue1");
		map.put("mapKey2", "mapValue2");
		
		return new ModelAndView("scope");
	}
           

保存到org.springframework.ui.Model中,SpringMVC也会自动保存数据到request域中

@RequestMapping("/modelRequest")
	public ModelAndView model(Model model) {
		System.out.println("这是model方法保存到request域中");
		//把数据保存到Model中,SpringMVC会自动把这些数据保存到request域中
		model.addAttribute("model1", "modelValue1");
		model.addAttribute("model2", "modelValue2");
		
		return new ModelAndView("scope");
	}
           

保存到org.springframework.ui.ModelMap当中,SpringMVC也会自动的把这些数据保存到request域中

@RequestMapping("/modelMapRequest")
	public ModelAndView modelMap(ModelMap modelMap) {
		System.out.println("这是modelMap方法保存到request域中");
		//把数据保存到ModelMap中,SpringMVC会自动把这些数据保存到request域中
		modelMap.addAttribute("modelMap1", "modelMapValue1");
		modelMap.addAttribute("modelMap2", "modelMapValue2");
		
		return new ModelAndView("scope");
	}
           

隐含模型 就是Map参数,Model参数和ModelMap参数。他们三其实都是接收同一个对象实例。

/**
	 * 		BindingAwareModelMap 它叫隐含模型
	 *            /\
	 *            ||
	 *            ||
	 *      ExtendedModelMap    -----实现>>>>>>Model接口
	 *            /\
	 *            ||
	 *            ||
	 *         ModelMap  
	 *            /\
	 *            ||
	 *            ||
	 *       LinkedHashMap
	 *            /\
	 *            ||
	 *          HashMap  ------实现>>>>>> Map接口
	 */
	@RequestMapping(value="/test")
	public ModelAndView test(Map<String, Object> map,Model model,ModelMap modelMap) {
		map.put("key1", "value1");
		model.addAttribute("model1", "modelValue1");
		modelMap.addAttribute("modelMap1", "modelMapValue1");
		System.out.println("我反倒扣分");
		System.out.println(map.getClass()+"我是map");
		System.out.println(model.getClass()+"我是model");
		System.out.println(modelMap.getClass()+"我是modelMap");
		return new ModelAndView("scope");
		
	}
           

测试结果:

SpringMVC详解二、返回值与数据在域中的保存1、返回值的设置2、数据在域中的保存

从结果可以看出其实就是同一个对象:隐含模型 就是Map参数,Model参数和ModelMap参数。他们三其实都是接收同一个对象实例。

2.5、ModelAndView方式保存数据到request域中

把数据保存到ModelAndView中,springMVC保存到把数据保存到Request域中

@RequestMapping(value="/modelAndViewScope")
	public ModelAndView modelAndViewScope() {
		ModelAndView modelAndView = new ModelAndView("scope");
		
		System.out.println("这是modelAndViewScope方法");
		// 往ModelAndView中保存数据,同样SpringMVC也会保存到request域中
		modelAndView.addObject("modelAndView1", "modelAndViewValue1");
		modelAndView.addObject("modelAndView2", "modelAndViewValue2");
		
		return modelAndView;
	}
           

页面中输出数据:

<hr/>

${ requestScope.modelAndView1 }<br/>

${ requestScope.modelAndView2 }<br/>

2.6、@SessionAttributes保存数据到Session域中(不推荐使用)

@SessionAttributes 注解可以标注在类上。它的作用是指定哪些数据可以保存到Session域中。

@SessionAttributes(value = { "key1","key2" }, types = { String.class, Book.class })

value属性,它表示把request域中key为key1,key2的键值对信息,也保存到Session中

types属性,它表示把request域中value类型为String.class或Book.class类型的键值对,也保存到Session中

@RequestMapping(value="/testSessionAttributes")
	public ModelAndView testSessionAttributes(Map<String, Object> map) {
		System.out.println("这是testSessionAttributes方法");
		// 往map中保存数据,就会自动保存到Request域中
		map.put("key1", new Long(1234));
		
		return new ModelAndView("scope");
	}
           

2.7、@ModelAttribute注解

@ModelAttribute这个注解可以标注在方法和参数上。

@ModelAttribute三个常见作用:

1、被标注了@ModelAttribute的方法都会在Controller的目标方法之前执行。

2、目标方法的参数(JavaBean对象,book)会先从隐含模型中获取值传入。

3、@ModelAttribute被标注在目标的参数上(即取别名),参数值会按照指定的key从隐含模型中获取值。

@ModelAttribute
	public void abc(Map<String, Object> map) {
		System.out.println("我是@ModelAttribute标注的abc()方法");
		map.put("book111", new Book("我是一个兵!", new BigDecimal(99999999)));
	}
	/**
	 *  目标方法中,如果有对象参数(非原生API,是那些pojo对象),它会先按照参数的类型取类名,然后首字母小写book,从隐含模型中取值注入。
	 */
	@RequestMapping(value="/targetMethod")
	public ModelAndView targetMethod(@ModelAttribute("book111")Book book) {
		System.out.println("targetMethod被调用了!");
		System.out.println("目标方法中book的值是:" + book);
		return new ModelAndView("scope");
	}
           

SpringMVC详解一、@RequestMapping注解与Controller接收参数

继续阅读