国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

基于注解的SpringMVC簡(jiǎn)單介紹

2019-11-14 23:39:52
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
基于注解的SPRingMVC簡(jiǎn)單介紹

SpringMVC是一個(gè)基于DispatcherServlet的MVC框架,每一個(gè)請(qǐng)求最先訪(fǎng)問(wèn)的都是 DispatcherServlet,DispatcherServlet負(fù)責(zé)轉(zhuǎn)發(fā)每一個(gè)Request請(qǐng)求給相應(yīng)的Handler,Handler處理 以后再返回相應(yīng)的視圖(View)和模型(Model),返回的視圖和模型都可以不指定,即可以只返回Model或只返回View或都不返回。在使用注解 的SpringMVC中,處理器Handler是基于@Controller和@RequestMapping這兩個(gè)注解的,@Controller聲明 一個(gè)處理器類(lèi),@RequestMapping聲明對(duì)應(yīng)請(qǐng)求的映射關(guān)系,這樣就可以提供一個(gè)非常靈活的匹配和處理方式。

DispatcherServlet是繼承自HttpServlet的,既然SpringMVC是基于DispatcherServlet的,那么 我們先來(lái)配置一下DispatcherServlet,好讓它能夠管理我們希望它管理的內(nèi)容。HttpServlet是在web.xml文件中聲明的。

Xml代碼 收藏代碼
  1. <servlet>
  2. <servlet-name>blog</servlet-name>
  3. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  4. <load-on-startup>1</load-on-startup>
  5. </servlet>
  6. <servlet-mapping>
  7. <servlet-name>blog</servlet-name>
  8. <url-pattern>*.do</url-pattern>
  9. </servlet-mapping>

上面聲明了一個(gè)名為blog的DispatcherServlet,該Servlet將處理所有以“.do”結(jié)尾的請(qǐng)求。在初始化 DispatcherServlet的時(shí)候,SpringMVC默認(rèn)會(huì)到/WEB-INF目錄下尋找一個(gè)叫[servlet-name]- servlet.xml的配置文件,來(lái)初始化里面的bean對(duì)象,該文件中對(duì)應(yīng)的bean對(duì)象會(huì)覆蓋spring配置文件中聲明的同名的bean對(duì)象。如 上面的就會(huì)在/WEB-INF目錄下尋找一個(gè)叫blog-servlet.xml的文件;當(dāng)然也可以在Servlet中聲明配置文件的位置,那就是通過(guò) Servlet的初始化參數(shù)來(lái)設(shè)置contextConfigLocation參數(shù)的值。

Xml代碼 收藏代碼
  1. <servlet>
  2. <servlet-name>blog</servlet-name>
  3. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  4. <init-param>
  5. <param-name>contextConfigLocation</param-name>
  6. <param-value>/WEB-INF/blog-servlet.xml</param-value>
  7. </init-param>
  8. <load-on-startup>1</load-on-startup>
  9. </servlet>
  10. <servlet-mapping>
  11. <servlet-name>blog</servlet-name>
  12. <url-pattern>*.do</url-pattern>
  13. </servlet-mapping>

DispatcherServlet會(huì)利用一些特殊的bean來(lái)處理Request請(qǐng)求和生成相應(yīng)的視圖返回。

關(guān)于視圖的返回,Controller只負(fù)責(zé)傳回來(lái)一個(gè)值,然后到底返回的是什么視圖,是由視圖解析器控制的,在jsp中常用的視圖解析器是InternalResourceViewResovler,它會(huì)要求一個(gè)前綴和一個(gè)后綴

Xml代碼 收藏代碼
  1. <bean
  2. class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  3. <propertyname="prefix"value="/WEB-INF/"/>
  4. <propertyname="suffix"value=".jsp"/>
  5. </bean>

在上述視圖解析器中,如果Controller返回的是blog/index,那么通過(guò)視圖解析器解析之后的視圖就是/WEB-INF/blog/index.jsp。

要使用注解的SpringMVC需要在SpringMVC的配置文件中進(jìn)行聲明,具體方式為先引入mvc命名空間,然后利用<mvc:annotation-driven />進(jìn)行聲明。

Xml代碼 收藏代碼
  1. <beansxmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"
  3. <spanstyle="background-color:#00ff00;"><spanstyle="color:#ff0000;">xmlns:mvc="http://www.springframework.org/schema/mvc"</span>
  4. </span>
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  9. <spanstyle="background-color:#00ff00;color:#ff0000;">http://www.springframework.org/schema/mvc
  10. http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"</span>
  11. >
  12. <mvc:annotation-driven/>
  13. </beans>

主要是說(shuō)說(shuō)Controller.

在SpringMVC中Controller不需要繼承什么類(lèi),也不需要實(shí)現(xiàn)什么接口,一切使用了@Controller進(jìn)行標(biāo)記的類(lèi)都是Controller

java代碼 收藏代碼
  1. @Controller
  2. publicclassBlogController{
  3. }

有了Controller之后,那么到底是怎樣請(qǐng)求一個(gè)Controller具體的方法的呢,那是通過(guò)@RequestMapping來(lái)標(biāo)記 的,@RequestMapping可以標(biāo)記在類(lèi)上面,也可以標(biāo)記在方法上,當(dāng)方法上和類(lèi)上都標(biāo)記了@RequestMapping的時(shí)候,那么對(duì)應(yīng)的方 法對(duì)應(yīng)的Url就是類(lèi)上的加方法上的,如下面的index方法,其對(duì)應(yīng)的URL應(yīng)為類(lèi)上的/blog加上index方法上的/index,所以應(yīng)為 /blog/index,所以當(dāng)請(qǐng)求/blog/index.do的時(shí)候就會(huì)訪(fǎng)問(wèn)BlogController的index方法。加在類(lèi)上的 @RequestMapping不是必須的,當(dāng)Controller類(lèi)上加上了@RequestMapping的時(shí)候,那么Controller方法上的 @RequestMapping就是相對(duì)于類(lèi)上的@RequestMapping而言的,也就是前面說(shuō)的請(qǐng)求映射的時(shí)候是類(lèi)上的地址加方法上的地址,而當(dāng) Controller類(lèi)上沒(méi)有加@RequestMapping的時(shí)候,方法上的@RequestMapping就是絕對(duì)路徑了。

Java代碼 收藏代碼
  1. @Controller
  2. @RequestMapping("/blog")
  3. publicclassBlogController{
  4. @RequestMapping("/index")
  5. publicStringindex(Map<String,Object>map){
  6. return"blog/index";
  7. }
  8. }

在上面的代碼中,如果index方法上沒(méi)有RequestMapping注解,而只有BlogController類(lèi)上有,且該類(lèi)只有一個(gè)方法的時(shí)候,直接請(qǐng)求類(lèi)上的URL就會(huì)調(diào)用里面的方法,即直接請(qǐng)求/blog.do的時(shí)候就會(huì)調(diào)用index方法。

在RequestMapping中還可以指定一個(gè)屬性method,其主要對(duì)應(yīng)的值有RequestMethod.GET和 RequestMethod.POST,利用該屬性可以嚴(yán)格的控制某一方法只能被標(biāo)記的請(qǐng)求路徑對(duì)應(yīng)的請(qǐng)求方法才能訪(fǎng)問(wèn),如指定method的值為 GET,則表示只有通過(guò)GET方式才能訪(fǎng)問(wèn)該方法,默認(rèn)是都可以訪(fǎng)問(wèn)。RequestMapping中的URL映射還支持通配符*,如:

Java代碼 收藏代碼
  1. @Controller
  2. @RequestMapping("/blog")
  3. publicclassBlogController{
  4. @RequestMapping("/*/index")
  5. publicStringindex(Map<String,Object>map){
  6. return"blog/index";
  7. }
  8. }

在@RequestMapping中還有一個(gè)屬性params,可以通過(guò)該屬性指定請(qǐng)求參數(shù)中必須包含某一參數(shù),或必須不包含某一參數(shù),或某參數(shù)的值必須是什么,以此來(lái)縮小指定的映射范圍。

Java代碼 收藏代碼
  1. @Controller
  2. @RequestMapping("/blog")
  3. publicclassBlogController{
  4. @RequestMapping(value="/index",params="param1=value1")
  5. publicStringindex(Map<String,Object>map){
  6. return"blog/index";
  7. }
  8. }

在上面示例中,只有當(dāng)請(qǐng)求/blog/index.do并且請(qǐng)求參數(shù)param1的值為value1的時(shí)候才能訪(fǎng)問(wèn)到對(duì)應(yīng)的index方法。如果 params的值為"param1",則表示請(qǐng)求參數(shù)只要包含param1就可以了,至于它的值是什么無(wú)所謂;如果params的值 為"!param1",則表示請(qǐng)求參數(shù)必須不包含param1才可以。@RequestMapping中還可以使用header來(lái)縮小映射范圍,如:

Java代碼 收藏代碼
  1. @Controller
  2. @RequestMapping("/blog")
  3. publicclassBlogController{
  4. @RequestMapping(value="/index",headers="content-type=text/html")
  5. publicStringindex(Map<String,Object>map){
  6. return"blog/index";
  7. }
  8. }

在SpringMVC中常用的注解還有@PathVariable,@RequestParam,@PathVariable標(biāo)記在方法的參數(shù)上,利用它標(biāo)記的參數(shù)可以利用請(qǐng)求路徑傳值,看下面一個(gè)例子

Java代碼 收藏代碼
  1. @RequestMapping(value="/comment/{blogId}",method=RequestMethod.POST)
  2. publicvoidcomment(Commentcomment,@PathVariableintblogId,Httpsessionsession,HttpServletResponseresponse)throwsIOException{
  3. }

在該例子中,blogId是被@PathVariable標(biāo)記為請(qǐng)求路徑變量的,如果請(qǐng)求的是/blog/comment/1.do的時(shí)候就表示 blogId的值為1,@PathVariable在進(jìn)行賦值的時(shí)候如果像上面那樣沒(méi)有指定后面接的變量是對(duì)應(yīng)URL中的哪個(gè)變量時(shí)默認(rèn)是從URL中取跟 后面接的變量名相同的變量,如上面示例中的@PathVariable int blogId,沒(méi)有指明要獲取URL中的哪個(gè)變量,這個(gè)時(shí)候就默認(rèn)取URL中的blogId變量對(duì)應(yīng)的值賦給方法參數(shù)中的blogId,那如果方法參數(shù)的 名稱(chēng)跟RequestMapping中定義的訪(fǎng)問(wèn)路徑中的變量名不一樣,或者我要利用PathVariable明確指定后面接的方法參數(shù)是對(duì)應(yīng)于URL中 的哪個(gè)變量時(shí),可以像下面這樣做,在PathVariable中給定一個(gè)value="blogId"(只有一個(gè)參數(shù)的時(shí)候value是可以省略的)值明 確指定方法參數(shù)中的id變量是對(duì)應(yīng)請(qǐng)求路徑定義中的blogId變量的。

Java代碼 收藏代碼
  1. @RequestMapping(value="/comment/{blogId}",method=RequestMethod.POST)
  2. publicvoidcomment(Commentcomment,@PathVariable("blogId")intid,HttpSessionsession,HttpServletResponseresponse)throwsIOException{
  3. }

同樣@RequestParam也是用來(lái)給參數(shù)傳值的,但是它是從頭request的參數(shù)里面取值,相當(dāng)于 request.getParameter("參數(shù)名")方法。它的取值規(guī)則跟@PathVariable是一樣的,當(dāng)沒(méi)有指定的時(shí)候,默認(rèn)是從 request中取名稱(chēng)跟后面接的變量名同名的參數(shù)值,當(dāng)要明確從request中取一個(gè)參數(shù)的時(shí)候使用@RequestParam("參數(shù)名"),如下 所示:

Java代碼 收藏代碼
  1. @RequestMapping("/show")
  2. publicvoidshowParam(@RequestParamintid,@RequestParam("name")Stringusername){
  3. //這樣做進(jìn)行URL請(qǐng)求訪(fǎng)問(wèn)這個(gè)方法的時(shí)候,就會(huì)先從request中獲取參數(shù)id的值賦給參數(shù)變量id,從request中獲取參數(shù)name的值賦給參數(shù)變量username
  4. }

在Controller的方法中,如果需要WEB元素HttpServletRequest,HttpServletResponse和 HttpSession,只需要在給方法一個(gè)對(duì)應(yīng)的參數(shù),那么在訪(fǎng)問(wèn)的時(shí)候SpringMVC就會(huì)自動(dòng)給其傳值,但是需要注意的是在傳入Session的 時(shí)候如果是第一次訪(fǎng)問(wèn)系統(tǒng)的時(shí)候就調(diào)用session會(huì)報(bào)錯(cuò),因?yàn)檫@個(gè)時(shí)候session還沒(méi)有生成。

接下來(lái)討論一下方法的返回值,主要有以下情況:

  • 返回一個(gè)ModelAndView,其中Model是一個(gè)Map,里面存放的是一對(duì)對(duì)的鍵值對(duì),其可以直接在頁(yè)面上使用,View是一個(gè)字符串,表示的是某一個(gè)View的名稱(chēng)
  • 返回一個(gè)字符串,這個(gè)時(shí)候如果需要給頁(yè)面?zhèn)髦担梢越o方法一個(gè)Map參數(shù),該Map就相當(dāng)于一個(gè)Model,往該Model里面存入鍵值對(duì)就可以在頁(yè)面上進(jìn)行訪(fǎng)問(wèn)了
  • 返回一個(gè)View對(duì)象
  • 返回一個(gè)Model也就是一個(gè)Map,這個(gè)時(shí)候?qū)⒔馕瞿J(rèn)生成的view name,默認(rèn)情況view name就是方法名, 這里之前搞錯(cuò)了,感謝網(wǎng)友的指正。默認(rèn)的View Name是由RequestToViewNameTranslator來(lái)解析的,顧名思義就是把request翻譯成viewName,在沒(méi)有指定 RequestToViewNameTranslator時(shí),Spring將使用其自身的默認(rèn)實(shí)現(xiàn) DefaultRequestToViewNameTranslator的默認(rèn)配置,即取到當(dāng)前請(qǐng)求的URI,去掉最前和最后的斜杠“/”,以及對(duì)應(yīng)的后 綴。所以當(dāng)你請(qǐng)求“http://localhost/app/abc”的時(shí)候,對(duì)應(yīng)的默認(rèn)viewName就是請(qǐng)求URI——“/abc”去掉最前最后 的斜杠和后綴之后的結(jié)果,即“abc”,請(qǐng)求“http://localhost/app/abc/efg”時(shí)對(duì)應(yīng)的默認(rèn)視圖名稱(chēng)是“abc /efg”,“http://localhost/app/abc/efg/hi.html”——>“abc/efg/hi”。如果需要改變默認(rèn)的 視圖名稱(chēng)的解析方式,可以在SpringMVC的配置文件中配置一個(gè)名稱(chēng)為viewNameTranslator,類(lèi)型為 RequestToViewNameTranslator的bean。如果該bean是 DefaultRequestToViewNameTranslator,那么你可以通過(guò)prefix屬性指定視圖名稱(chēng)的前綴,通過(guò)suffix指定后 綴,通過(guò)stripLeadingSlash指定是否需要去掉最前面的斜杠,更多可指定的屬性請(qǐng)參考 DefaultRequestToViewNameTranslator的實(shí)現(xiàn)。當(dāng)然你也可以定義自己的 RequestToViewNameTranslator實(shí)現(xiàn)類(lèi),實(shí)現(xiàn)RequestToViewNameTranslator接口的 getViewName(HttpServletRequest request)方法,實(shí)現(xiàn)自己的獲取默認(rèn)視圖名稱(chēng)的邏輯。
  • 什么也不返回,這個(gè)時(shí)候可以在方法體中直接往HttpServletResponse寫(xiě)入返回內(nèi)容,否則將會(huì)由RequestToViewNameTranslator來(lái)決定
  • 任何其他類(lèi)型的對(duì)象。這個(gè)時(shí)候就會(huì)把該方法返回類(lèi)型對(duì)象當(dāng)做返回Model模型的一個(gè)屬性返回給視圖使用,這個(gè)屬性名稱(chēng)可以通過(guò)在方法上給定@ModelAttribute注解來(lái)指定,否則將默認(rèn)使用該返回類(lèi)名稱(chēng)作為屬性名稱(chēng)。
下面是一個(gè)簡(jiǎn)單的實(shí)例Java代碼 收藏代碼
  1. @RequestMapping("/{owner}/index")
  2. publicStringuserIndex(Map<String,Object>map,@PathVariableStringowner,HttpServletRequestrequest)throwsParserException{
  3. List<DefCategory>categories=categoryService.find(owner);
  4. intoffset=Util.getOffset(request);
  5. Pager<Blog>pager=blogService.find(owner,0,offset,maxResults);
  6. inttotalRecords=pager.getTotalRecords();
  7. List<Blog>blogs=pager.getData();
  8. Util.shortBlog(blogs);
  9. List<Message>messages=messageService.find(owner,0,5).getData();
  10. Util.shortMessage(messages,20);
  11. map.put("messages",messages);
  12. map.put("totalRecords",totalRecords);
  13. List<BlogStore>stores=storeService.find(owner,0,5).getData();
  14. map.put("maxResults",maxResults);
  15. map.put("blogs",blogs);
  16. map.put("totalRecords",totalRecords);
  17. map.put("owner",userService.find(owner));
  18. map.put("defCategories",categories);
  19. map.put("stores",stores);
  20. return"blog/userIndex";
  21. }
給頁(yè)面?zhèn)髦?p> 在Controller中把請(qǐng)求轉(zhuǎn)發(fā)給業(yè)務(wù)邏輯層進(jìn)行處理之后需要把業(yè)務(wù)邏輯層的處理結(jié)果進(jìn)行展現(xiàn),在展現(xiàn)的過(guò)程中就需要我們把處理結(jié)果傳給展示層進(jìn)行展 示。那么處理結(jié)果是怎么進(jìn)行傳遞的呢?前面已經(jīng)說(shuō)了Controller的返回結(jié)果可以是一個(gè)包含模型和視圖的ModelAndView,也可以?xún)H僅是一 個(gè)視圖View,當(dāng)然也可以什么都不返回,還可以是僅僅返回一個(gè)Model。我們知道模型Model是用來(lái)封裝數(shù)據(jù)給視圖View進(jìn)行展示的,那么,在 SpringMVC中,如果要把我們后臺(tái)的信息傳遞給前臺(tái)進(jìn)行展示的話(huà)應(yīng)該怎么做呢?這主要有兩種方式: 1.返回包含模型Model的ModelAndView,或者是直接返回一個(gè)Model(這個(gè)時(shí)候就需要考慮默認(rèn)的視圖),這種類(lèi)型的返回結(jié)果是包含Model的,這個(gè)Model對(duì)象里面的對(duì)應(yīng)屬性列都可以直接在視圖里面使用。 2.如果是直接返回一個(gè)視圖View,這個(gè)時(shí)候SpringMVC提供了一種類(lèi)似于在Controller方法中獲取HttpRequest對(duì)象的機(jī)制,這個(gè)時(shí)候我們只需要給定Controller方法一個(gè)Map參數(shù),然后在方法體里面給這個(gè)Map加上需要傳遞到視圖的鍵值對(duì),這樣在視圖中就可以直接訪(fǎng)問(wèn)對(duì)應(yīng)的鍵值對(duì)。

文章出自:http://haohaoxuexi.VEvb.com/blog/1343761


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 普安县| 当阳市| 芜湖县| 乳源| 印江| 剑川县| 无极县| 嘉荫县| 台江县| 光山县| 金华市| 绿春县| 土默特左旗| 维西| 徐汇区| 昌都县| 开平市| 西充县| 罗江县| 阳西县| 桂平市| 济南市| 怀远县| 东乌珠穆沁旗| 桑植县| 柳河县| 宜兰市| 祥云县| 九台市| 锦屏县| 南安市| 绥德县| 巍山| 阿尔山市| 龙州县| 永丰县| 唐河县| 山丹县| 宜城市| 定兴县| 永兴县|