一文回顧SpringMVC

0.概述

  1. Spring 爲展示層提供的基於 MVC 設計理念的優秀的 Web 框架,是目前最主流的MVC 框架之一
  2. Spring3.0 後全面超越 Struts2,成爲最優秀的 MVC 框架。
  3. Spring MVC 經過一套 MVC 註解,讓 POJO 成爲處理請求的控制器,而無須實現任何接口。-------POJO(plain old java object)
  4. 支持 REST 風格的 URL 請求。
  5. 採用了鬆散耦合可插拔組件結構,比其餘 MVC 框架更具擴展性和靈活性。

SpringMVC是什麼?

一種輕量級的、基於MVCWeb層應用框架。偏前端而不是基於業務邏輯層。Spring框架的一個後續產品。html

2)Spring框架結構圖(新版本):前端

SpringMVC能幹什麼

  1. 天生與Spring框架集成,如:(IOC,AOP)
  2. 支持Restful風格
  3. 進行更簡潔的Web層開發
  4. 支持靈活的URL到頁面控制器的映射
  5. 很是容易與其餘視圖技術集成,如:VelocityFreeMarker等等
  6. 由於模型數據不存放在特定的API裏,而是放在一個Model(Map數據結構實現,所以很容易被其餘框架使用)
  7. 很是靈活的數據驗證、格式化和數據綁定機制、能使用任何對象進行數據綁定,沒必要實現特定框架的API
  8. 更加簡單、強大的異常處理
  9. 對靜態資源的支持
  10. 支持靈活的本地化、主題等解析

SpringMVC怎麼玩

  1. Web層進行了職責解耦,基於請求-響應模型
  2. 經常使用主要組件
      • DispatcherServlet:前端控制器
      • Controller:處理器/頁面控制器,作的是MVC中的C的事情,但控制邏輯轉移到前端控制器了,用於對請求進行處理
      • HandlerMapping :請求映射處處理器,找誰來處理,若是映射成功返回一個HandlerExecutionChain對象(包含一個Handler處理器(頁面控制器)對象、多個HandlerInterceptor攔截器對象)
      • View Resolver : 視圖解析器,找誰來處理返回的頁面。把邏輯視圖解析爲具體的View,進行這種策略模式,很容易更換其餘視圖技術
      • LocalResolver:本地化、國際化
      • MultipartResolver:文件上傳解析器
      • HandlerExceptionResolver:異常處理器

1.HelloWorld

1.新建Web工程,加入 jar java

spring-aop-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
commons-logging-1.1.3.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar

2.在 web.xml 中配置 DispatcherServlet程序員

<!-- 配置SpringMVC核心控制器: -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>


<!-- 配置DispatcherServlet的初始化參數:設置文件的路徑和文件名稱 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

3.加入 Spring MVC 的配置文件:springmvc.xmlweb

  •  增長名稱空間
    •   
  • 增長配置
<!-- 設置掃描組件的包: -->`
<context:component-scan base-package="com.hbuas.springmvc"/>
 
<!-- 配置映射解析器:如何將控制器返回的結果字符串,轉換爲一個物理的視圖文件-->
<bean id="internalResourceViewResolver" 
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>

這裏回顧一下知識點:ajax

  • 靜態資源放在webContent下面的時候,可直接經過瀏覽器訪問,不須要配置映射,安全性略低
  • WEB-INF是JavaWEB應用的安全目錄。所謂安全就是客戶端沒法訪問,只有服務端能夠訪問的目錄。當靜態資源放在WEB-INF下面的時候,外部是不能直接訪問的。

4.須要建立一個入口頁面,index.jspspring

<a href="${pageContext.request.contextPath }/helloworld">Hello World</a>

5.編寫處理請求的處理器,並標識爲Controllerexpress

package com.hbuas.springmvc.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller  //聲明Bean對象,爲一個控制器組件
public class HelloWorldController {
 
/**
 * 
 * 1. 使用 @RequestMapping 註解來映射請求的 URL
 * 2. 返回值會經過視圖解析器解析爲實際的物理視圖
 */
@RequestMapping(value="/helloworld",method=RequestMethod.GET)
public String helloworld(){
     System.out.println("hello,world");
     return "success"; 
   }
/**
**  如何跳轉呢?
 *  對於 InternalResourceViewResolver 視圖解析器, 
 *  會作以下的解析:
 *     經過 prefix + returnVal + suffix 這樣的方式獲得實際的物理視圖, 而後作轉發操做.
 *    /WEB-INF/views/success.jsp
*/
        
}

HelloWorld深度解析

基本步驟:json

  • 客戶端請求提交到DispatcherServlet
  • DispatcherServlet控制器查詢一個或多個HandlerMapping,找處處理請求的Controller
  • DispatcherServlet將請求提交到Controller(也稱爲Handler)
  • Controller調用業務邏輯處理後,返回ModelAndView
  • DispatcherServlet查詢一個或多個ViewResoler視圖解析器,找到ModelAndView指定的視圖
  • 視圖負責將結果顯示到客戶端

2.@RequestMapping

@RequestMapping 概念

  1. SpringMVC使用@RequestMapping註解爲控制器指定能夠處理哪些 URL 請求
    1. 在控制器的類及方法處均可標註 @RequestMapping
      • 標記在類上:提供初步的請求映射信息。相對於  WEB 的根目錄
      • 標記在方法上:提供進一步的細分映射信息。相對於標記在類上的 URL
    2. 若類上未標註 @RequestMapping,則方法處標記的 URL 相對於 WEB 的根目錄
    3. 做用:DispatcherServlet 截獲請求後,就經過控制器上 @RequestMapping 提供的映射信息肯定請求所對應的處理方法。

實驗代碼:數組

定義頁面連接

<a href="springmvc/helloworld">test</a>

定義控制器方法

@Controller 
@RequestMapping("/springmvc")
public class HelloWorldController {

@RequestMapping(value="/helloworld")
public String helloworld(){
System.out.println("hello,world");
return "success"; 
   }        
}

映射請求方法

@RequestMapping 除了可使用請求 URL 映射請求外,還可使用請求方法、請求參數及請求頭映射請求.

@RequestMapping valuemethodparams heads 分別表示請求 URL、請求方法、請求參數及請求頭的映射條件,他們之間是與的關係,聯合使用多個條件可以讓請求映射更加精確化。

請求方式:GET 查詢  POST 添加  PUT  修改  DELETE  刪除

實驗代碼:

定義請求方式爲POST

@Controller
@RequestMapping("/springmvc")
public class SpringMVCController {
@RequestMapping(value="/testMethord",method=RequestMethod.POST)
public String testMethord(){
System.out.println("testMethord...");
return "success";
}
}

以get方式請求

<a href="springmvc/testMethord">testMethord</a>

映射請求參數&請求頭

// 可使用 params 和 headers 來更加精確的映射請求. params 和 headers 支持簡單的表達式.
@RequestMapping(value="/testParamsAndHeaders",
params= {"username","age!=10"}, headers = { "Accept-Language=en-US,zh;q=0.8" })
public String testParamsAndHeaders(){
System.out.println("testParamsAndHeaders...");
return "success";
}

測試不正確的話會出現

警告: No matching handler method found for servlet request: path '/springmvc/testParamsAndHeaders', method 'GET', parameters map[[empty]]

RequestMapping支持Ant 路徑風格

Ant

  1. Ant 風格資源地址支持 3 種匹配符

?:匹配文件名中的一個字符

*:匹配文件名中的任意字符

**** 匹配多層路徑

/user/*/createUser
匹配 /user/aaa/createUser或者/user/bbb/createUser 等 URL
/user/**/createUser
匹配 /user/createUser或者/user/aaa/bbb/createUser 等 URL
/user/createUser??
匹配 /user/createUseraa或者/user/createUserbb 等 URL


//@RequestMapping(value="/testAntPath/*/abc")
//@RequestMapping(value="/testAntPath/**/abc")
@RequestMapping(value="/testAntPath/abc??")

請求佔位符PathVariable註解

 @PathVariable

帶佔位符的URL Spring3.0 新增的功能,該功能在 SpringMVC REST 目標挺進發展過程當中具備里程碑的意義

經過 @PathVariable 能夠將 URL 中佔位符參數綁定到控制器處理方法的入參中

URL 中的 {xxx} 佔位符能夠經過 @PathVariable("xxx") 綁定到操做方法的入參中。

//@PathVariable 註解能夠將請求URL路徑中的請求參數,傳遞處處理請求方法的入參中
//瀏覽器的請求:  testPathVariable/1001


@RequestMapping(value="/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable...id="+id);
return "success";
}

3.處理請求數據

@RequestParam註解

1)在處理方法入參處使用 @RequestParam 能夠把請求參數傳遞給請求方法

2value:參數名

3required:是否必須。默認爲 true, 表示請求參數中必須包含對應的參數,若不存在,將拋出異常

4defaultValue: 默認值,當沒有傳遞參數時使用該值

/**
 * @RequestParam 註解用於映射請求參數
 *         value 用於映射請求參數名稱
 *         required 用於設置請求參數是否必須的
 *         defaultValue 設置默認值,當沒有傳遞參數時使用該值
 */
@RequestMapping(value="/testRequestParam")
public String testRequestParam(
@RequestParam(value="username") String username,
@RequestParam(value="age",required=false,defaultValue="0") int age){
System.out.println("testRequestParam - username="+username +",age="+age);
return "success";
}
<!--測試 請求參數 @RequestParam 註解使用 -->
<a href="springmvc/testRequestParam?username=admin&age=10">testRequestParam</a>

@RequestHeader

  1. 使用 @RequestHeader 綁定請求報頭的屬性值
  2. 請求頭包含了若干個屬性,服務器可據此獲知客戶端的信息,經過 @RequestHeader 便可將請求頭中的屬性值綁定處處理方法的入參中 
//瞭解: 映射請求頭信息 用法同 @RequestParam
@RequestMapping(value="/testRequestHeader")
public String testRequestHeader(@RequestHeader(value="Accept-Language") String al){
System.out.println("testRequestHeader - Accept-Language:"+al);
return "success";
}

@CookieValue

  1. 使用 @CookieValue 綁定請求中的 Cookie
  2. @CookieValue 可以讓處理方法入參綁定某個 Cookie
//瞭解:@CookieValue: 映射一個 Cookie 值. 屬性同 @RequestParam
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) {
System.out.println("testCookieValue: sessionId: " + sessionId);
return "success";
}

使用POJO做爲參數

  1. 使用 POJO 對象綁定請求參數值
  2. Spring MVC 會按請求參數名和 POJO 屬性名進行自動匹配,自動爲該對象填充屬性值支持級聯屬性。如:dept.deptIddept.address.tel
/**
 * Spring MVC 會按請求參數名和 POJO 屬性名進行自動匹配, 自動爲該對象填充屬性值。
 * 支持級聯屬性
 *                 如:dept.deptId、dept.address.tel 等
 */
@RequestMapping("/testPOJO")
public String testPojo(User user) {
System.out.println("testPojo: " + user);
return "success";
}
<!-- 測試 POJO 對象傳參,支持級聯屬性 -->
<form action=" testPOJO" method="POST">
username: <input type="text" name="username"/><br>
password: <input type="password" name="password"/><br>
email: <input type="text" name="email"/><br>
age: <input type="text" name="age"/><br>
city: <input type="text" name="address.city"/><br>
province: <input type="text" name="address.province"/>
<input type="submit" value="Submit"/>
</form>

增長實體類

public class Address {

 private String province;

private String city;

public class User {

private Integer id ;

private String username;

private String password;

private String email;

private int age;

private Address address;

 

4.處理響應數據

SpringMVC 輸出模型數據

SpringMVC 提供瞭如下幾種途徑輸出模型數據

  1. ModelAndView: 處理方法返回值類型爲 ModelAndView , 方法體便可經過該對象添加模型數據
  2. Map Model: 入參爲 org.springframework.ui.Modelorg.springframework.ui.ModelMap java.uti.Map 時,處理方法返回時,Map 中的數據會自動添加到模型中。

ModelAndView

控制器處理方法的返回值若是爲 ModelAndView, 則其既包含視圖信息,也包含模型數據信息。

  1. 兩個重要的成員變量:

private Object view;      視圖信息

private ModelMap model; 模型數據

2)添加模型數據:

MoelAndView addObject(String attributeName, Object attributeValue)   設置模型數據

ModelAndView addAllObject(Map<String, ?> modelMap)

3)設置視圖:

void setView(View view)                設置視圖對象

void setViewName(String viewName)     設置視圖名字

 4)獲取模型數據

      protected Map<String, Object> getModelInternal()   獲取模型數據

      public ModelMap getModelMap()

      public Map<String, Object> getModel()

實驗代碼:

/**
 * 目標方法的返回類型能夠是ModelAndView類型
 *                 其中包含視圖信息和模型數據信息
 */
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
System.out.println("testModelAndView");
String viewName = "success";
ModelAndView mv = new ModelAndView(viewName );
mv.addObject("time",new Date().toString()); //實質上存放到request域中 
return mv;
}

處理模型數據之 Map   Model

Map介紹

Spring MVC 在內部使用了一個 org.springframework.ui.Model 接口存儲模型數據

具體使用步驟

2Spring MVC 在調用方法前會建立一個隱含的模型對象做爲模型數據的存儲容器

3)若是方法的入參爲 Map Model 類型Spring MVC 會將隱含模型的引用傳遞給這些入參。

4)在方法體內,開發者能夠經過這個入參對象訪問到模型中的全部數據,也能夠向模型中添加新的屬性數據

實驗代碼:

//目標方法的返回類型也能夠是一個Map類型參數(也能夠是Model,或ModelMap類型)
@RequestMapping("/testMap")
public String testMap(Map<String,Object> map){ //【重點】
System.out.println(map.getClass().getName());
map.put("names", Arrays.asList("Tom","Jerry","Kite"));
return "success";
}
<!-- 測試 Map 做爲處理返回結果 -->
<a href="springmvc/testMap">testMap</a>
<!--增長成功頁面,顯示結果-->
names: ${requestScope.names }

注意問題:Map集合的泛型,keyString,ValueObject,而不是String

5.視圖解析

視圖

  1. 視圖的做用是渲染模型數據,將模型裏的數據以某種形式呈現給客戶。
  2. 爲了實現視圖模型和具體實現技術的解耦,Spring org.springframework.web.servlet 包中定義了一個高度抽象的 View 接口:

3.視圖對象由視圖解析器負責實例化。因爲視圖是無狀態的,因此他們不會有線程安全的問題

 

不論控制器返回一個String,ModelAndView,View都會轉換爲ModelAndView對象,由視圖解析器解析視圖,而後,進行頁面的跳轉。

  1. 請求處理方法執行完成後,最終返回一個 ModelAndView 對象。對於那些返回 StringView ModeMap 等類型的處理方法,Spring MVC 也會在內部將它們裝配成一個 ModelAndView 對象,它包含了邏輯名和模型對象的視圖
  2. Spring MVC 藉助視圖解析器ViewResolver)獲得最終的視圖對象(View),最終的視圖能夠是 JSP ,也多是 ExcelJFreeChart等各類表現形式的視圖
  3. 對於最終究竟採起何種視圖對象對模型數據進行渲染,處理器並不關心,處理器工做重點聚焦在生產模型數據的工做上,從而實現 MVC 的充分解耦

重定向 

  • 通常狀況下,控制器方法返回字符串類型的值會被當成邏輯視圖名處理
  • 若是返回的字符串中帶 forward: redirect: 前綴時,SpringMVC 會對他們進行特殊處理:將 forward: redirect: 當成指示符,其後的字符串做爲 URL 來處理
  • redirect:success.jsp:會完成一個到 success.jsp 的重定向的操做
  • forward:success.jsp:會完成一個到 success.jsp 的轉發操做
@RequestMapping("/testRedirect")
public String testRedirect(){
System.out.println("testRedirect");
return "redirect:/index.jsp";
//return "forward:/index.jsp";
}

轉發與重定向知識回顧:

區別 轉發forward() 重定向sendRedirect()
根目錄 包含項目訪問地址 沒有項目訪問地址
地址欄 不會發生變化 會發生變化
哪裏跳轉 服務器端進行的跳轉 瀏覽器端進行的跳轉
請求域中數據 不會丟失 會丟失

6.處理JSON

springMVC處理json的四個條件:
      一、導入jackson的jar
      二、在springMVC的配置文件中開啓MVC驅動,<mvc:annotation-driven />
      三、在處理ajax請求的方法上加上註解@ResponseBody
      四、將要轉換爲json且響應到客戶端的數據,直接做爲該方法的返回值返回
    

@RequestMapping("/testJson")
	@ResponseBody
	public Collection<Employee> testJson() {
		Collection<Employee> emps = dao.getAll();
		return emps;
	}

7.文件上傳

  1. Spring MVC 爲文件上傳提供了直接的支持,這種支持是經過即插即用的 MultipartResolver 實現的。
  2. Spring Jakarta Commons FileUpload 技術實現了一個 MultipartResolver 實現類:CommonsMultipartResolver  
  3. Spring MVC 上下文中默認沒有裝配 MultipartResovler,所以默認狀況下不能處理文件的上傳工做,若是想使用 Spring 的文件上傳功能,需如今上下文中配置 MultipartResolver

實例:

  1. 拷貝jar
  • commons-fileupload-1.2.1.jar
  • commons-io-2.0.jar
  1. 配置文件上傳解析器
 

<bean id="multipartResolver"

 class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<property name="defaultEncoding" value="UTF-8"></property>

<property name="maxUploadSize" value="1024000"></property>

</bean>

  1. 上傳頁面

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

 "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<form action="testUpload" method="post" enctype="multipart/form-data">

文件: <input type="file" name="file"/><br><br>

描述: <input type="text" name="desc"/><br><br>

<input type="submit" value="提交"/>

</form>

</body>

</html>

  1. 控制器方法

@Controller

public class UploadHandler {

 @RequestMapping(value="/testUpload",method=RequestMethod.POST)

public String testUpload(

@RequestParam(value="desc",required=false) String desc,

@RequestParam("file") MultipartFile multipartFile) throws IOException{                

System.out.println("desc : "+desc);

System.out.println("OriginalFilename : "+multipartFile.getOriginalFilename());

InputStream inputStream = multipartFile.getInputStream();

System.out.println("inputStream.available() : "+inputStream.available());

System.out.println("inputStream : "+inputStream);

return "success";

}

}

 多個文件上傳

8.攔截器

  1. Spring MVC也可使用攔截器對請求進行攔截處理,用戶能夠自定義攔截器來實現特定的功能,自定義的攔截器能夠實現HandlerInterceptor接口,也能夠繼承HandlerInterceptorAdapter 適配器類  
    • preHandle():這個方法在業務處理器處理請求以前被調用,在該方法中對用戶請求 request 進行處理。若是程序員決定該攔截器對請求進行攔截處理後還要調用其餘的攔截器,或者是業務處理器去進行處理,則返回true;若是程序員決定不須要再調用其餘的組件去處理請求,則返回false
    • postHandle()這個方法在業務處理器處理完請求後,可是DispatcherServlet 向客戶端返回響應前被調用,在該方法中對用戶請求request進行處理。
    • afterCompletion():這個方法 DispatcherServlet 徹底處理完請求後被調用,能夠在該方法中進行一些資源清理的操做。
  2. 當有多個攔截器時
    • preHandle:按照攔截器數組的正向順序執行
    • postHandle:按照攔截器數組的反向順序執行
    • afterCompletion:按照攔截器數組的反向順序執行

9.異常處理

  1. Spring MVC 經過 HandlerExceptionResolver  處理程序的異常,包括 Handler 映射、數據綁定以及目標方法執行時發生的異常。
  2. SpringMVC 提供的 HandlerExceptionResolver 的實現類

DispatcherServlet  默認裝配的 HandlerExceptionResolver

能夠對一些特殊的異常進行處理,好比:

  1. NoSuchRequestHandlingMethodException
  2. HttpRequestMethodNotSupportedException
  3. HttpMediaTypeNotSupportedException
  4. HttpMediaTypeNotAcceptableException等。

若是但願對全部異常進行統一處理,可使用 SimpleMappingExceptionResolver,它將異常類名映射爲視圖名,即發生異常時使用對應的視圖報告異常

10.運行流程圖解

Spring工做流程描述

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

2.DispatcherServlet對請求URL進行解析,獲得請求資源標識符(URI:

判斷請求URI對應的映射

不存在:

  • 再判斷是否配置了mvc:default-servlet-handler
  • 若是沒配置,則控制檯報映射查找不到,客戶端展現404錯誤
  • 若是有配置,則執行目標資源(通常爲靜態資源,如:JS,CSS,HTML

存在:

  • 執行下面流程

3.根據該URI,調用HandlerMapping得到該Handler配置的全部相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以HandlerExecutionChain對象的形式返回;

4.DispatcherServlet 根據得到的Handler,選擇一個合適的HandlerAdapter

5.若是成功得到HandlerAdapter後,此時將開始執行攔截器的preHandler(...)方法【正向】

6.提取Request中的模型數據,填充Handler入參,開始執行HandlerController)方法,處理請求。在填充Handler的入參過程當中,根據你的配置,Spring將幫你作一些額外的工做:

  • HttpMessageConveter 將請求消息(如Jsonxml等數據)轉換成一個對象,將對象轉換爲指定的響應信息
  • 數據轉換:對請求消息進行數據轉換。如String轉換成IntegerDouble
  • 數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等
  • 數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResultError

7.Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象;

8.此時將開始執行攔截器的postHandle(...)方法【逆向】

9.根據返回的ModelAndView(此時會判斷是否存在異常:若是存在異常,則執行HandlerExceptionResolver進行異常處理)選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)返回給DispatcherServlet,根據ModelView,來渲染視圖

10.在返回給客戶端時須要執行攔截器的AfterCompletion方法【逆向】

11.將渲染結果返回給客戶端

11.Spring整合SpringMVC

SpringIOC 容器和 SpringMVC IOC 容器的關係

SpringMVC IOC 容器中的 bean 能夠來引用 Spring IOC 容器中的 bean.反之則不行. Spring IOC 容器中的 bean 卻不能來引用 SpringMVC IOC 容器中的 bean 

  1. Spring MVC 配置文件中引用業務層的 Bean
  2. 多個 Spring IOC 容器之間能夠設置爲父子關係,以實現良好的解耦。
  3. Spring MVC WEB 層容器可做爲 「業務層」 Spring 容器的子容器:

WEB 層容器能夠引用業務層容器的 Bean,而業務層容器卻訪問不到 WEB 層容器的 Bean

SpringMVC對比Struts2

  • Spring MVC 的入口是 Servlet, Struts2 Filter。Spring MVC 會稍微比 Struts2 快些.
  • Spring MVC 是基於方法設計, Sturts2 是基於類每次發一次請求都會實例一個 Action.
  • Spring MVC 使用更加簡潔, 開發效率Spring MVC確實比 struts2 : 支持 JSR303,  ajax 的請求更方便
  • Struts2 OGNL 表達式使頁面的開發效率相比 Spring MVC 更高些.
相關文章
相關標籤/搜索