Spring MVC 入門筆記

主要名詞解釋

DispatcherServlet 前端控制器  相當於一個轉發器

入口:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception

HandlerMapping 處理器映射器  

核心方法HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

對HandlerExecutionChain稍微解釋下,並不是我一開始理解的由很多個Handler組成的鏈,而是一個Hanler和多個攔截器interceptor

源碼爲證:

public class HandlerExecutionChain {

 

private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);

 

private final Object handler;

 

private HandlerInterceptor[] interceptors;

 

private List<HandlerInterceptor> interceptorList;

 

private int interceptorIndex = -1;

 

 

 

HandlerAdapter 處理器適配器

核心方法:

ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

 

ViewResolver    視圖解析器

核心方法

View resolveViewName(String viewName, Locale locale) throws Exception;

 

 

ModelAndView  模型和視圖的結合體  是一個底層對象

部分源碼方便理解

public class ModelAndView {

 

/** View instance or view name String */

private Object view;

/** Model Map */

private ModelMap model;

 

 

 

View           視圖

核心方法:渲染

void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;

 

Handler處理器也就是Controller

源碼如下:

public interface Controller {

ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

非註解的處理器映射器(多個處理器映射器可共存)

1、BeanNameUrlHandlerMapping

 

Bean的Name作爲URL 的處理器映射器

示範:

<bean name="/queryItems.action" class="com.study.controller.ItemsController" />

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

  1. SimpleUrlHandlerMapping

    

簡單URL處理器映射器

示範:

<bean id="id1" class="com.study.controller.ItemsController1" />

<bean id="id2" class="com.study.controller.ItemsController2" />

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="mapping">

<props>

<!-- 在這裏面進行配置 -->

<prop key="/url1">id1</prop>

<prop key="/url2">id2</prop>

<!-- 一個id可以對應多個key -->

<prop key="/url3">id1</prop>

</props>

</property>

</bean>   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

非註解的處理器適配器

  1. SimpleControllerHandlerAdapter

   簡單Controller處理器適配器

  直接實現Controller接口

<bean

class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

示範創建一個ItemsController處理器:

public class ItemsController implements Controller {

/*

 * 自己的Controller實現Controller接口中handleRequest方法

 */

@Override

public ModelAndView handleRequest(HttpServletRequest request,

HttpServletResponse response) throws Exception {

// 此處採用代碼方式建對象提供測試,實際中通過和MyBatis等框架整合查詢數據庫得到數據並由ORM(對象關係映射)轉換成對象進行操作

// 像商品列表中添加三條數據

List<Item> itemlist = new ArrayList<Item>();

itemlist.add(new Item("蘋果", 5.2));

itemlist.add(new Item("香蕉", 1.5));

itemlist.add(new Item("梨子", 3.4));

// ModelAndView 是模型和視圖的結合體

// model中添加的Object會被添加到request請求域,使用addObject(String,Object)相當於request.setAttribute(String,Object)

ModelAndView mav = new ModelAndView();

// 將商品列表對象放入ModelAndView

mav.addObject("itemlist", itemlist);

// 設置邏輯視圖名

mav.setViewName("ListItems.jsp");

return mav;

}

 

}

 

 

 

 

 

 

 

 

 

 

  1. HttpRequestHandlerAdapter

   實現HttpRequestHandler接口

示範創建一個處理器ItemsController2

使用此方法可以針對於返回JSON數據的情況可以操response

res.setCharacterEncoding("utf-8");

res.setContentType("application/json;charset=utf-8");

res.getWriter().write("你的JSON字符串");

 

public class ItemsController2 implements HttpRequestHandler {

 

/*

 * 自己的Controller實現Controller接口中handleRequest方法

 */

@Override

public void handleRequest(HttpServletRequest req, HttpServletResponse res)

throws ServletException, IOException {

// 此處採用代碼方式建對象提供測試,實際中通過和MyBatis等框架整合查詢數據庫得到數據並由ORM(對象關係映射)轉換成對象進行操作

// 像商品列表中添加三條數據

List<Item> itemlist = new ArrayList<Item>();

itemlist.add(new Item("蘋果", 5.2));

itemlist.add(new Item("香蕉", 1.5));

itemlist.add(new Item("梨子", 3.4));

//Model填充

req.setAttribute("itemlist", itemlist);

//ViewResolver

req.getRequestDispatcher("ListItems.jsp").forward(req, res);

//可以針對只需要返回JSON字符串的情況

// res.setCharacterEncoding("utf-8");

// res.setContentType("application/json;charset=utf-8");

// res.getWriter().write("你的JSON字符串");

}

 

}

 

 

 

 

 

 

 

 

 

 

基於註解的處理器映射器

版本區別

注意點:Spring MVC 3.1版本之前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

3.1版本之後使用

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

 

基於註解的處理器適配器

 

版本區別

注意點:Spring MVC 3.1版本之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

3.1版本之後使用

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

 

<!--

註解方式配置第二種做法 使用mvc:annotation-driven

兩種方式任選其一

區別點在於

mvc:annotation-driven方式默認加載了很多參數綁定方法,比如JSON解析器就默認加載了

實際開發中使用mvc:annotation-driven這種方式

 

 

-->

<!-- <mvc:annotation-driven></mvc:annotation-driven> -->

 

 

註解的處理器映射器需要搭配註解的處理器適配器同時使用

註解方式和非註解方式同時使用並搶佔同一個URL的時候按照xml中配置的先後順序,先配置的處理器映射器被使用

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

註解語法

1、@Controller

使用@Controller註解標誌該類爲一個Controller

2、@RequestMapping(url)

使用@RequestMapping(/myurl.action)註解標誌下面的方法映射到/myurl.action

示範如下

@Controller

public class ItemsController3 {

/*

 * 註解開發Handler

 */

@RequestMapping("/queryItems.action")

public ModelAndView queryItems() throws Exception{

// 此處採用代碼方式建對象提供測試,實際中通過和MyBatis等框架整合查詢數據庫得到數據並由ORM(對象關係映射)轉換成對象進行操作

// 像商品列表中添加三條數據

List<Item> itemlist = new ArrayList<Item>();

itemlist.add(new Item("蘋果", 5.2));

itemlist.add(new Item("香蕉", 1.5));

itemlist.add(new Item("梨子", 3.4));

// ModelAndView 是模型和視圖的結合體

// model中添加的Object會被添加到request請求域,使用addObject(String,Object)相當於request.setAttribute(String,Object)

ModelAndView mav = new ModelAndView();

// 將商品列表對象放入ModelAndView

mav.addObject("itemlist", itemlist);

// 設置邏輯視圖名

mav.setViewName("ListItems.jsp");

return mav;

}

 

}

開發完Handler需要將Handler配置到springmvcconfig.xml

單個配置方式如下

<bean class="com.study.controller.ItemsController3" />

掃描包內組件的方式如下

<context:component-scan base-package="com.study.controller"></context:component-scan>

 

深入源碼分析Spring MVC框架

只複製了關鍵步驟代碼其他代碼省略

  1. 請求到達Spring MVC框架
    入口如下
    類名:DispatcherServlet

方法名:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception

  1. 上述方法中執行
    HandlerExecutionChain mappedHandler = null;
    ...
    mappedHandler = getHandler(processedRequest);
    根據Request拿到HandlerExecutionChain

  2. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    通過HandlerExecutionChain中的getHandler()方法拿到Handler

  3. ModelAndView mv = null;

.....
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

  1. 通過HandlerAdapter中的handle方法執行處理器中的處理並返回ModelAndView

 

 

 

 


  1. processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

調用該方法來執行轉發結果、也就是進行最後一步視圖渲染

processDispatchResult方法中調用render(mv, request, response);方法

在render方法中調用了view.render(mv.getModelInternal(), request, response);
View對象中的render方法並沒有處理,只是個接口

然後AbstractView這個抽象類實現了View接口
如下圖

然後AbstractUrlBasedView 繼承了AbstractView

public abstract class AbstractUrlBasedView extends AbstractView implements InitializingBean {

 

然後內置解析器 InternalResourceView繼承了 AbstractUrlBasedView

public class InternalResourceView extends AbstractUrlBasedView {

我們的JSP頁面最終調用的是InternalResourceView內置的視圖解析器
項目包已壓縮爲ZIP文件,大小8M地址
http://xingxunxinxi.com/source/SpringMVC_Study.zip

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章