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");
}
測試結果:
從結果可以看出其實就是同一個對象:隐含模型 就是Map參數,Model參數和ModelMap參數。他們三其實都是接收同一個對象執行個體。
2.5、ModelAndView方式儲存資料到request域中
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");
}