天天看點

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接收參數

繼續閱讀