1.1 @Controller是什么
首先看個例子:
@Controller
@RequestMapping("/blog")
public class BlogController {
@RequestMapping("/index")
public ModelAndView index(HttpServletRequest request){
ModelAndView mav = new ModelAndView("/index");
String ctx = request.getContextPath();
System.out.println(ctx);
mav.addObject("ctx", ctx);
return mav;
}
}
@Controller表示在tomcat啟動的時候,把這個類作為一個控制器加載到Spring的Bean工廠,如果不加,就是一個普通的類,和Spring沒有半毛錢關系。
以下是兩個常見的配置:
<!-- 開啟注解模式驅動 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 掃包 -->
<context:component-scan base-package=*"com.blogMgr.*"*></context:component-scan>
其中,base-package表示會掃描com.blogMgr目錄下所有的包,一旦發現有個類上面加了類似於@Controller的注解,在容器啟動的時候系統就會把它加載到Spring的Bean工廠,並且對其實例化。
這也是為什么,我們只是寫了Controller,但是從來沒有在一個地方new這個Controller的原因,因為在Web容器啟動的時候,這個Controller已經被Spring加載到自己的Bean工廠里面去了。
這也就是所謂的Spring掃包機制。@Controller就是一個注解,當tomcat啟動,我們會看到一些JAVA類揮舞着印有@Controller的旗子大喊:" Hey,SpringMVC,I'm here,please take me to your bean factory!"
1.2 @RequestMapping是什么
在Controller中,總是會看到RequestMapping這個注解,看起來像是路徑的跳轉,以下列舉了一個方便我們記憶的比喻。
比如,有一天,我發現一部電影挺好看的,就在D盤建了一個文件夾,叫“電影”。里面放了兩部電影,各自用一個文件夾來存放。
在上圖中,我們可以看它的路徑是“D:\電影”,該路徑下又有一個文件夾【瘋狂動物城 2016】,里面是這樣的
那么,該文件的具體路徑就是“D:\電影\瘋狂動物城 2016”,現在我要訪問這個資源,除了雙擊之外,是不是只需要在地址欄里面輸入:“D:\電影\瘋狂動物城 2016\瘋狂動物城 2016.mp4”也可以呢?
是的,當然可以。
成功了,我們通過url的方式得到了我們想要的資源文件!
現在我們把這個文件復制一份,拷貝到相同路徑下
如果我嘗試將第一個MP4文件的名字也改為“瘋狂動物城 2016.mp4”,則會彈出提示如下
可見,在同一個路徑下,不能有兩個重名的文件。
同理,如果我在同一個Controller里面設置兩個相同的RequestMapping
編譯是可以通過的,但是當我啟動tomcat后,
我通過url “http://localhost:8088/BlogMgr/blog/index”來訪問,就會報錯:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'blogController' bean method
Ambiguous mapping found表示有一個路徑模棱兩可,也就是路徑重名了,系統無法進行映射,所以報錯了。這個和無法在同一個文件夾下面創建兩個同名文件,是一個道理。
那么,如果我一定要再創建一個“瘋狂動物城 2016.mp4”的文件該怎么辦呢
然后,我把這個文件放在另一個文件夾里面就可以了。
同理,我也可以另外建一個Controller,Controller類上面的RequestMapping叫“/blog2”,再在里面寫一個一模一樣的RequestMapping就肯定沒有問題了。
小結
一個web項目本身就是一個系統,和操作系統一樣,可以把項目當做一個系統,一個應用程序。人為什么要使用電腦,因為電腦可以
1.給我們想要的資源(比如.avi)
2.幫我們做事。
在一個系統中,如果沒有圖形界面,我們要訪問一個資源,必然是通過一個黑窗口來訪問的,就是通過路徑來訪問的。一個B/S架構的web項目,就是一個類似於命令行一樣的應用程序,我們唯有通過url,也就是路徑去獲得我們想要的資源和服務。
再來看RequestMapping,最終對應的必然是一個方法,方法的功能無非就是進行一些業務的操作,或者返回一個什么東西。
比如
我們就是通過這個方法獲得了想要的jsp頁面,RequestMapping的作用就是提供了一個句柄,讓我們可以訪問到對應的方法,最終獲得我們想要的東西。綜上所述,RequestMapping就是一個映射路徑。
1.3 @ResponseBody的作用
在Controller里面,我們經常可以看到@ResponseBody這個注解,它的意思很簡單,就是說明這個方法返回的東西會通過IO流的方式寫入到瀏覽器。
比如我們寫一個方法:
@RequestMapping("/testResponseBody")
@ResponseBody
public String testResponseBody(HttpServletRequest request){
return "<h1 style='color:lightGreen'>Hello Web!</h1>";
}
最終在瀏覽器獲得的效果是這樣的: