[转]springmvc常用注解标签详解
1、@Controller
在SpringMVC?中,控制器Controller?負(fù)責(zé)處理由DispatcherServlet?分發(fā)的請(qǐng)求,它把用戶請(qǐng)求的數(shù)據(jù)經(jīng)過業(yè)務(wù)處理層處理之后封裝成一個(gè)Model?,然后再把該Model?返回給對(duì)應(yīng)的View?進(jìn)行展示。在SpringMVC?中提供了一個(gè)非常簡(jiǎn)便的定義Controller?的方法,你無需繼承特定的類或?qū)崿F(xiàn)特定的接口,只需使用@Controller?標(biāo)記一個(gè)類是Controller?,然后使用@RequestMapping?和@RequestParam?等一些注解用以定義URL?請(qǐng)求和Controller?方法之間的映射,這樣的Controller?就能被外界訪問到。此外Controller?不會(huì)直接依賴于HttpServletRequest?和HttpServletResponse?等HttpServlet?對(duì)象,它們可以通過Controller?的方法參數(shù)靈活的獲取到。
@Controller?用于標(biāo)記在一個(gè)類上,使用它標(biāo)記的類就是一個(gè)SpringMVC Controller?對(duì)象。分發(fā)處理器將會(huì)掃描使用了該注解的類的方法,并檢測(cè)該方法是否使用了@RequestMapping?注解。@Controller?只是定義了一個(gè)控制器類,而使用@RequestMapping?注解的方法才是真正處理請(qǐng)求的處理器。單單使用@Controller?標(biāo)記在一個(gè)類上還不能真正意義上的說它就是SpringMVC?的一個(gè)控制器類,因?yàn)檫@個(gè)時(shí)候Spring?還不認(rèn)識(shí)它。那么要如何做Spring?才能認(rèn)識(shí)它呢?這個(gè)時(shí)候就需要我們把這個(gè)控制器類交給Spring?來管理。有兩種方式:
(1)在SpringMVC?的配置文件中定義MyController?的bean?對(duì)象。
(2)在SpringMVC?的配置文件中告訴Spring?該到哪里去找標(biāo)記為@Controller?的Controller?控制器。
<!--方式一--> <bean class="com.host.app.web.controller.MyController"/> <!--方式二--> < context:component-scan base-package = "com.host.app.web" />//路徑寫到controller的上一層(掃描包詳解見下面淺析)2、@RequestMapping
RequestMapping是一個(gè)用來處理請(qǐng)求地址映射的注解,可用于類或方法上。用于類上,表示類中的所有響應(yīng)請(qǐng)求的方法都是以該地址作為父路徑。
RequestMapping注解有六個(gè)屬性,下面我們把她分成三類進(jìn)行說明(下面有相應(yīng)示例)。
1、 value, method;
value:???? 指定請(qǐng)求的實(shí)際地址,指定的地址可以是URI Template 模式(后面將會(huì)說明);
method:? 指定請(qǐng)求的method類型, GET、POST、PUT、DELETE等;
2、consumes,produces
consumes: 指定處理請(qǐng)求的提交內(nèi)容類型(Content-Type),例如application/json, text/html;
produces:??? 指定返回的內(nèi)容類型,僅當(dāng)request請(qǐng)求頭中的(Accept)類型中包含該指定類型才返回;
3、params,headers
params: 指定request中必須包含某些參數(shù)值是,才讓該方法處理。
headers: 指定request中必須包含某些指定的header值,才能讓該方法處理請(qǐng)求。
3、@Resource和@Autowired? ?參考1 參考2?參考3?
@Resource和@Autowired都是做bean的注入時(shí)使用,其實(shí)@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要導(dǎo)入,但是Spring支持該注解的注入。
1、共同點(diǎn)
兩者都可以寫在字段和setter方法上。兩者如果都寫在字段上,那么就不需要再寫setter方法。
2、不同點(diǎn)
(1)@Autowired
@Autowired為Spring提供的注解,需要導(dǎo)入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
public class TestServiceImpl {// 下面兩種@Autowired只要使用一種即可@Autowiredprivate UserDao userDao; // 用于字段上@Autowiredpublic void setUserDao(UserDao userDao) { // 用于屬性的方法上this.userDao = userDao;} }@Autowired注解是按照類型(byType)裝配依賴對(duì)象,默認(rèn)情況下它要求依賴對(duì)象必須存在,如果允許null值,可以設(shè)置它的required屬性為false。如果我們想使用按照名稱(byName)來裝配,可以結(jié)合@Qualifier注解一起使用。如下:
public class TestServiceImpl {@Autowired@Qualifier("userDao")private UserDao userDao; }(2)@Resource
@Resource默認(rèn)按照ByName自動(dòng)注入,由J2EE提供,需要導(dǎo)入包javax.annotation.Resource。@Resource有兩個(gè)重要的屬性:name和type,而Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以,如果使用name屬性,則使用byName的自動(dòng)注入策略,而使用type屬性時(shí)則使用byType自動(dòng)注入策略。如果既不制定name也不制定type屬性,這時(shí)將通過反射機(jī)制使用byName自動(dòng)注入策略。
public class TestServiceImpl {// 下面兩種@Resource只要使用一種即可@Resource(name="userDao")private UserDao userDao; // 用于字段上@Resource(name="userDao")public void setUserDao(UserDao userDao) { // 用于屬性的setter方法上this.userDao = userDao;} }注:最好是將@Resource放在setter方法上,因?yàn)檫@樣更符合面向?qū)ο蟮乃枷?#xff0c;通過set、get去操作屬性,而不是直接去操作屬性。
@Resource裝配順序:
①如果同時(shí)指定了name和type,則從Spring上下文中找到唯一匹配的bean進(jìn)行裝配,找不到則拋出異常。
②如果指定了name,則從上下文中查找名稱(id)匹配的bean進(jìn)行裝配,找不到則拋出異常。
③如果指定了type,則從上下文中找到類似匹配的唯一bean進(jìn)行裝配,找不到或是找到多個(gè),都會(huì)拋出異常。
④如果既沒有指定name,又沒有指定type,則自動(dòng)按照byName方式進(jìn)行裝配;如果沒有匹配,則回退為一個(gè)原始類型進(jìn)行匹配,如果匹配則自動(dòng)裝配。
@Resource的作用相當(dāng)于@Autowired,只不過@Autowired按照byType自動(dòng)注入。
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ù)
參考:spring mvc:注解@ModelAttribute妙用??spring學(xué)習(xí)之@ModelAttribute運(yùn)用詳解
5、@PathVariable
用于將請(qǐng)求URL中的模板變量映射到功能處理方法的參數(shù)上,即取出uri模板中的變量作為參數(shù)。如:
@Controller public class TestController { @RequestMapping(value="/user/{userId}/roles/{roleId}",method = RequestMethod.GET) public String getLogin(@PathVariable("userId") String userId, @PathVariable("roleId") String roleId){ System.out.println("User Id : " + userId); System.out.println("Role Id : " + roleId); return "hello"; } @RequestMapping(value="/product/{productId}",method = RequestMethod.GET) public String getProduct(@PathVariable("productId") String productId){ System.out.println("Product Id : " + productId); return "hello"; } @RequestMapping(value="/javabeat/{regexp1:[a-z-]+}", method = RequestMethod.GET) public String getRegExp(@PathVariable("regexp1") String regexp1){ System.out.println("URI Part 1 : " + regexp1); return "hello"; } }6、@requestParam
@requestParam主要用于在SpringMVC后臺(tái)控制層獲取參數(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的方法返回的對(duì)象,通過適當(dāng)?shù)腍ttpMessageConverter轉(zhuǎn)換為指定格式后,寫入到Response對(duì)象的body數(shù)據(jù)區(qū)。
使用時(shí)機(jī):返回的數(shù)據(jù)不是html標(biāo)簽的頁(yè)面,而是其他某種格式的數(shù)據(jù)時(shí)(如json、xml等)使用;
8、@Component
相當(dāng)于通用的注解,當(dāng)不知道一些類歸到哪個(gè)層時(shí)使用,但是不建議。
9、@Repository
用于注解dao層,在daoImpl類上面注解。
?
注:
1、使用?@RequestMapping?來映射?Request?請(qǐng)求與處理器
方式一、通過常見的類路徑和方法路徑結(jié)合訪問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 中的屬性名稱 " , " 對(duì)應(yīng)的屬性值,它是一個(gè)對(duì)象 " );return modelAndView;} }
URI?模板就是在URI?中給定一個(gè)變量,然后在映射的時(shí)候動(dòng)態(tài)的給該變量賦值。如URI?模板http://localhost/app/{variable1}/index.html?,這個(gè)模板里面包含一個(gè)變量variable1?,那么當(dāng)我們請(qǐ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?模板中對(duì)應(yīng)的變量的值來賦值。
代碼中我們定義了兩個(gè)URI?變量,一個(gè)是控制器類上的variable1?,一個(gè)是showView?方法上的variable2?,然后在showView?方法的參數(shù)里面使用@PathVariable?標(biāo)記使用了這兩個(gè)變量。所以當(dāng)我們使用/test/hello/showView/2.do?來請(qǐng)求的時(shí)候就可以訪問到MyController?的showView?方法,這個(gè)時(shí)候variable1?就被賦予值hello?,variable2?就被賦予值2?,然后我們?cè)趕howView?方法參數(shù)里面標(biāo)注了參數(shù)variable1?和variable2?是來自訪問路徑的path?變量,這樣方法參數(shù)variable1?和variable2?就被分別賦予hello?和2?。方法參數(shù)variable1?是定義為String?類型,variable2?是定義為int?類型,像這種簡(jiǎn)單類型在進(jìn)行賦值的時(shí)候Spring?是會(huì)幫我們自動(dòng)轉(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è)變量。
?除了在請(qǐng)求路徑中使用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" ;} }當(dāng)@RequestParam中沒有指定參數(shù)名稱時(shí),Spring?在代碼是debug?編譯的情況下會(huì)默認(rèn)取更方法參數(shù)同名的參數(shù),如果不是debug?編譯的就會(huì)報(bào)錯(cuò)。
2、使用?@RequestMapping?的一些高級(jí)用法
(1)params屬性
@RequestMapping (value= "testParams" , params={ "param1=value1" , "param2" , "!param3" })public String testParams() {System. out .println( "test Params..........." );return "testParams" ;}用@RequestMapping?的params?屬性指定了三個(gè)參數(shù),這些參數(shù)都是針對(duì)請(qǐng)求參數(shù)而言的,它們分別表示參數(shù)param1?的值必須等于value1?,參數(shù)param2?必須存在,值無所謂,參數(shù)param3?必須不存在,只有當(dāng)請(qǐng)求/testParams.do?并且滿足指定的三個(gè)參數(shù)條件的時(shí)候才能訪問到該方法。所以當(dāng)請(qǐng)求/testParams.do?param1=value1¶m2=value2?的時(shí)候能夠正確訪問到該testParams?方法,當(dāng)請(qǐng)求/testParams.do?param1=value1¶m2=value2¶m3=value3?的時(shí)候就不能夠正常的訪問到該方法,因?yàn)樵?#64;RequestMapping?的params?參數(shù)里面指定了參數(shù)param3?是不能存在的。
(2)method屬性
@RequestMapping (value= "testMethod" , method={RequestMethod. GET , RequestMethod. DELETE })public String testMethod() {return "method" ;}在上面的代碼中就使用method?參數(shù)限制了以GET?或DELETE?方法請(qǐng)求/testMethod 的時(shí)候才能訪問到該Controller?的testMethod?方法。
(3)headers屬性
@RequestMapping (value= "testHeaders" , headers={ "host=localhost" , "Accept" })public String testHeaders() {return "headers" ;}headers?屬性的用法和功能與params?屬性相似。在上面的代碼中當(dāng)請(qǐng)求/testHeaders.do?的時(shí)候只有當(dāng)請(qǐng)求頭包含Accept?信息,且請(qǐng)求的host?為localhost?的時(shí)候才能正確的訪問到testHeaders?方法。
3、 @RequestMapping?標(biāo)記的處理器方法支持的方法參數(shù)和返回類型
1.?支持的方法參數(shù)類型
?????????(1?)HttpServlet?對(duì)象,主要包括HttpServletRequest?、HttpServletResponse?和HttpSession?對(duì)象。?這些參數(shù)Spring?在調(diào)用處理器方法的時(shí)候會(huì)自動(dòng)給它們賦值,所以當(dāng)在處理器方法中需要使用到這些對(duì)象的時(shí)候,可以直接在方法上給定一個(gè)方法參數(shù)的申明,然后在方法體里面直接用就可以了。但是有一點(diǎn)需要注意的是在使用HttpSession?對(duì)象的時(shí)候,如果此時(shí)HttpSession?對(duì)象還沒有建立起來的話就會(huì)有問題。
???(2?)Spring?自己的WebRequest?對(duì)象。?使用該對(duì)象可以訪問到存放在HttpServletRequest?和HttpSession?中的屬性值。
???(3?)InputStream?、OutputStream?、Reader?和Writer?。?InputStream?和Reader?是針對(duì)HttpServletRequest?而言的,可以從里面取數(shù)據(jù);OutputStream?和Writer?是針對(duì)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?對(duì)象。?這兩個(gè)對(duì)象參數(shù)必須緊接在需要驗(yàn)證的實(shí)體對(duì)象參數(shù)之后,它里面包含了實(shí)體對(duì)象的驗(yàn)證結(jié)果。
2.?支持的返回類型
? ?(1?)一個(gè)包含模型和視圖的ModelAndView?對(duì)象。
???(2?)一個(gè)模型對(duì)象,這主要包括Spring?封裝好的Model?和ModelMap?,以及java.util.Map?,當(dāng)沒有視圖返回的時(shí)候視圖名稱將由RequestToViewNameTranslator?來決定。
???(3?)一個(gè)View?對(duì)象。這個(gè)時(shí)候如果在渲染視圖的過程中模型的話就可以給處理器方法定義一個(gè)模型參數(shù),然后在方法體里面往模型中添加值。
???(4?)一個(gè)String?字符串。這往往代表的是一個(gè)視圖名稱。這個(gè)時(shí)候如果需要在渲染視圖的過程中需要模型的話就可以給處理器方法一個(gè)模型參數(shù),然后在方法體里面往模型中添加值就可以了。
???(5?)返回值是void?。這種情況一般是我們直接把返回結(jié)果寫到HttpServletResponse?中了,如果沒有寫的話,那么Spring?將會(huì)利用RequestToViewNameTranslator?來返回一個(gè)對(duì)應(yīng)的視圖名稱。如果視圖中需要模型的話,處理方法與返回字符串的情況相同。
???(6?)如果處理器方法被注解@ResponseBody?標(biāo)記的話,那么處理器方法的任何返回類型都會(huì)通過HttpMessageConverters?轉(zhuǎn)換之后寫到HttpServletResponse?中,而不會(huì)像上面的那些情況一樣當(dāng)做視圖或者模型來處理。
???(7?)除以上幾種情況之外的其他任何返回類型都會(huì)被當(dāng)做模型中的一個(gè)屬性來處理,而返回的視圖還是由RequestToViewNameTranslator?來決定,添加到模型中的屬性名稱可以在該方法上用@ModelAttribute(“attributeName”)?來定義,否則將使用返回類型的類名稱的首字母小寫形式來表示。使用@ModelAttribute?標(biāo)記的方法會(huì)在@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í)行,然后把返回的對(duì)象存放在?session?或模型屬性中,屬性名稱可以使用?@ModelAttribute(“attributeName”)?在標(biāo)記方法的時(shí)候指定,若未指定,則使用返回類型的類名稱(首字母小寫)作為屬性名稱。關(guān)于?@ModelAttribute?標(biāo)記在方法上時(shí)對(duì)應(yīng)的屬性是存放在?session?中還是存放在模型中,我們來做一個(gè)實(shí)驗(yàn),看下面一段代碼。
@Controller @RequestMapping ( "/myTest" ) public class MyController {@ModelAttribute ( "hello" )public String getModel() {System. out .println( "-------------Hello---------" );return "world" ;}@ModelAttribute ( "intValue" )public int getInteger() {System. out .println( "-------------intValue---------------" );return 10;}@RequestMapping ( "sayHello" )public void sayHello( @ModelAttribute ( "hello" ) String hello, @ModelAttribute ( "intValue" ) int num, @ModelAttribute ( "user2" ) User user, Writer writer, HttpSession session) throws IOException {writer.write( "Hello " + hello + " , Hello " + user.getUsername() + num);writer.write( "\r" );Enumeration enume = session.getAttributeNames();while (enume.hasMoreElements())writer.write(enume.nextElement() + "\r" );}@ModelAttribute ( "user2" )public User getUser(){System. out .println( "---------getUser-------------" );return new User(3, "user2" );} }當(dāng)我們請(qǐng)求?/myTest/sayHello.do?的時(shí)候使用?@ModelAttribute?標(biāo)記的方法會(huì)先執(zhí)行,然后把它們返回的對(duì)象存放到模型中。最終訪問到?sayHello?方法的時(shí)候,使用?@ModelAttribute?標(biāo)記的方法參數(shù)都能被正確的注入值。執(zhí)行結(jié)果如下所示:
?Hello world,Hello user210
???????由執(zhí)行結(jié)果我們可以看出來,此時(shí)?session?中沒有包含任何屬性,也就是說上面的那些對(duì)象都是存放在模型屬性中,而不是存放在?session?屬性中。那要如何才能存放在?session?屬性中呢?這個(gè)時(shí)候我們先引入一個(gè)新的概念?@SessionAttributes?,它的用法會(huì)在講完?@ModelAttribute?之后介紹,這里我們就先拿來用一下。我們?cè)?MyController?類上加上?@SessionAttributes?屬性標(biāo)記哪些是需要存放到?session?中的。看下面的代碼:
@Controller @RequestMapping ( "/myTest" ) @SessionAttributes (value={ "intValue" , "stringValue" }, types={User. class }) public class MyController {@ModelAttribute ( "hello" )public String getModel() {System. out .println( "-------------Hello---------" );return "world" ;}@ModelAttribute ( "intValue" )public int getInteger() {System. out .println( "-------------intValue---------------" );return 10;}@RequestMapping ( "sayHello" )public void sayHello(Map<String, Object> map, @ModelAttribute ( "hello" ) String hello, @ModelAttribute ( "intValue" ) int num, @ModelAttribute ( "user2" ) User user, Writer writer, HttpServletRequest request) throws IOException {map.put( "stringValue" , "String" );writer.write( "Hello " + hello + " , Hello " + user.getUsername() + num);writer.write( "\r" );HttpSession session = request.getSession();Enumeration enume = session.getAttributeNames();while (enume.hasMoreElements())writer.write(enume.nextElement() + "\r" );System. out .println(session);}@ModelAttribute ( "user2" )public User getUser() {System. out .println( "---------getUser-------------" );return new User(3, "user2" );} }在上面代碼中我們指定了屬性為?intValue?或?stringValue?或者類型為?User?的都會(huì)放到?Session中,利用上面的代碼當(dāng)我們?cè)L問?/myTest/sayHello.do?的時(shí)候,結(jié)果如下:
?Hello world,Hello user210
仍然沒有打印出任何?session?屬性,這是怎么回事呢?怎么定義了把模型中屬性名為?intValue?的對(duì)象和類型為?User?的對(duì)象存到?session?中,而實(shí)際上沒有加進(jìn)去呢?難道我們錯(cuò)啦?我們當(dāng)然沒有錯(cuò),只是在第一次訪問?/myTest/sayHello.do?的時(shí)候?@SessionAttributes?定義了需要存放到?session?中的屬性,而且這個(gè)模型中也有對(duì)應(yīng)的屬性,但是這個(gè)時(shí)候還沒有加到?session?中,所以?session?中不會(huì)有任何屬性,等處理器方法執(zhí)行完成后?Spring?才會(huì)把模型中對(duì)應(yīng)的屬性添加到?session?中。所以當(dāng)請(qǐng)求第二次的時(shí)候就會(huì)出現(xiàn)如下結(jié)果:
?Hello world,Hello user210
user2
intValue
stringValue
當(dāng)?@ModelAttribute?標(biāo)記在處理器方法參數(shù)上的時(shí)候,表示該參數(shù)的值將從模型或者?Session?中取對(duì)應(yīng)名稱的屬性值,該名稱可以通過?@ModelAttribute(“attributeName”)?來指定,若未指定,則使用參數(shù)類型的類名稱(首字母小寫)作為屬性名稱。
5、@PathVariable和@RequestParam的區(qū)別?
請(qǐng)求路徑上有個(gè)id的變量值,可以通過@PathVariable來獲取? @RequestMapping(value = "/page/{id}", method = RequestMethod.GET)??
@RequestParam用來獲得靜態(tài)的URL請(qǐng)求入?yún)???? spring注解時(shí)action里用到。
簡(jiǎn)介:
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ù)上。
示例代碼:
@Controller @RequestMapping("/owners/{ownerId}") public class RelativePathUriTemplateController { @RequestMapping("/pets/{petId}") public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { // implementation omitted } }上面代碼把URI template 中變量 ownerId的值和petId的值,綁定到方法的參數(shù)上。若方法參數(shù)名稱和需要綁定的uri template中變量名稱不一致,需要在@PathVariable("name")指定uri template中的名稱。
(2)、 @RequestHeader、@CookieValue
@RequestHeader 注解,可以把Request請(qǐng)求header部分的值綁定到方法的參數(shù)上。
示例代碼:
這是一個(gè)Request 的header部分:
上面的代碼,把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) 常用來處理簡(jiǎn)單類型的綁定,通過Request.getParameter() 獲取的String可直接轉(zhuǎn)換為簡(jiǎn)單類型的情況( String--> 簡(jiǎn)單類型的轉(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ù)是否必須綁定;
示例代碼:
@Controller @RequestMapping("/pets") @SessionAttributes("pet") public class EditPetForm { @RequestMapping(method = RequestMethod.GET) public String setupForm(@RequestParam("petId") int petId, ModelMap model) { Pet pet = this.clinic.loadPet(petId); model.addAttribute("pet", pet); return "petForm"; }}
@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<String, String>里,這種情況在某些特殊需求下使用,詳情查看FormHttpMessageConverter api;
示例代碼:
@RequestMapping(value = "/something", method = RequestMethod.PUT) public void handle(@RequestBody String body, Writer writer) throws IOException { writer.write(body); }(4)、@SessionAttributes, @ModelAttribute
@SessionAttributes:
該注解用來綁定HttpSession中的attribute對(duì)象的值,便于在方法中的參數(shù)里使用。
該注解有value、types兩個(gè)屬性,可以通過名字和類型指定要使用的attribute 對(duì)象;
示例代碼:
@Controller @RequestMapping("/editPet.do") @SessionAttributes("pet") public class EditPetForm { // ... }@ModelAttribute
該注解有兩個(gè)用法,一個(gè)是用于方法上,一個(gè)是用于參數(shù)上;
用于方法上時(shí):? 通常用來在處理@RequestMapping之前,為請(qǐng)求綁定需要從后臺(tái)查詢的model;
用于參數(shù)上時(shí): 用來通過名稱對(duì)應(yīng),把相應(yīng)名稱的值綁定到注解的參數(shù)bean上;要綁定的值來源于:
A) @SessionAttributes 啟用的attribute 對(duì)象上;
B) @ModelAttribute 用于方法上時(shí)指定的model對(duì)象;
C) 上述兩種情況都沒有時(shí),new一個(gè)需要綁定的bean對(duì)象,然后把request中按名稱對(duì)應(yīng)的方式把值綁定到bean中。
?
用到方法上@ModelAttribute的示例代碼:
@ModelAttribute public Account addAccount(@RequestParam String number) { return accountManager.findAccount(number); }這種方式實(shí)際的效果就是在調(diào)用@RequestMapping的方法之前,為request對(duì)象的model里put(“account”, Account)。
用在參數(shù)上的@ModelAttribute示例代碼:
@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST) public String processSubmit(@ModelAttribute Pet pet) { }首先查詢 @SessionAttributes有無綁定的Pet對(duì)象,若沒有則查詢@ModelAttribute方法層面上是否綁定了Pet對(duì)象,若沒有則將URI template中的值按對(duì)應(yīng)的名稱綁定到Pet對(duì)象的各屬性上。
?
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> //排除掃描的路徑
<context:component-scan>有一個(gè)use-default-filters屬性,屬性默認(rèn)為true,表示會(huì)掃描指定包下的全部的標(biāo)有@Component的類,并注冊(cè)成bean.也就是@Component的子注解@Service,@Reposity等。
這種掃描的粒度有點(diǎn)太大,如果你只想掃描指定包下面的Controller或其他內(nèi)容則設(shè)置use-default-filters屬性為false,表示不再按照scan指定的包掃描,而是按照<context:include-filter>指定的包掃描,示例:
<context:component-scan base-package="com.tan" use-default-filters="false"><context:include-filter type="regex" expression="com.tan.*"/>//注意后面要寫.* </context:component-scan> 當(dāng)沒有設(shè)置use-default-filters屬性或者屬性為true時(shí),表示基于base-packge包下指定掃描的具體路徑 <context:component-scan base-package="com.tan" ><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.tan" ><context:exclude-filter type="regex" expression=".model.*"/> </context:component-scan>?
注意:本人嘗試時(shí)無論哪種情況<context:include-filter>和<context:exclude-filter>都不能同時(shí)存在轉(zhuǎn)載于:https://www.cnblogs.com/lhuser/p/8805447.html
總結(jié)
以上是生活随笔為你收集整理的[转]springmvc常用注解标签详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数组的冒泡排序方法
- 下一篇: CodeForces - 540B Sc