BaseCommandController及其子類AbstractCommandController、AbstractFormController、AbstractWizardFormController、
在一個(gè)POJO上面使用 @Controller 就可以標(biāo)注該P(yáng)OJO是一個(gè)Controller,就這么簡單。 @Controller注解定義在org.springframework.steretype包中。
使用方式: @Controller 或者 @Controller("indexController)。 org.springframework.steretype包中還包含 @Componenet @Service @Respository
三個(gè)注解。@Component是通用標(biāo)注,@Controller標(biāo)注web控制器,@Service標(biāo)注Servicec層的服務(wù),@Respository標(biāo)注DAO層的數(shù)據(jù)訪問。
2、使用@RequestMapping注解處理請求映射
SpringMVC中注解基本都包含在 org.springframework.web.bind.annotation 包中。先看一下
@RequestMapping 注解的源碼。
@Target( { ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
/**
* 指定映射的URL.可以在類層次和方法層次使用。方式如下:
* @RequestMapping("/add_")或 @RequestMapping(value = "/add")
* 支持Ant風(fēng)格的URL映射,如 @RequestMapping("/myPath/*.htm")
* 在類層次指定了映射后,可以在方法層次再指定相對路徑
*/
String[] value() default {};
/**
* 指定HttpRequest的方法, 如:GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
* 使用舉例: @RequestMapping(value = "/add_activity", method = RequestMethod.GET)
*/
RequestMethod[] method() default {};
/**
* 指定HttpRequest中包含的參數(shù),使用方式如下:
* @RequestMapping(value = "/something",params="myParam") 請求包含myParam參數(shù)
* @RequestMapping(value = "/something",params="myParam=myValue")請求包含myParam參數(shù),并且該參數(shù)值為myValue
* @RequestMapping(value = "/something",params="!myParam") 請求不包含myParam參數(shù)
*/
String[] params() default {};
/**
* 指定HttpRequest中包含的頭部信息,使用方式如下:
* @RequestMapping(value = "/something", headers="content-type")請求包含該頭部
* @RequestMapping(value = "/something", headers="content-type=text/*")請求包含特定值的頭部
* @RequestMapping(value = "/something", headers="!content-type")請求不包含該頭部
*/
String[] headers() default {};
}
注:如果在類層次指定了映射,則方法層次上都將繼承類層次的映射
3、獲取HttpRequest中得參數(shù)
@RequestMapping("active")
public @ResponseBody boolean active(Long accountId) {
return accountService.activeAccount(accountId);
}
@RequestMapping("active")
public @ResponseBody boolean active(Account account) {
return accountService.activeAccount(accountId);
}
@RequestMapping("inactive")
public @ResponseBody boolean inactive(@RequestParam("accountId") Long accountId,
@RequestHeader("User-Agent") String userAgent,
@CookieValue("loginId") String loginId) {
return accountService.inactiveAccount(accountId);
}
@RequestMapping(value = "list/{pageNo}", method = RequestMethod.GET)
public String list(@PathVariable int pageNo) {
return "/account/list";
}
@RequestMapping(value = "add", method = RequestMethod.GET)
public String add(@RequestBody String body) {
return "/account/add";
}
active方法的入?yún)?accountId,如果請求中有名為 accountId的參數(shù),則會(huì)進(jìn)行默認(rèn)綁定,不僅基本類型,javabean的屬性也可以默認(rèn)進(jìn)行綁定;
如果需要明確綁定,使用@RequestParam。 一般建議進(jìn)行明確指定。
3.1 @RequestParam 綁定httpRequest中參數(shù),@RequestParam("accountId") 完整形式為 @RequestParam(value="accountId",required=true,defaultValue=null)
3.2 @RequestHeader 綁定httpRequest頭部信息,@RequestHeader("User-Agent") 完整形式為 @RequestHeader(value="User-Agebt",required=true, defaultValue=null)
3.3 @CookieValue 綁定一個(gè)Cookie值,@CookieValue("loginId") 完整形式為 @CookieValue(value="loginId",required=true,defaultValue=null)
3.4 @RequestBody 將httpRequest的body綁定到方法參數(shù)上
3.5 @ModelAttribute 有兩種使用方式: 1)在方法級(jí)別,指定方法的返回值綁定到model中; 2)方法參數(shù)級(jí)別,指定model中的值綁定到方法的入?yún)⑸?示例如下:
@ModelAttribute("countryList")
public List<String> getCountries() {
return new ArrayList<String>();
}
@RequestMapping(value = "search", method = RequestMethod.POST)
public String searchAccount(@ModelAttribute("accountId") Long accountId) {
return "/search";
}
4、使用@ResponseBody 生成response
適用于webservice的數(shù)據(jù)交換,或ajax異步請求,text、json或者xml格式的數(shù)據(jù)交換。
例如訪問: http://localhost:8080/accounts/info.htm
@RequestMapping(value = "info")
public @ResponseBody Account getAccount() {
Account a = new Account();
a.setId(123L);
a.setName("zhangsan");
return a;
}
返回?cái)?shù)據(jù)如下: {"name":"zhangsan","id":123}
從上面例子可以看出,使用@ResponseBody后,返回的javabean默認(rèn)被序列化成json格式的數(shù)據(jù)并被寫入到response body中。
@Request 和 @ReponseBody 使用了HttpMessageConverter機(jī)制。下面是HttpMessageConverter的繼承體系。

常用的有如下幾個(gè):
StringHttpMessageConverter ---字符串
MappingJacksonHttpMessageConverter ----json
ByteArrayHttpMessageConverter ----字節(jié)數(shù)組
MarshallingHttpMessageConverter -----xml
5、使用模板技術(shù)生成response
適用于一般頁面請求。可以使用velocity freemarker等模板技術(shù),在dispatcher-servlet.xml中需要設(shè)置viewResolver。
@RequestMapping("/index")
public String index(ModelMap modelMap) {
modelMap.put("name", "liucs");
return "index";
}
@RequestMapping("/index")
public String index2(Model model) {
model.addAttribute("name","liucs");
return "index";
}
@RequestMapping("/index")
public ModelAndView index3() throws Exception {
ModelAndView mav = new ModelAndView("index");
mav.addObject("name", "liucs");
return mav;
}
如上面代碼index1和index2所示,不使用@ResponseBody注解。 返回一個(gè)String類型,這個(gè)String是viewname, 如果是重定向,return "redirect:/index.htm".
入?yún)⒖梢园琈odelMap或者M(jìn)odel,其實(shí)這兩者是一個(gè)東西,作用一樣。也可以采用index3式的傳統(tǒng)寫法,返回一個(gè)ModelAndView對象。
6、數(shù)據(jù)驗(yàn)證
@InitBinder標(biāo)注
@InitBinder
public void myInitBinder(WebDataBinder binder){
binder.setDisallowedFields(new String[]{"id"});
}
通過在方法中聲明一個(gè)BindingResult參數(shù)來啟動(dòng)綁定和驗(yàn)證
@RequestMapping("update")
public void update(@ModelAttribute("account") Account account,BindingResult bindResult) {
if(bindResult.hasErrors()){
//……
}
}
需要注意以下限制:
1、BindingResult參數(shù)必須跟在一個(gè)JavaBean參數(shù)后面
2、錯(cuò)誤會(huì)被自動(dòng)的綁定到model中,便于渲染模板時(shí)使用
3、不支持@RequestBody等類型的參數(shù)形式
7、異常處理
@ExceptionHandler