第一章 - 初識 SpringMVC注解

1艺栈、@Controller

在SpringMVC 中姑隅,控制器Controller 負(fù)責(zé)處理由DispatcherServlet 分發(fā)的請求得滤,它把用戶請求的數(shù)據(jù)經(jīng)過業(yè)務(wù)處理層處理之后封裝成一個(gè)Model 盐肃,然后再把該Model 返回給對應(yīng)的View 進(jìn)行展示赡盘。在SpringMVC 中提供了一個(gè)非常簡便的定義Controller 的方法号枕,你無需繼承特定的類或?qū)崿F(xiàn)特定的接口,只需使用@Controller 標(biāo)記一個(gè)類是Controller 陨享,然后使用@RequestMapping 和@RequestParam 等一些注解用以定義URL 請求和Controller 方法之間的映射葱淳,這樣的Controller 就能被外界訪問到。此外Controller 不會直接依賴于HttpServletRequest 和HttpServletResponse 等HttpServlet 對象抛姑,它們可以通過Controller 的方法參數(shù)靈活的獲取到赞厕。

@Controller 用于標(biāo)記在一個(gè)類上,使用它標(biāo)記的類就是一個(gè)SpringMVC Controller 對象定硝。分發(fā)處理器將會掃描使用了該注解的類的方法皿桑,并檢測該方法是否使用了@RequestMapping 注解。@Controller 只是定義了一個(gè)控制器類蔬啡,而使用@RequestMapping 注解的方法才是真正處理請求的處理器诲侮。單單使用@Controller 標(biāo)記在一個(gè)類上還不能真正意義上的說它就是SpringMVC 的一個(gè)控制器類,因?yàn)檫@個(gè)時(shí)候Spring 還不認(rèn)識它箱蟆。那么要如何做Spring 才能認(rèn)識它呢浆西?這個(gè)時(shí)候就需要我們把這個(gè)控制器類交給Spring 來管理。有兩種方式:

 ⊥缣凇(1)在SpringMVC 的配置文件中定義MyController 的bean 對象。

 ∨岛恕(2)在SpringMVC 的配置文件中告訴Spring 該到哪里去找標(biāo)記為@Controller 的Controller 控制器抄肖。

2、@RequestMapping

RequestMapping是一個(gè)用來處理請求地址映射的注解窖杀,可用于類或方法上漓摩。用于類上,表示類中的所有響應(yīng)請求的方法都是以該地址作為父路徑入客。

RequestMapping注解有六個(gè)屬性管毙,下面我們把她分成三類進(jìn)行說明(下面有相應(yīng)示例)。

1桌硫、 value夭咬, method;

value:? ? 指定請求的實(shí)際地址铆隘,指定的地址可以是URI Template 模式(后面將會說明)卓舵;

method:? 指定請求的method類型, GET膀钠、POST掏湾、PUT裹虫、DELETE等;

2融击、consumes筑公,produces

consumes: 指定處理請求的提交內(nèi)容類型(Content-Type),例如application/json, text/html;

produces:? ? 指定返回的內(nèi)容類型尊浪,僅當(dāng)request請求頭中的(Accept)類型中包含該指定類型才返回匣屡;

3、params际长,headers

params: 指定request中必須包含某些參數(shù)值是耸采,才讓該方法處理。

headers: 指定request中必須包含某些指定的header值工育,才能讓該方法處理請求虾宇。

3、@Resource和@Autowired

@Resource和@Autowired都是做bean的注入時(shí)使用如绸,其實(shí)@Resource并不是Spring的注解嘱朽,它的包是javax.annotation.Resource,需要導(dǎo)入怔接,但是Spring支持該注解的注入搪泳。

1、共同點(diǎn)

兩者都可以寫在字段和setter方法上扼脐。兩者如果都寫在字段上岸军,那么就不需要再寫setter方法。

2瓦侮、不同點(diǎn)

(1)@Autowired

? ? ? ? ? ? 1艰赞、@Autowired為Spring提供的注解,需要導(dǎo)入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入肚吏。

publicclass TestServiceImpl {

? ? // 下面兩種@Autowired只要使用一種即可? ?

? ? @Autowired

? ? privateUserDao userDao;// 用于字段上?

? ? @Autowired

? ? // 用于屬性的方法上this.userDao = userDao;

? ? publicvoidsetUserDao(UserDao userDao) {

? ? }

}

? ? ? ? ? ? ? 2方妖、 @Autowired注解是按照類型(byType)裝配依賴對象,默認(rèn)情況下它要求依賴對象必須存在罚攀,如果允許null值党觅,可以設(shè)置它的required屬性為false。如果我們想使用按照名稱(byName)來裝配斋泄,可以結(jié)合@Qualifier注解一起使用杯瞻。如下:

publicclass TestServiceImpl {

? ? @Autowired

? ? @Qualifier("userDao")

? ? private UserDao userDao;

}

(2)@Resource

? ? ? ? 1、@Resource默認(rèn)按照ByName自動注入炫掐,由J2EE提供又兵,需要導(dǎo)入包javax.annotation.Resource。@Resource有兩個(gè)重要的屬性:name和type,而Spring將@Resource注解的name屬性解析為bean的名字沛厨,而type屬性則解析為bean的類型宙地。所以,如果使用name屬性逆皮,則使用byName的自動注入策略宅粥,而使用type屬性時(shí)則使用byType自動注入策略。如果既不制定name也不制定type屬性电谣,這時(shí)將通過反射機(jī)制使用byName自動注入策略秽梅。

publicclass TestServiceImpl {

? ? ? ? // 下面兩種@Resource只要使用一種即可@Resource(name="userDao")

? ? ? ? privateUserDao userDao;// 用于字段上?

? ? ? ? @Resource(name="userDao")

? ? ? ? publicvoidsetUserDao(UserDao userDao) {// 用于屬性的setter方法上this.userDao = userDao;

? ? }

}

注:最好是將@Resource放在setter方法上,因?yàn)檫@樣更符合面向?qū)ο蟮乃枷虢宋ㄟ^set企垦、get去操作屬性,而不是直接去操作屬性晒来。

@Resource裝配順序:

? ? ①如果同時(shí)指定了name和type钞诡,則從Spring上下文中找到唯一匹配的bean進(jìn)行裝配,找不到則拋出異常湃崩。

? ? ②如果指定了name荧降,則從上下文中查找名稱(id)匹配的bean進(jìn)行裝配,找不到則拋出異常攒读。

? ? ③如果指定了type朵诫,則從上下文中找到類似匹配的唯一bean進(jìn)行裝配,找不到或是找到多個(gè)薄扁,都會拋出異常剪返。

? ? ④如果既沒有指定name,又沒有指定type邓梅,則自動按照byName方式進(jìn)行裝配随夸;如果沒有匹配,則回退為一個(gè)原始類型進(jìn)行匹配震放,如果匹配則自動裝配。

? ? @Resource的作用相當(dāng)于@Autowired驼修,只不過@Autowired按照byType自動注入殿遂。

4、@ModelAttribute和 @SessionAttributes

? ? ? ? 代表的是:該Controller的所有方法在調(diào)用前乙各,先執(zhí)行此@ModelAttribute方法墨礁,可用于注解和方法參數(shù)中,可以把這個(gè)@ModelAttribute特性耳峦,應(yīng)用在BaseController當(dāng)中恩静,所有的Controller繼承BaseController,即可實(shí)現(xiàn)在調(diào)用Controller時(shí),先執(zhí)行@ModelAttribute方法驶乾。

@SessionAttributes即將值放到session作用域中邑飒,寫在class上面。

具體示例參見下面:使用 @ModelAttribute 和 @SessionAttributes 傳遞和保存數(shù)據(jù)

5级乐、@PathVariable

用于將請求URL中的模板變量映射到功能處理方法的參數(shù)上疙咸,即取出uri模板中的變量作為參數(shù)。如圖一所示:


圖一

6风科、@requestParam

@requestParam主要用于在SpringMVC后臺控制層獲取參數(shù)撒轮,類似一種是request.getParameter("name"),它有三個(gè)常用參數(shù):defaultValue = "0", required = false, value = "isApp"贼穆;defaultValue 表示設(shè)置默認(rèn)值题山,required 銅過boolean設(shè)置是否是必須要傳入的參數(shù),value 值表示接受的傳入的參數(shù)類型故痊。

7顶瞳、@ResponseBody

作用: 該注解用于將Controller的方法返回的對象,通過適當(dāng)?shù)腍ttpMessageConverter轉(zhuǎn)換為指定格式后崖蜜,寫入到Response對象的body數(shù)據(jù)區(qū)浊仆。

使用時(shí)機(jī):返回的數(shù)據(jù)不是html標(biāo)簽的頁面,而是其他某種格式的數(shù)據(jù)時(shí)(如json豫领、xml等)使用抡柿;

8、@Component

相當(dāng)于通用的注解等恐,當(dāng)不知道一些類歸到哪個(gè)層時(shí)使用洲劣,但是不建議。

9课蔬、@Repository

用于注解dao層囱稽,在daoImpl類上面注解。

注:

1二跋、使用 @RequestMapping 來映射 Request 請求與處理器

方式一战惊、通過常見的類路徑和方法路徑結(jié)合訪問controller方法

方式二、使用uri模板

如圖二所示:

圖二

URI 模板就是在URI 中給定一個(gè)變量扎即,然后在映射的時(shí)候動態(tài)的給該變量賦值吞获。如URI 模板http://localhost/app/{variable1}/index.html ,這個(gè)模板里面包含一個(gè)變量variable1 谚鄙,那么當(dāng)我們請求http://localhost/app/hello/index.html 的時(shí)候各拷,該URL 就跟模板相匹配,只是把模板中的variable1 用hello 來取代闷营。這個(gè)變量在SpringMVC 中是使用@PathVariable 來標(biāo)記的烤黍。在SpringMVC 中,我們可以使用@PathVariable 來標(biāo)記一個(gè)Controller 的處理方法參數(shù),表示該參數(shù)的值將使用URI 模板中對應(yīng)的變量的值來賦值速蕊。

代碼中我們定義了兩個(gè)URI 變量嫂丙,一個(gè)是控制器類上的variable1 ,一個(gè)是showView 方法上的variable2 互例,然后在showView 方法的參數(shù)里面使用@PathVariable標(biāo)記使用了這兩個(gè)變量奢入。所以當(dāng)我們使用/test/hello/showView/2.do 來請求的時(shí)候就可以訪問到MyController 的showView 方法,這個(gè)時(shí)候variable1 就被賦予值hello 媳叨,variable2 就被賦予值2 腥光,然后我們在showView 方法參數(shù)里面標(biāo)注了參數(shù)variable1 和variable2 是來自訪問路徑的path 變量,這樣方法參數(shù)variable1 和variable2 就被分別賦予hello 和2 糊秆。方法參數(shù)variable1 是定義為String 類型武福,variable2 是定義為int 類型,像這種簡單類型在進(jìn)行賦值的時(shí)候Spring 是會幫我們自動轉(zhuǎn)換的痘番。

在上面的代碼中我們可以看到在標(biāo)記variable1 為path 變量的時(shí)候我們使用的是@PathVariable 捉片,而在標(biāo)記variable2 的時(shí)候使用的是@PathVariable(“variable2”) 。這兩者有什么區(qū)別呢汞舱?第一種情況就默認(rèn)去URI 模板中找跟參數(shù)名相同的變量伍纫,但是這種情況只有在使用debug 模式進(jìn)行編譯的時(shí)候才可以,而第二種情況是明確規(guī)定使用的就是URI 模板中的variable2 變量昂芜。當(dāng)不是使用debug 模式進(jìn)行編譯莹规,或者是所需要使用的變量名跟參數(shù)名不相同的時(shí)候,就要使用第二種方式明確指出使用的是URI 模板中的哪個(gè)變量泌神。

除了在請求路徑中使用URI 模板良漱,定義變量之外,@RequestMapping 中還支持通配符“* ”欢际。如下面的代碼我就可以使用/myTest/whatever/wildcard.do 訪問到Controller 的testWildcard 方法母市。如圖三所示:


圖三

當(dāng)@RequestParam中沒有指定參數(shù)名稱時(shí),Spring 在代碼是debug 編譯的情況下會默認(rèn)取更方法參數(shù)同名的參數(shù)损趋,如果不是debug 編譯的就會報(bào)錯(cuò)患久。

2、使用 @RequestMapping 的一些高級用法

? ? ? ? (1)params屬性

如圖四所示:

圖四

? ? 注:用@RequestMapping 的params 屬性指定了三個(gè)參數(shù)浑槽,這些參數(shù)都是針對請求參數(shù)而言的蒋失,它們分別表示參數(shù)param1 的值必須等于value1 ,參數(shù)param2 必須存在括荡,值無所謂,參數(shù)param3 必須不存在溉旋,只有當(dāng)請求/testParams.do 并且滿足指定的三個(gè)參數(shù)條件的時(shí)候才能訪問到該方法畸冲。所以當(dāng)請求/testParams.do?param1=value1&m2=value2 的時(shí)候能夠正確訪問到該testParams 方法,當(dāng)請求/testParams.do?param1=value1&m2=value2&m3=value3 的時(shí)候就不能夠正常的訪問到該方法,因?yàn)樵贎RequestMapping 的params 參數(shù)里面指定了參數(shù)param3 是不能存在的邑闲。

? ? ? ? (2)method屬性

圖五

? ? 注:在上面的代碼中就使用method 參數(shù)限制了以GET 或DELETE 方法請求/testMethod 的時(shí)候才能訪問到該Controller 的testMethod 方法算行。

? ? ? ? (3)headers屬性

圖六

? ? 注:headers 屬性的用法和功能與params 屬性相似。在上面的代碼中當(dāng)請求/testHeaders.do 的時(shí)候只有當(dāng)請求頭包含Accept 信息苫耸,且請求的host 為localhost 的時(shí)候才能正確的訪問到testHeaders 方法州邢。

3、 @RequestMapping 標(biāo)記的處理器方法支持的方法參數(shù)和返回類型

1. 支持的方法參數(shù)類型

(1 )HttpServlet 對象褪子,主要包括HttpServletRequest 量淌、HttpServletResponse 和HttpSession 對象。 這些參數(shù)Spring 在調(diào)用處理器方法的時(shí)候會自動給它們賦值嫌褪,所以當(dāng)在處理器方法中需要使用到這些對象的時(shí)候呀枢,可以直接在方法上給定一個(gè)方法參數(shù)的申明,然后在方法體里面直接用就可以了笼痛。但是有一點(diǎn)需要注意的是在使用HttpSession 對象的時(shí)候裙秋,如果此時(shí)HttpSession 對象還沒有建立起來的話就會有問題。

(2 )Spring 自己的WebRequest 對象缨伊。 使用該對象可以訪問到存放在HttpServletRequest 和HttpSession 中的屬性值摘刑。

(3 )InputStream 、OutputStream 刻坊、Reader 和Writer 枷恕。 InputStream 和Reader 是針對HttpServletRequest 而言的,可以從里面取數(shù)據(jù)紧唱;OutputStream 和Writer 是針對HttpServletResponse 而言的活尊,可以往里面寫數(shù)據(jù)。

(4 )使用@PathVariable 、@RequestParam 蹲堂、@CookieValue 和@RequestHeader 標(biāo)記的參數(shù)宫盔。

? (5 )使用@ModelAttribute 標(biāo)記的參數(shù)。

? (6 )java.util.Map 铜犬、Spring 封裝的Model 和ModelMap 。 這些都可以用來封裝模型數(shù)據(jù)轻庆,用來給視圖做展示癣猾。

(7 )實(shí)體類。 可以用來接收上傳的參數(shù)余爆。

(8 )Spring 封裝的MultipartFile 纷宇。 用來接收上傳文件的。

(9 )Spring 封裝的Errors 和BindingResult 對象蛾方。 這兩個(gè)對象參數(shù)必須緊接在需要驗(yàn)證的實(shí)體對象參數(shù)之后像捶,它里面包含了實(shí)體對象的驗(yàn)證結(jié)果上陕。

2. 支持的返回類型

? (1 )一個(gè)包含模型和視圖的ModelAndView 對象。

? (2 )一個(gè)模型對象拓春,這主要包括Spring 封裝好的Model 和ModelMap 释簿,以及java.util.Map ,當(dāng)沒有視圖返回的時(shí)候視圖名稱將由RequestToViewNameTranslator 來決定硼莽。

? (3 )一個(gè)View 對象庶溶。這個(gè)時(shí)候如果在渲染視圖的過程中模型的話就可以給處理器方法定義一個(gè)模型參數(shù),然后在方法體里面往模型中添加值懂鸵。

? (4 )一個(gè)String 字符串偏螺。這往往代表的是一個(gè)視圖名稱。這個(gè)時(shí)候如果需要在渲染視圖的過程中需要模型的話就可以給處理器方法一個(gè)模型參數(shù)矾瑰,然后在方法體里面往模型中添加值就可以了砖茸。

? (5 )返回值是void 。這種情況一般是我們直接把返回結(jié)果寫到HttpServletResponse 中了殴穴,如果沒有寫的話凉夯,那么Spring 將會利用RequestToViewNameTranslator 來返回一個(gè)對應(yīng)的視圖名稱。如果視圖中需要模型的話采幌,處理方法與返回字符串的情況相同劲够。

? (6 )如果處理器方法被注解@ResponseBody 標(biāo)記的話,那么處理器方法的任何返回類型都會通過HttpMessageConverters 轉(zhuǎn)換之后寫到HttpServletResponse 中休傍,而不會像上面的那些情況一樣當(dāng)做視圖或者模型來處理征绎。

? (7 )除以上幾種情況之外的其他任何返回類型都會被當(dāng)做模型中的一個(gè)屬性來處理,而返回的視圖還是由RequestToViewNameTranslator 來決定磨取,添加到模型中的屬性名稱可以在該方法上用@ModelAttribute(“attributeName”) 來定義人柿,否則將使用返回類型的類名稱的首字母小寫形式來表示。使用@ModelAttribute 標(biāo)記的方法會在@RequestMapping 標(biāo)記的方法執(zhí)行之前執(zhí)行忙厌。

4凫岖、使用 @ModelAttribute 和 @SessionAttributes 傳遞和保存數(shù)據(jù)

SpringMVC 支持使用 @ModelAttribute和 @SessionAttributes在不同的模型(model)和控制器之間共享數(shù)據(jù)。@ModelAttribute 主要有兩種使用方式逢净,一種是標(biāo)注在方法上哥放,一種是標(biāo)注在 Controller 方法參數(shù)上。

當(dāng) @ModelAttribute標(biāo)記在方法上的時(shí)候爹土,該方法將在處理器方法執(zhí)行之前執(zhí)行甥雕,然后把返回的對象存放在 session 或模型屬性中,屬性名稱可以使用 @ModelAttribute(“attributeName”) 在標(biāo)記方法的時(shí)候指定胀茵,若未指定社露,則使用返回類型的類名稱(首字母小寫)作為屬性名稱。關(guān)于 @ModelAttribute 標(biāo)記在方法上時(shí)對應(yīng)的屬性是存放在 session 中還是存放在模型中琼娘,我們來做一個(gè)實(shí)驗(yàn)峭弟,如圖七


圖七

當(dāng)我們請求 /myTest/sayHello.do 的時(shí)候使用 @ModelAttribute 標(biāo)記的方法會先執(zhí)行赁濒,然后把它們返回的對象存放到模型中。最終訪問到 sayHello 方法的時(shí)候孟害,使用 @ModelAttribute 標(biāo)記的方法參數(shù)都能被正確的注入值。執(zhí)行結(jié)果:Hello world,Hello user210

? ? ? 由執(zhí)行結(jié)果我們可以看出來挪拟,此時(shí) session 中沒有包含任何屬性挨务,也就是說上面的那些對象都是存放在模型屬性中,而不是存放在 session 屬性中玉组。那要如何才能存放在 session 屬性中呢谎柄?這個(gè)時(shí)候我們先引入一個(gè)新的概念 @SessionAttributes ,它的用法會在講完 @ModelAttribute 之后介紹惯雳,這里我們就先拿來用一下朝巫。我們在 MyController 類上加上 @SessionAttributes 屬性標(biāo)記哪些是需要存放到 session 中的∈埃看圖八的代碼:

圖八

在上面代碼中我們指定了屬性為 intValue 或 stringValue 或者類型為 User 的都會放到 Session中劈猿,利用上面的代碼當(dāng)我們訪問 /myTest/sayHello.do 的時(shí)候,結(jié)果如下:

Hello world,Hello user210

仍然沒有打印出任何 session 屬性潮孽,這是怎么回事呢揪荣?怎么定義了把模型中屬性名為 intValue 的對象和類型為 User 的對象存到 session 中,而實(shí)際上沒有加進(jìn)去呢往史?難道我們錯(cuò)啦仗颈?我們當(dāng)然沒有錯(cuò),只是在第一次訪問 /myTest/sayHello.do 的時(shí)候 @SessionAttributes 定義了需要存放到 session 中的屬性椎例,而且這個(gè)模型中也有對應(yīng)的屬性挨决,但是這個(gè)時(shí)候還沒有加到 session 中,所以 session 中不會有任何屬性订歪,等處理器方法執(zhí)行完成后 Spring 才會把模型中對應(yīng)的屬性添加到 session 中脖祈。所以當(dāng)請求第二次的時(shí)候就會出現(xiàn)如下結(jié)果:

Hello world,Hello user210

user2

intValue

stringValue

當(dāng) @ModelAttribute 標(biāo)記在處理器方法參數(shù)上的時(shí)候,表示該參數(shù)的值將從模型或者 Session 中取對應(yīng)名稱的屬性值陌粹,該名稱可以通過 @ModelAttribute(“attributeName”) 來指定撒犀,若未指定,則使用參數(shù)類型的類名稱(首字母小寫)作為屬性名稱掏秩。

5或舞、@PathVariable和@RequestParam的區(qū)別

請求路徑上有個(gè)id的變量值,可以通過@PathVariable來獲取? @RequestMapping(value = "/page/{id}", method = RequestMethod.GET)?

@RequestParam用來獲得靜態(tài)的URL請求入?yún)? ? spring注解時(shí)action里用到蒙幻。

簡介:

handler method 參數(shù)綁定常用的注解,我們根據(jù)他們處理的Request的不同內(nèi)容部分分為四類:(主要講解常用類型)

A映凳、處理requet uri 部分(這里指uri template中variable,不含queryString部分)的注解:? @PathVariable;

B邮破、處理request header部分的注解:? @RequestHeader, @CookieValue;

C诈豌、處理request body部分的注解:@RequestParam,? @RequestBody;

D仆救、處理attribute類型是注解: @SessionAttributes, @ModelAttribute;

(1)、@PathVariable

當(dāng)使用@RequestMapping URI template 樣式映射時(shí)矫渔, 即 someUrl/{paramId}, 這時(shí)的paramId可通過 @Pathvariable注解綁定它傳過來的值到方法的參數(shù)上彤蔽。

示例代碼圖九所示:


圖九

上面代碼把URI template 中變量 ownerId的值和petId的值,綁定到方法的參數(shù)上庙洼。若方法參數(shù)名稱和需要綁定的uri template中變量名稱不一致顿痪,需要在@PathVariable("name")指定uri template中的名稱。

(2)油够、 @RequestHeader蚁袭、@CookieValue

@RequestHeader 注解,可以把Request請求header部分的值綁定到方法的參數(shù)上石咬。

示例代碼:

這是一個(gè)Request 的header部分:

Host? ? ? ? ? ? ? ? ? ? localhost:8080?

Accept? ? ? ? ? ? ? ? ? text/html,application/xhtml+xml,application/xml;q=0.9?

Accept-Language? ? ? ? fr,en-gb;q=0.7,en;q=0.3?

Accept-Encoding? ? ? ? gzip,deflate?

Accept-Charset? ? ? ? ? ISO-8859-1,utf-8;q=0.7,*;q=0.7?

Keep-Alive? ? ? ? ? ? ? 300?

@RequestMapping("/displayHeaderInfo.do")

public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding,@RequestHeader("Keep-Alive")longkeepAlive)? {

}?

上面的代碼揩悄,把request header部分的 Accept-Encoding的值,綁定到參數(shù)encoding上了鬼悠, Keep-Alive header的值綁定到參數(shù)keepAlive上删性。

@CookieValue 可以把Request header中關(guān)于cookie的值綁定到方法的參數(shù)上。

例如有如下Cookie值:

  JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84

@RequestMapping("/displayHeaderInfo.do")

public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie)? {

}

即把JSESSIONID的值綁定到參數(shù)cookie上焕窝。

(3)镇匀、@RequestParam, @RequestBody,@RequestParam

A) 常用來處理簡單類型的綁定,通過Request.getParameter() 獲取的String可直接轉(zhuǎn)換為簡單類型的情況( String--> 簡單類型的轉(zhuǎn)換操作由ConversionService配置的轉(zhuǎn)換器來完成)袜啃;因?yàn)槭褂胷equest.getParameter()方式獲取參數(shù)汗侵,所以可以處理get 方式中queryString的值,也可以處理post方式中 body data的值群发;

B)用來處理Content-Type: 為application/x-www-form-urlencoded編碼的內(nèi)容晰韵,提交方式GET、POST熟妓;

C) 該注解有兩個(gè)屬性: value雪猪、required; value用來指定要傳入值的id名稱起愈,required用來指示參數(shù)是否必須綁定只恨;

@RequestBody

該注解常用來處理Content-Type: 不是application/x-www-form-urlencoded編碼的內(nèi)容,例如application/json, application/xml等抬虽;

它是通過使用HandlerAdapter 配置的HttpMessageConverters來解析post data body官觅,然后綁定到相應(yīng)的bean上的。

因?yàn)榕渲糜蠪ormHttpMessageConverter阐污,所以也可以用來處理application/x-www-form-urlencoded的內(nèi)容休涤,處理完的結(jié)果放在一個(gè)MultiValueMap里,這種情況在某些特殊需求下使用,詳情查看FormHttpMessageConverter api;


(4)功氨、@SessionAttributes, @ModelAttribute

@SessionAttributes:

該注解用來綁定HttpSession中的attribute對象的值序苏,便于在方法中的參數(shù)里使用。

該注解有value捷凄、types兩個(gè)屬性忱详,可以通過名字和類型指定要使用的attribute 對象;

@ModelAttribute

該注解有兩個(gè)用法跺涤,一個(gè)是用于方法上踱阿,一個(gè)是用于參數(shù)上;

用于方法上時(shí):? 通常用來在處理@RequestMapping之前钦铁,為請求綁定需要從后臺查詢的model;

用于參數(shù)上時(shí): 用來通過名稱對應(yīng)才漆,把相應(yīng)名稱的值綁定到注解的參數(shù)bean上牛曹;要綁定的值來源于:

A) @SessionAttributes 啟用的attribute 對象上;

B) @ModelAttribute 用于方法上時(shí)指定的model對象醇滥;

C) 上述兩種情況都沒有時(shí)黎比,new一個(gè)需要綁定的bean對象,然后把request中按名稱對應(yīng)的方式把值綁定到bean中鸳玩。

6阅虫、< context:component-scan base-package = "" /> 淺析注解掃描包

component-scan 默認(rèn)掃描的注解類型是 @Component,不過不跟,在 @Component 語義基礎(chǔ)上細(xì)化后的 @Repository, @Service 和 @Controller 也同樣可以獲得 component-scan 的青睞

有了<context:component-scan>颓帝,另一個(gè)<context:annotation-config />標(biāo)簽根本可以移除掉,因?yàn)橐呀?jīng)被包含進(jìn)去了

另外<context:annotation-config />還提供了兩個(gè)子標(biāo)簽

1.? ? ? <context: include-filter>? //指定掃描的路徑

2.? ? ? <context:exclude-filter> //排除掃描的路徑

有一個(gè)use-default-filters屬性窝革,屬性默認(rèn)為true,表示會掃描指定包下的全部的標(biāo)有@Component的類购城,并注冊成bean.也就是@Component的子注解@Service,@Reposity等。

這種掃描的粒度有點(diǎn)太大虐译,如果你只想掃描指定包下面的Controller或其他內(nèi)容則設(shè)置use-default-filters屬性為false瘪板,表示不再按照scan指定的包掃描,而是按照指定的包掃描漆诽,示例:

<context:component-scan base-package="com.jkian" use-default-filters="false">

? ? ? ? <context:include-filter type="regex" expression="com.jkian.*">//注意后面要寫.*

<context:component-scan>

當(dāng)沒有設(shè)置use-default-filters屬性或者屬性為true時(shí)侮攀,表示基于base-packge包下指定掃描的具體路徑

<context:component-scan base-package="com.jkian">

? ? <context:include-filter type="regex" expression=".controller.*" />

? ? <context:include-filter type="regex" expression=".service.*" />

? ? <context:include-filter type="regex" expression=".dao.*">

</context:component-scan>

效果相當(dāng)于:

<context:component-scan base-package="com.jkian">//指定包

? ? ? ? <context:exclude-filter type="regex" expression=".entity.*">//排除掃描的路徑

</context:component-scan>

或者

<context:component-scan base-package="com.jkian" /> // 推薦使用

注意:本人嘗試時(shí)無論哪種情況和都不能同時(shí)存在

7、開啟注解

<mvc:annotation-driven />

8厢拭、開啟靜態(tài)資源訪問

<mvc:resources location="/index/" mapping="/index/**">

<mvc:resources location="/js/" mapping="/js/**">

<mvc:resources location="/pages/" mapping="/pages/**" >

9兰英、開啟文件Cache,可以設(shè)置cache-period=1000

<mvc:resources location="/downFile/" mapping="/downFile/**" cache-period="0" >

10、Documented 注解

Documented 注解表明這個(gè)注解應(yīng)該被 javadoc工具記錄. 默認(rèn)情況下,javadoc是不包括注解的. 但如果聲明注解時(shí)指定了

@Documented,則它會被 javadoc 之類的工具處理,

所以注解類型信息也會被包括在生成的文檔中.(個(gè)人觀點(diǎn):不是重點(diǎn)供鸠,了解即可箭昵。勿噴)

11、Retention注解

Retention(保留)注解說明,這種類型的注解會被保留到那個(gè)階段. 有三個(gè)值:

1.RetentionPolicy.SOURCE —— 這種類型的Annotations只在源代碼級別保留,編譯時(shí)就會被忽略

2.RetentionPolicy.CLASS —— 這種類型的Annotations編譯時(shí)被保留,在class文件中存在,但JVM將會忽略

3.RetentionPolicy.RUNTIME —— 這種類型的Annotations將被JVM保留,所以他們能在運(yùn)行時(shí)被JVM或其他使用反射機(jī)制的代碼所讀取和使用.

下面示例中, @Retention(RetentionPolicy.RUNTIME)注解表明 Test_Retention注解將會由虛擬機(jī)保留,以便它可以在運(yùn)行時(shí)通過反射讀取.

12回季、Target注解

@Target說明了Annotation所修飾的對象范圍:Annotation可被用于 packages家制、types(類正林、接口、枚舉颤殴、Annotation類型)觅廓、類型成員(方法、構(gòu)造方法涵但、成員變量杈绸、枚舉值)、方法參數(shù)和本地變量(如循環(huán)變量矮瘟、catch參數(shù))瞳脓。在Annotation類型的聲明中使用了target可更加明晰其修飾的目標(biāo)。

作用:用于描述注解的使用范圍(即:被描述的注解可以用在什么地方)

取值(ElementType)有:

1.CONSTRUCTOR:用于描述構(gòu)造器

2.FIELD:用于描述域

3.LOCAL_VARIABLE:用于描述局部變量

4.METHOD:用于描述方法

5.PACKAGE:用于描述包

6.PARAMETER:用于描述參數(shù)

7.TYPE:用于描述類澈侠、接口(包括注解類型) 或enum聲明

13劫侧、Inherited 注解

這是一個(gè)稍微復(fù)雜的注解類型. 它指明被注解的類會自動繼承. 更具體地說,如果定義注解時(shí)使用了 @Inherited 標(biāo)記,然后用定義的注解來標(biāo)注另一個(gè)父類, 父類又有一個(gè)子類(subclass),則父類的所有屬性將被繼承到它的子類中.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市哨啃,隨后出現(xiàn)的幾起案子烧栋,更是在濱河造成了極大的恐慌,老刑警劉巖拳球,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件审姓,死亡現(xiàn)場離奇詭異,居然都是意外死亡祝峻,警方通過查閱死者的電腦和手機(jī)魔吐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莱找,“玉大人画畅,你說我怎么就攤上這事∷尉啵” “怎么了轴踱?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谚赎。 經(jīng)常有香客問我淫僻,道長,這世上最難降的妖魔是什么壶唤? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任雳灵,我火速辦了婚禮,結(jié)果婚禮上闸盔,老公的妹妹穿的比我還像新娘悯辙。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布躲撰。 她就那樣靜靜地躺著针贬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拢蛋。 梳的紋絲不亂的頭發(fā)上桦他,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機(jī)與錄音谆棱,去河邊找鬼快压。 笑死,一個(gè)胖子當(dāng)著我的面吹牛垃瞧,可吹牛的內(nèi)容都是我干的蔫劣。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼个从,長吁一口氣:“原來是場噩夢啊……” “哼脉幢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起信姓,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绸罗,沒想到半個(gè)月后意推,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡珊蟀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年菊值,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片育灸。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腻窒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出磅崭,到底是詐尸還是另有隱情儿子,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布砸喻,位于F島的核電站柔逼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏割岛。R本人自食惡果不足惜愉适,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望癣漆。 院中可真熱鬧维咸,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至费坊,卻和暖如春倒槐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背附井。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工讨越, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人永毅。 一個(gè)月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓把跨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親沼死。 傳聞我的和親對象是個(gè)殘疾皇子着逐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容