天天看點

Controller

一、簡介

在SpringMVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把使用者請求的資料經過業務處理層處理之後封裝成一個Model ,然後再把該Model 傳回給對應的View 進行展示。在SpringMVC 中提供了一個非常簡便的定義Controller 的方法,你無需繼承特定的類或實作特定的接口,隻需使用@Controller 标記一個類是Controller ,然後使用@RequestMapping 和@RequestParam 等一些注解用以定義URL 請求和Controller 方法之間的映射,這樣的Controller 就能被外界通路到。此外Controller 不會直接依賴于HttpServletRequest 和HttpServletResponse 等HttpServlet 對象,它們可以通過Controller 的方法參數靈活的擷取到。為了先對Controller 有一個初步的印象,以下先定義一個簡單的Controller :

@Controller
public class MyController {

    @RequestMapping ( "/showView" )
    public ModelAndView showView() {
       ModelAndView modelAndView = new ModelAndView();
       modelAndView.setViewName( "viewName" );
       modelAndView.addObject( " 需要放到 model 中的屬性名稱 " , " 對應的屬性值,它是一個對象 " );
       return modelAndView;
    }

}      

在上面的示例中,@Controller 是标記在類MyController 上面的,是以類MyController 就是一個SpringMVC Controller 對象了,然後使用@RequestMapping(“/showView”) 标記在Controller 方法上,表示當請求/showView.do 的時候通路的是MyController 的showView 方法,該方法傳回了一個包括Model 和View 的ModelAndView 對象。

二、使用 @Controller 定義一個 Controller 控制器

@Controller 用于标記在一個類上,使用它标記的類就是一個SpringMVC Controller 對象。分發處理器将會掃描使用了該注解的類的方法,并檢測該方法是否使用了@RequestMapping 注解。@Controller 隻是定義了一個控制器類,而使用@RequestMapping 注解的方法才是真正處理請求的處理器,這個接下來就會講到。

單單使用@Controller 标記在一個類上還不能真正意義上的說它就是SpringMVC 的一個控制器類,因為這個時候Spring 還不認識它。那麼要如何做Spring 才能認識它呢?這個時候就需要我們把這個控制器類交給Spring 來管理。拿MyController 來舉一個例子

@Controller
public class MyController {
    @RequestMapping ( "/showView" )
    public ModelAndView showView() {
       ModelAndView modelAndView = new ModelAndView();
       modelAndView.setViewName( "viewName" );
       modelAndView.addObject( " 需要放到 model 中的屬性名稱 " , " 對應的屬性值,它是一個對象 " );
       return modelAndView;
    }

}      

這個時候有兩種方式可以把MyController 交給Spring 管理,好讓它能夠識别我們标記的@Controller 。

第一種方式是在SpringMVC 的配置檔案中定義MyController 的bean 對象。

<bean class="com.host.app.web.controller.MyController"/>      

第二種方式是在SpringMVC 的配置檔案中告訴Spring 該到哪裡去找标記為@Controller 的Controller 控制器。

< context:component-scan base-package = "com.host.app.web.controller" >
       < context:exclude-filter type = "annotation"
           expression = "org.springframework.stereotype.Service" />
    </ context:component-scan >      

注:上面 context:exclude-filter 标注的是不掃描 @Service 标注的類

三、使用 @RequestMapping 來映射 Request 請求與處理器

可以使用@RequestMapping 來映射URL 到控制器類,或者是到Controller 控制器的處理方法上。當@RequestMapping 标記在Controller 類上的時候,裡面使用@RequestMapping 标記的方法的請求位址都是相對于類上的@RequestMapping 而言的;當Controller 類上沒有标記@RequestMapping 注解時,方法上的@RequestMapping 都是絕對路徑。這種絕對路徑和相對路徑所組合成的最終路徑都是相對于根路徑“/ ”而言的。

@Controller
public class MyController {
    @RequestMapping ( "/showView" )
    public ModelAndView showView() {
       ModelAndView modelAndView = new ModelAndView();
       modelAndView.setViewName( "viewName" );
       modelAndView.addObject( " 需要放到 model 中的屬性名稱 " , " 對應的屬性值,它是一個對象 " );
       return modelAndView;
    }

}      

在這個控制器中,因為MyController 沒有被@RequestMapping 标記,是以當需要通路到裡面使用了@RequestMapping 标記的showView 方法時,就是使用的絕對路徑/showView.do 請求就可以了。

@Controller
@RequestMapping ( "/test" )
public class MyController {
    @RequestMapping ( "/showView" )
    public ModelAndView showView() {
       ModelAndView modelAndView = new ModelAndView();
       modelAndView.setViewName( "viewName" );
       modelAndView.addObject( " 需要放到 model 中的屬性名稱 " , " 對應的屬性值,它是一個對象 " );
       return modelAndView;
    }

}      

這種情況是在控制器上加了@RequestMapping 注解,是以當需要通路到裡面使用了@RequestMapping 标記的方法showView() 的時候就需要使用showView 方法上@RequestMapping 相對于控制器MyController上@RequestMapping 的位址,即/test/showView.do 。

(一)使用 URI 模闆

URI 模闆就是在URI 中給定一個變量,然後在映射的時候動态的給該變量指派。如URI 模闆http://localhost/app/{variable1}/index.html ,這個模闆裡面包含一個變量variable1 ,那麼當我們請求http://localhost/app/hello/index.html 的時候,該URL 就跟模闆相比對,隻是把模闆中的variable1 用hello 來取代。在SpringMVC 中,這種取代模闆中定義的變量的值也可以給處理器方法使用,這樣我們就可以非常友善的實作URL 的RestFul 風格。這個變量在SpringMVC 中是使用@PathVariable 來标記的。

在SpringMVC 中,我們可以使用@PathVariable 來标記一個Controller 的處理方法參數,表示該參數的值将使用URI 模闆中對應的變量的值來指派。

@Controller
@RequestMapping ( "/test/{variable1}" )
public class MyController {

    @RequestMapping ( "/showView/{variable2}" )
    public ModelAndView showView( @PathVariable String variable1, @PathVariable ( "variable2" ) int variable2) {
       ModelAndView modelAndView = new ModelAndView();
       modelAndView.setViewName( "viewName" );
       modelAndView.addObject( " 需要放到 model 中的屬性名稱 " , " 對應的屬性值,它是一個對象 " );
       return modelAndView;
    }
}      

在上面的代碼中我們定義了兩個URI 變量,一個是控制器類上的variable1 ,一個是showView 方法上的variable2,然後在showView 方法的參數裡面使用@PathVariable 标記使用了這兩個變量。是以當我們使用/test/hello/showView/2.do 來請求的時候就可以通路到MyController 的showView 方法,這個時候variable1 就被賦予值hello ,variable2 就被賦予值2 ,然後我們在showView 方法參數裡面标注了參數variable1 和variable2 是來自通路路徑的path 變量,這樣方法參數variable1 和variable2 就被分别賦予hello 和2 。方法參數variable1 是定義為String 類型,variable2 是定義為int 類型,像這種簡單類型在進行指派的時候Spring 是會幫我們自動轉換的

在上面的代碼中我們可以看到在标記variable1 為path 變量的時候我們使用的是@PathVariable ,而在标記variable2 的時候使用的是@PathVariable(“variable2”) 。這兩者有什麼差別呢?第一種情況就預設去URI 模闆中找跟參數名相同的變量,但是這種情況隻有在使用debug 模式進行編譯的時候才可以,而第二種情況是明确規定使用的就是URI 模闆中的variable2 變量。當不是使用debug 模式進行編譯,或者是所需要使用的變量名跟參數名不相同的時候,就要使用第二種方式明确指出使用的是URI 模闆中的哪個變量。

除了在請求路徑中使用URI 模闆,定義變量之外,@RequestMapping 中還支援通配符“* ”。如下面的代碼我就可以使用/myTest/whatever/wildcard.do 通路到Controller 的testWildcard 方法。

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

(二)使用 @RequestParam 綁定 HttpServletRequest 請求參數到控制器方法參數

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

繼續閱讀