SpringMVC 第二篇【基於註冊的框架解析】

本文簡介

       在前一篇文章中給大家講述了SpringMVC基本開發框架的搭建,相信看過的朋友已經可以搭建出SpringMVC開發環境了。在本篇文章中,本人將使用Web應用中最常見的註冊功能作爲引子給大家講述一下SpringMVC框架的原理。讓大家知道SpringMVC框架執行的完整流程。

      SpringMVC框架向大多數MVC框架一樣基於請求驅動,設計圍繞一箇中心Servlet,把請求轉發給控制器,提供其他功能,便於web應用程序的開發。然而,Spring的DispatcherServlet遠遠不止這些。這是完全與Spring IoC容器集成,從而允許你使用Spring擁有的其它功能。

 下圖中所示的Spring Web MVC的DispatcherServlet的請求處理流程。精通設計模式的讀者會認識到,DispatcherServlet的是“前端控制器設計模式”(這是一個模式,SpringMVC與許多其他領先的Web框架的所共有的)。

(此圖源自Spring官方入門指南)   從圖中可以看到,請求經過前端控制器也就是DispatcherServlet把請求委託給後臺控制器(我們自己創建的Controller),控制器再處理請求,返回model到DispatcherServlet ,DispatcherServlet再解析根據對應的配置文件(servlet-context.xml)解析model爲對應的視圖返回給用戶。 具體的詳細流程爲: 1.客戶端發出Http請求,Web應用服務器接收到這個請求,如果匹配在web.xml中配置的DispatcherServlet請求路徑,web容器將請求轉交給DispatcherServlet處理。 2.DispatcherServlet接收到請求以後,根據請求的信息(包括URL、HTTP方法、請求頭、請求參數、Cookie等)以及HandlerMapping的配置找到處理請求的Handler(我們定義的Controller,SpringMVC沒有規定Controller需要繼承或者實現相應的接口,這也爲我們提供了很大的方便,任何Object都可以成爲Controller). 3.DispatcherServlet根據HandlerMapping得到相應請求的Handler後,通過HandlerAdapter進行封裝,再以統一的適配器接口調用Handler(HandlerAdapter.handle()  代碼可以參見:DispatcherServlet.doDispatch()方法)。 4.HandlerAdapter.handle()方法返回的是ModelAndView,ModelAndView包含了視圖邏輯名稱以及模型數據信息。 5.DispatcherServlet根據ModelAndView裏面的邏輯視圖名稱使用ViewResolver完成邏輯視圖名稱到真實視圖對象的解析工作。 6.得到真實的視圖對象View後,DispatcherServlet就使用後整個View對象對ModelAndView中的模型數據進行視圖渲染。 7.最終用戶得到的響應消息,可能是普通的HTML頁面,也可能是XML或者JSON字符串,甚至是一張圖片或者一個PDF文檔。 流程講完了,我們做一個登錄功能給大家演示一下這個流程。 首先回顧一下SpringMVC應用開發的基本步驟: 1.配置web.xml 指定業務層對應的Spring配置文件,定義DispatcherServlet. 2.編寫視圖對象 3.編寫請求的控制器 4.配置SpringMVC的配置文件,使控制器視圖解析器生效。 在HelloWorld中1、4 我們已經做過了,這裏繼續使用上次的架子進行開發。           編寫視圖對象在webapp/WEB-INF/views/user/下面創建register.jsp頁面  代碼清單如下:  

  1. <%@ page language="java" contentType="text/html; charset=GBK"
  2. pageEncoding="GBK"%>
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=GBK">
  8. <title>SpringMVC 註冊頁面</title>
  9. </head>
  10. <body>
  11. <form action="user/register">
  12. <table>
  13. <c:if test="${!empty errorMsg}">
  14. <tr>
  15. <td colspan="2">
  16. <font color="red">${errorMsg}</font>
  17. </td>
  18. </tr>
  19. </c:if>
  20. <tr>
  21. <td>用戶名:</td>
  22. <td><input type="text" name="username"/></td>
  23. </tr>
  24. <tr>
  25. <td>密碼:</td>
  26. <td><input type="password" name="password"/></td>
  27. </tr>
  28. <tr>
  29. <td><input type="submit" value="註冊"/></td>
  30. <td><input type="reset" value="重置"/></td>
  31. </tr>
  32. </table>
  33. </form>
  34. </body>
  35. </html>

在webapp/WEB-INF/views/user/下面創建register_ok.jsp頁面  代碼清單如下:

 

  1. <%@ page language="java" contentType="text/html; GBK"
  2. pageEncoding="GBK"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; GBK">
  7. <title>SpringMVC 註冊成功</title>
  8. </head>
  9. <body>
  10. <h2>恭喜您,註冊成功!用戶名:${username}</h2><br>
  11. <a href="../">返回首頁</a>
  12. </body>
  13. </html>

在上一節home.jsp頁面上加上 <a href="user/toRegister">註冊新用戶</a>   用於跳轉

 

    編寫控制器

創建com.yubai.springmvc.web.UserController控制器 用於處理所有與用戶有關的操作,代碼如下:

  1. package com.yubai.springmvc.web;
  2.  
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.util.StringUtils;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.servlet.ModelAndView;
  9.  
  10. import com.yubai.springmvc.entity.User;
  11.  
  12. //此註解表明當前類爲控制器
  13. @Controller
  14. // 此註解表明 此控制器負責處理來自/user的請求
  15. @RequestMapping("/user")
  16. public class UserController {
  17. private final static Logger logger = LoggerFactory
  18. .getLogger(UserController.class);
  19.  
  20. /**
  21. * 跳轉到註冊頁面
  22. *
  23. * @return
  24. */
  25. // 此註解表示處理/user/toRegister 請求
  26. @RequestMapping("/toRegister")
  27. public String toRegister() {
  28. // 視圖解析器會在/user目錄下 找到register.jsp頁面返回
  29. logger.debug("跳轉到註冊頁面");
  30. return "/user/register";
  31. }
  32.  
  33. /**
  34. * 註冊
  35. *
  36. * @param user
  37. * @return
  38. */
  39. // 此註解表示處理/user/register 請求
  40. @RequestMapping("/register")
  41. public ModelAndView register(User user) {
  1. //User對象SpringMVC自動注入進來的
  2. logger.debug("註冊……");
  3. ModelAndView mv = new ModelAndView();
  4. if (StringUtils.isEmpty(user.getUsername())
  5. || StringUtils.isEmpty(user.getPassword())) {
  6. logger.warn("用戶名或者密碼爲空,註冊失敗");
  7. mv.setViewName("/user/register");
  8. mv.addObject("errorMsg", "用戶名或密碼不能爲空");
  9. } else {
  10.  
  11. mv.setViewName("/user/register_ok");
  12. mv.addObject("username", user.getUsername());
  13. logger.debug("註冊成功");
  14. }
  15. return mv;
  16. }
  17. }

 運行註冊模塊

  

流程解析

對於註冊這一過程,再簡單的解析一下。   

1.DispatcherServlet接收到客戶端的user/toRegister請求 ,使用DefaultAnnotationHadnlerMapping查詢負責處理請求的處理器爲user/toRegister。

2.DispatcherServlet將請求分發給名稱user/toRegister的UserController處理器。

3.處理器處理完後返回ModelAndView 其中視圖名稱爲/user/register,DispatcherServlet調用InternalResourceViewResolver組件對ModelAndView中的邏輯視圖名稱進行解析,得到真是的/WEB-INF/view/user/register.jsp頁面。

4.返回響應頁面給客戶端。

5. ......同上面

知識點解析

 @Controller:在POJO類定義處標註此註解,再通過<context:component-scan/>掃描響應的類包,即可使POJO成爲一個能處理HTTP請求的控制器。 你可以創建很多個控制器,每個控制器用來處理不同的業務方法。如何將請求對應到控制器的任務由@RequestMapping註解承擔。  @RequestMapping:在控制器的定義處以及方法的定義出都可以標註@RequestMapping註解。類的定義處標註此註解提供請求的初步映射信息,方法提供進一步的詳細映射信息(也可以不在類定義出定義,在那定義的好處是省略了後面重複的定義路徑同時也限制死了 當前控制器只能處理當前請求路徑下的請求。) 下面一節將詳細講述強大的SpringMVC請求映射規則。 注意:此節我們使用了JSTL標籤所以需要增加兩個jar包 jstl-api-1.2.jar  jstl-1.2.jar  我已經將jar包放在項目lib路徑下了。其它jar包已經在第一篇文章中提供,不予以重複上傳。使用MAVEN的同學可以無需理會,MAVEN配置文件中已經增加着兩個jar包的依賴。

結束語

      在本節大家已經大致瞭解了SpringMVC的內部運作機制,其內部實現代碼暫不作剖析。註冊功能還很不完善,如AJAX請求校驗,SpringMVC自帶的校驗處理 本節均爲涉及。後面章節會專門作出講解。

      下一講我們將學習Spring的映射規則已經參數的綁定,URL映射、請求參數映射、請求方法映射、請求頭映射等。通過下節大家可以看到Spring強大而又靈活的映射方法爲我們的開發帶來了很多好處。

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