SpringMVC學習記錄(二)--controller和view的聯系


對於SpringMVC來說,controller由兩個部分構成,分別是分發器和控制器,分發器DispatcherServlet決定着請求使用哪個控制器,並且決定着控制器返回哪個視圖,整體結構如下.
這里寫圖片描述


1.創建一個controller

對於DispatcherServlet這個是springMVC框架自動實現,而我們只需要寫相應的控制器即可,就拿上一個helloworld例子來說,創建一個控制器,只需要給其加上@controller的注解

/**
* 加上@Controller決定這個類是一個控制器
*/

@Controller
public class HelloController {

@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String hello(){

return "hello";
}
}

@Controller 用於標記在一個類上,使用它標記的類就是一個SpringMVC Controller 對象。分發處理器將會掃描使用了該注解的類的方法,並檢測該方法是否使用了@RequestMapping 注解。@Controller 只是定義了一個控制器類,而使用@RequestMapping 注解的方法才是真正處理請求的處理器,這個接下來就會講到。
讓控制器起作用,則需要在springMVC.xml配置文件中配置,也就是上一篇搭建基本環境中的配置
這里寫圖片描述


2.讓controller返回一個jsp視圖

@RequestMapping 注解決定着返回的jsp視圖,對於這個屬性先簡單來說一般配置value和method兩個值,value決定着請求的路徑,method決定着請求的方法

@Controller
public class HelloController {

@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String hello(){

return "hello";
}
}

拿上面例子來說,直接在瀏覽器訪問localhost:8888/hello即可訪問到這個控制器,對應的請求為GET請求,此方法返回一個hello字符串,說明對應的視圖為hello.jsp,這是最簡單的訪問形式,如果我們想要傳值的話,該怎么做呢?

  • 方法1:在參數中加一個model,直接把值放進去就可以了
  @RequestMapping(value = "/hello",method = RequestMethod.GET)
public String hello(Model model){
// 這樣放參數的話,在jsp中直接用EL訪問hello即可
model.addAttribute("hello","world1");
// 這樣方參數的話,默認的key是參數類型
model.addAttribute("world2");
return "hello";
}

在對應的jsp中可以如下獲取

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1 style="text-align: center">Hello World!${hello}----${string}</h1>
</body>
</html>

這里寫圖片描述

  • 方法2;使用ModelAndView
    @RequestMapping(value = "/hello",method = RequestMethod.GET)
public ModelAndView hello(){
ModelAndView model = new ModelAndView();
//設置返回視圖名稱
model.setViewName("hello");
//傳值,規則同上
model.addObject("hello","world1");
//傳值,規則同上
model.addObject("world2");
return model;
}

兩種方法幾乎沒區別,根據愛好使用.
這里寫圖片描述


3.使用URI模板

URI模板是用來獲取url中的值,看下面小例子

@RequestMapping(value = "/hello/{id}",method = RequestMethod.GET)
public String hello(@PathVariable("id") String id, Model model){
// 這樣放參數的話,在jsp中直接用EL訪問hello即可
model.addAttribute("hello",id);
return "hello";
}

上面在value = “/hello/{id}”,說明訪問的url必須為/hello/XX這樣的鏈接,@PathVariable(“id”) String id,的作用就是把這個XX放入id中,然后jsp頁面就可以獲取這個值了
這里寫圖片描述

除此之外還支持*通配符訪問

@Controller
@RequestMapping ( "/myTest" )
public class MyController {
@RequestMapping ( "*/wildcard" )
public String testWildcard() {
System. out .println( "wildcard------------" );
return "wildcard" ;
}
}

那么此時的訪問路徑只要為/mytest/**/wildcard都可以訪問當前連接


4.@RequestParam 綁定 HttpServletRequest 請求參數

對於請求名和屬性名一致的,springmvc會默認自動綁定,對於不一致的需要使用RequestParam 來進行映射

    @RequestMapping ( "requestParam" )
public String testRequestParam( @RequestParam(required=false) String name, @RequestParam ( "age" ) int age) {
return "requestParam" ;
}

required=false代表name是非必須值,可以不存在HttpServletRequest 之中,而后面的age則不同,要求必須在HttpServletRequest 之中,否則會報錯.
值得注意的是和@PathVariable 一樣,當你沒有明確指定從request 中取哪個參數時,Spring 在代碼是debug 編譯的情況下會默認取更方法參數同名的參數,如果不是debug 編譯的就會報錯。此外,當需要從request 中綁定的參數和方法的參數名不相同的時候,也需要在@RequestParam 中明確指出是要綁定哪個參數。
類似的還有@CookieValue,@RequestHeader都類似用法,不過一般不用這種方法,接着看下面RequestMapping 的高級用法.


5.RequestMapping 的高級用法

1.支持的方法參數類型

  1. HttpServlet 對象,主要包括HttpServletRequest 、HttpServletResponse 和HttpSession 對象。 這些參數Spring 在調用處理器方法的時候會自動給它們賦值,所以當在處理器方法中需要使用到這些對象的時候,可以直接在方法上給定一個方法參數的申明,然后在方法體里面直接用就可以了。但是有一點需要注意的是在使用HttpSession 對象的時候,如果此時HttpSession 對象還沒有建立起來的話就會有問題。
  2. Spring 自己的WebRequest 對象。 使用該對象可以訪問到存放在HttpServletRequest 和HttpSession 中的屬性值。
  3. InputStream 、OutputStream 、Reader 和Writer 。 InputStream 和Reader 是針對HttpServletRequest 而言的,可以從里面取數據;OutputStream 和Writer 是針對HttpServletResponse 而言的,可以往里面寫數據。
  4. 使用@PathVariable 、@RequestParam 、@CookieValue 和@RequestHeader 標記的參數。
  5. 使用@ModelAttribute 標記的參數。
  6. java.util.Map 、Spring 封裝的Model 和ModelMap 。 這些都可以用來封裝模型數據,用來給視圖做展示。
  7. 實體類。 可以用來接收上傳的參數。
  8. Spring 封裝的MultipartFile 。 用來接收上傳文件的。
  9. Spring 封裝的Errors 和BindingResult 對象。 這兩個對象參數必須緊接在需要驗證的實體對象參數之后,它里面包含了實體對象的驗證結果。

2.支持的返回類型

  1. 一個包含模型和視圖的ModelAndView 對象。
  2. 一個模型對象,這主要包括Spring 封裝好的Model 和ModelMap ,以及java.util.Map ,當沒有視圖返回的時候視圖名稱將由RequestToViewNameTranslator 來決定。
  3. 一個View 對象。這個時候如果在渲染視圖的過程中模型的話就可以給處理器方法定義一個模型參數,然后在方法體里面往模型中添加值。
  4. 一個String 字符串。這往往代表的是一個視圖名稱。這個時候如果需要在渲染視圖的過程中需要模型的話就可以給處理器方法一個模型參數,然后在方法體里面往模型中添加值就可以了。
  5. 返回值是void 。這種情況一般是我們直接把返回結果寫到HttpServletResponse 中了,如果沒有寫的話,那么Spring 將會利用RequestToViewNameTranslator 來返回一個對應的視圖名稱。如果視圖中需要模型的話,處理方法與返回字符串的情況相同。
  6. 如果處理器方法被注解@ResponseBody 標記的話,那么處理器方法的任何返回類型都會通過HttpMessageConverters 轉換之后寫到HttpServletResponse 中,而不會像上面的那些情況一樣當做視圖或者模型來處理。
  7. 除以上幾種情況之外的其他任何返回類型都會被當做模型中的一個屬性來處理,而返回的視圖還是由RequestToViewNameTranslator 來決定,添加到模型中的屬性名稱可以在該方法上用@ModelAttribute(“attributeName”) 來定義,否則將使用返回類型的類名稱的首字母小寫形式來表示。使用@ModelAttribute 標記的方法會在@RequestMapping 標記的方法執行之前執行。

對於方法參數,就像使用Model傳值一樣,可以直接在參數中加入req,resp,session等,然后就像servlet那樣使用就可以了

 @RequestMapping(value = "/hello",method = RequestMethod.GET)
public String hello(Model model, HttpServletRequest request, HttpServletResponse response, HttpSession session){
// 這樣放參數的話,在jsp中直接用EL訪問hello即可
return "hello";
}

6.定義自己的轉換器

在通過處理器方法參數接收 request 請求參數綁定數據的時候,對於一些簡單的數據類型 Spring 會幫我們自動進行類型轉換,而對於一些復雜的類型由於 Spring 沒法識別,所以也就不能幫助我們進行自動轉換了,這個時候如果我們需要 Spring 來幫我們自動轉換的話就需要我們給 Spring 注冊一個對特定類型的識別轉換器。 Spring 允許我們提供兩種類型的識別轉換器,一種是注冊在 Controller 中的,一種是注冊在 SpringMVC 的配置文件中。聰明的讀者看到這里應該可以想到它們的區別了,定義在 Controller 中的是局部的,只在當前 Controller 中有效,而放在 SpringMVC 配置文件中的是全局的,所有 Controller 都可以拿來使用。

  • 局部轉換器
    @InitBinder
public void initBinder(WebDataBinder binder){
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
PropertyEditor propertyEditor = new CustomDateEditor(format, true ); // 第二個參數表示是否允許為空
binder.registerCustomEditor(Date.class, propertyEditor);
}

這里寫圖片描述

  • 全局轉換器
public class MyWebBindingInitializer implements WebBindingInitializer {

@Override
public void initBinder(WebDataBinder binder, WebRequest request) {
// TODO Auto-generated method stub
DateFormat dateFormat = new SimpleDateFormat( "yyyyMMdd" );
PropertyEditor propertyEditor = new CustomDateEditor(dateFormat, true );
binder.registerCustomEditor(Date. class , propertyEditor);
}

}

需要在springMVC.xml中引入這個轉換器

    < bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
< property name = "webBindingInitializer" >
< bean class = "com.host.app.web.util.MyWebBindingInitializer" />
</ property >
</ bean >

剩下的用法沒區別了


項目示例可以參考:
SSM框架整合: https://github.com/nl101531/JavaWEB


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com