springMVC

 spring MVC在性能上是要比struts2要好的。struts2的性能低的緣由是由於OGNL和值堆形成的,在springMVC中,若是併發性比較高,能夠用freemaker進行顯示,而不是用OGNL和值棧,這樣性能上會有很大的提升。前端

springMVC運行流程圖(在網上找的)java

這個圖化的很好,比官方文檔的畫的好多了web

這裏須要瞭解一個dispatcherServlet的初始化spring

  1.把初始化的那些init-param讀到Servlet的屬性裏。咱們知道Servlet的init-param是放在ServletConfig裏的,咱們能夠用循環去取這些屬性。可是每次都這麼幹實在太累了,幹嘛不把在Servlet裏增長几個property,再這些init-param直放到Servlet的property裏呢?呵呵,之後那些初始參數均可以直接拿來用啦,真方便。DispatchServlet的一個祖先類叫作HttpServletBean就是專門幹這個的。之後假如咱們要寫本身的Servlet也能夠直接繼承HttpServletBean這個類,這樣讀ServletConfig的操做都省掉了,哈哈!json

  2.從ServletContext裏取出ApplicationContext,並擴展成本身的ApplicationContext.spring-mvc

  在Spring MVC裏,咱們卻能夠有好多個Servlet!它們能夠處理不一樣類型的request,並且更重要的是它們的ApplicationContext不是相同的,它們共享了一個父ApplicationContext,也就是從ServletContext裏取出來的那個,可是它們卻會根據本身的配置做擴展,造成這個Servlet特有的ApplicationContext。這個子的ApplicationContext裏有本身的namespace,也就是將一個叫作(假如servlet名稱叫xiecc) xiecc-servlet.xml的配置文件讀進來,行成一個本身的ServletContext。因此這些過程全是在DispatchSevlet的一個父類FrameworkServlet裏乾的服務器

  3.初始化dispatcherServlet的接口,將applicationcontext定義好的接口注入dispatcherServlet中併發

initMultipartResolver();mvc

initLocaleResolver();app

initThemeResolver();

initHandlerMappings();

initHandlerAdapters();

initHandlerExceptionResolvers();

initViewResolvers();

  dispatcherServlet是不負責具體的操做的,他將具體的操做都委託給相應的接口,這是Template Method的Strategy模式

  1. 用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;

  這裏在web.xml中配置dispatcherServlet,文檔解釋dispatcherServlet    Central dispatcher for HTTP request handlers/controllers,Dispatches to registered handlers for processing a web request, providing convenient mapping and exception handling facilities意思基本是處理request請求並註冊handlers

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/hib-config.xml,/WEB-INF/springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

  2.DispatcherServlet對請求URL進行解析。DispatcherServlet裏面的BeanNameUrlHandlerMapping這個類實現了HandlerMapping這個接口。用來實現映射(The mapping is from URL to bean name)。BeanNameUrlHandlerMapping 的解釋

Implementation of the org.springframework.web.servlet.HandlerMapping interface that map from URLs to beans with names that start with a slash ("/"), similar to how Struts maps URLs to action names.

用的多的仍是handlerMapping的SimpleUrlHandlerMapping,

這是dispatcherServlet中定義的handlerMapping的集合

 

    /** List of HandlerMappings used by this servlet */
    private List<HandlerMapping> handlerMappings;

 

這裏我請求的url

http://oulin:8080/springMVC/user.do?uname=123&method=reg3

requestUrl字符串一截,拿到"/user.do"再去handlerMappings裏去找對應的"/user.do",將對應的controller和一組interceptor組裝成handlerExecutionChain。
<mvc:interceptors>中拿到一組interceptor

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd    
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd    
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

    <!-- 對web包中的全部類進行掃描,以完成Bean建立和自動依賴注入的功能 -->
    <context:component-scan base-package="com.sxt.web" />
    
    <mvc:annotation-driven />  <!-- 支持spring3.0新的mvc註解 -->
    <!-- 啓動Spring MVC的註解功能,完成請求和註解POJO的映射 -->
    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="cacheSeconds" value="0" />
        <property name="messageConverters">
            <list>
                <bean
                    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
            </list>
        </property>
    </bean>
    <mvc:interceptors>
        <bean class="com.sxt.interceptor.MyInterceptor"></bean> <!-- 攔截全部springmvc的url! -->
        <mvc:interceptor>
            <mvc:mapping path="/user.do" />
            <!--<mvc:mapping path="/test/*" />-->
            <bean class="com.sxt.interceptor.MyInterceptor2"></bean>
        </mvc:interceptor>
    </mvc:interceptors>




    <!--對模型視圖名稱的解析,即在模型視圖名稱添加先後綴 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:suffix=".jsp">
        <!-- 若是使用jstl的話,配置下面的屬性 -->
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
    </bean>

    <!-- 處理文件上傳 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="gbk" /> <!-- 默認編碼 (ISO-8859-1) -->
        <property name="maxInMemorySize" value="10240" /> <!-- 最大內存大小 (10240)-->
        <property name="uploadTempDir" value="/upload/" /> <!-- 上傳後的目錄名 (WebUtils#TEMP_DIR_CONTEXT_ATTRIBUTE) -->
        <property name="maxUploadSize" value="-1" /> <!-- 最大文件大小,-1爲無限止(-1) -->
    </bean>


</beans>

userController.java

package com.sxt.action;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.sxt.po.User;
import com.sxt.service.UserService;

@Controller
@RequestMapping("/user.do")
@SessionAttributes({"u","a"})
public class UserController  {
    @Resource
    private UserService userService;
    @RequestMapping(params="method=reg")
    public String reg(String uname){
        System.out.println("UserController.reg()");
        System.out.println(uname);
        userService.add(uname);
        return "index";
    }
    @RequestMapping(params="method=reg2")
    public ModelAndView reg2(User user){
        System.out.println("UserController.reg2()");
        System.out.println(user.getUname());
        ModelAndView mav = new ModelAndView("index");
        return mav;
    }
    @RequestMapping(params="method=reg3")
    public String reg3(@RequestParam("uname") String name,HttpServletRequest req,ModelMap map){
        System.out.println("UserController.reg()");
        System.out.println(name);
        req.getSession().setAttribute("c", "ccc");
        map.put("a", "aaa");
        return "index";
    }
    @RequestMapping(params="method=reg4")
    public String reg4(@ModelAttribute("a") String a,HttpServletRequest req,ModelMap map){
        System.out.println("UserController.reg4()");
        System.out.println(a);
        return "redirect:http://www.baidu.com";
    }
    @RequestMapping(params="method=reg5")
    public ModelAndView reg5(String uname){
        System.out.println("UserController.reg5()");    
        ModelAndView mav = new ModelAndView();
        mav.setViewName("index");        
        User u = new User("123");
        User u2 = new User("1234");
        mav.addObject(u);
        mav.addObject("uu", u2);
        return mav;
    }
    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    
}

3.  DispatcherServlet 根據得到的Handler,選擇一個合適的HandlerAdapter。(附註:若是成功得到HandlerAdapter後,此時將開始執行攔截器的preHandler(...)方法)

我前面說了HandlerExecutionChain就是一個Controller和一組interceptors。這是咱們執行一個request最基本的單元啦。

不過現實狀況會稍有些出入,HandlerExecutionChain實際上包括的一個Object和一組interceptor。這個Object是Adaptor,它能夠是Controller的Adaptor,也能夠是其它類的Adaptor。但現實中咱們通常用到的都是Controller,所以不詳細分析啦,這裏用了Adaptor後大大下降了代碼的可讀性,來換取與Controller非緊耦合的靈活性。至少我如今認爲這樣作不是太值。

   4.  提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程當中,根據你的配置,Spring將幫你作一些額外的工做:
      HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換爲指定的響應信息
      數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等
      數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等
      數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中
      5.  Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象;
詳見method=reg2
      6.  根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;
 
      7. ViewResolver 結合Model和View,來渲染視圖
      8. 將渲染結果返回給客戶端。
相關文章
相關標籤/搜索