1. 非註解方式 1.1 處理器適配器 上一節中使用的處理器適配器是:org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter。即: SimpleControllerHandlerAdapter適配器能執行實現了Contro ...
1. 非註解方式
1.1 處理器適配器
上一節中使用的處理器適配器是:org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter。即:
SimpleControllerHandlerAdapter適配器能執行實現了Controller介面的Handler,所以我們所寫的Handler需要實現Controller介面。
除了這個適配器外,還有另一個適配器,叫org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter。即可以配置:
HttpRequestHandlerAdapter適配器能執行實現了HttpRequestHandler介面的Handler,所以我們所寫的Handler需要實現HttpRequestHandler介面,這跟實現Controller介面稍微有點不同,比如我們寫一個Handler:
public class ItemsController2 implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//實際中是調用service查找資料庫,查詢商品列表,這裡直接使用靜態數據來模擬了
List<Items> itemsList = new ArrayList<Items>();
//向list中填充靜態數據
Items items_1 = new Items();
items_1.setName("聯想筆記本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad T430 聯想筆記本電腦!");
Items items_2 = new Items();
items_2.setName("蘋果手機");
items_2.setPrice(5000f);
items_2.setDetail("iPhone6蘋果手機!");
itemsList.add(items_1);
itemsList.add(items_2);
//設置模型數據
request.setAttribute("itemsList", itemsList);
//設置轉發的視圖
request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response);
//使用此方法可以通過修改response,設置響應的數據格式,比如響應json數據
/*
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");*/
}
}
前面獲取數據都是一模一樣的,後面轉到視圖部分和實現Controller介面是不同的,實現HttpRequestHandler介面的話,最後這裡處理和原來的servlet是一樣的,往request域中存入數據,然後跳轉到新的jsp視圖頁面。不過這種方式還可以修改response,設置響應的數據格式等。
不管是用那個適配器,一個相同點就是:每個Handler中只能有一個方法,因為要繼承Controller或者HttpRequestHandler,就要重寫相對應的那個方法,在那個方法中處理邏輯。也就是說一個Handler中不能有兩個方法或兩個以上的來處理不同的邏輯,這是弊端,但是也有它的好處,限定了程式員的編程,比較規範。
這兩個適配器可以同時使用,我測試了一下,不會衝突,我配了兩個適配器,寫了兩個Handler,分別去實現Controller和HttpRequestHandler介面,都可以被執行。
1.2 處理器映射器
上一節中使用的映射器是:org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping。即:
這個映射器根據名字也可以看得出,是根據bean的name作為url進行查找,所以配置Handler的bean的時候,要配置一下name屬性,設置為要請求的url即可正確映射。
還有一種處理器映射器叫簡單映射器:org.springframework.web.servlet.handler.SimpleUrlHandlerMapping。它的映射方式是直接根據url來的,如下:
這種可以直接配url,然後對應的url指定一個Handler,使用的是該Handler對應bean的id,所以只要在bean中配好id,然後將url和這個id對應上即可。
經測試,這兩個映射器也可以一起使用,互不衝突,匹配到哪個就用哪個。
2. 註解方式
2.1 處理器適配器和映射器
在spring3.1之前使用:
註解映射器:org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
註解適配器:org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
在spring3.1之後使用:
註解映射器:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
註解適配器:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
毫無疑問,現在都已經到了版本4以上了,肯定有後者了,如果使用了註解方式的適配器和映射器,就不需要前面那些非註解的適配器和映射器了,所以只需要兩行代碼即可:
我們可以看到,上面還配了個Handler,那麼url的映射怎麼辦?我怎麼知道對應到哪個Handler呢?不著急,這些全交給註解!下麵來寫這個Handler:
@Controller
public class ItemsController3 {
// 商品查詢列表
// @RequestMapping實現 對queryItems方法和url進行映射,一個方法對應一個url
// 一般建議將url和方法寫成一樣
@RequestMapping("/queryItems")
public ModelAndView queryItems() throws Exception {
// 實際中是調用service查找資料庫,查詢商品列表,這裡直接使用靜態數據來模擬了
List<Items> itemsList = new ArrayList<Items>();
// 向list中填充靜態數據
Items items_1 = new Items();
items_1.setName("聯想筆記本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad T430 聯想筆記本電腦!");
Items items_2 = new Items();
items_2.setName("蘋果手機");
items_2.setPrice(5000f);
items_2.setDetail("iPhone6蘋果手機!");
itemsList.add(items_1);
itemsList.add(items_2);
// 返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
// 相當於request的setAttribute,在jsp頁面中通過itemsList取數據
modelAndView.addObject("itemsList", itemsList);
// 指定視圖
modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
return modelAndView;
}
@RequestMapping("/queryItems2")
public ModelAndView queryItems2() throws Exception {
// 實際中是調用service查找資料庫,查詢商品列表,這裡直接使用靜態數據來模擬了
List<Items> itemsList = new ArrayList<Items>();
// 向list中填充靜態數據
Items items_1 = new Items();
items_1.setName("聯想筆記本2");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad T430 聯想筆記本電腦!");
Items items_2 = new Items();
items_2.setName("蘋果手機2");
items_2.setPrice(5000f);
items_2.setDetail("iPhone6蘋果手機!");
itemsList.add(items_1);
itemsList.add(items_2);
// 返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
// 相當於request的setAttribute,在jsp頁面中通過itemsList取數據
modelAndView.addObject("itemsList", itemsList);
// 指定視圖
modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
return modelAndView;
}
}
從上面的代碼中可以看出,首先,我一個Handler中可以寫多個方法了,現在是兩個,邏輯一模一樣,就是item的名字稍微變了一下好用來測試。在類的上面加上@Controller註解,可以指定bean的名字,也可以不指定,預設為類名首字母小寫。然後url映射交給@RequestMapping類處理,可以指定url,一個url對應一個方法。
這樣就很清晰了,前臺傳了個url進來,映射器根據這個url找到Handler,然後根據Handler選擇一個適配器去執行,這裡全部用的都是註解,這樣就將url和這個Handler連到一起了,也把url和具體的處理方法連到一起了,由此可見,使用註解的開發方式比較方便。開發中常用的是註解的方式。
2.2 繼續優化註解
使用註解要註意一個問題,就是註解適配器和映射器必須配對使用,也就是說,不能一個用註解,一個用非註解。要用一起用,要麼都不用。其實在springmvc中還有更加簡便的註解:
只要這一個註解即可,適配器和映射器就可以省略不配了。另外,如果Controller很多的話,我們還得針對這些Controller配好多個bean,也不方便,所以springmvc中也提供了掃描包的方式來配置,如下:
所以到最後,使用註解的方法,適配器、映射器、Controller等的配置加在一起就兩行代碼!搞定!當然,視圖解析器還是和上一節一樣,自己配一下即可。
到這就基本總結完了springmvc中使用非註解方式和註解方式的適配器和映射器了,很明顯,開發中我們使用最後面的那個註解配置,非常方便。