1. 程式人生 > >SpringMVC入門級知識點簡單總結

SpringMVC入門級知識點簡單總結

SpringMVC是Spring框架的一個模組,是一個基於MVC的web框架。

流程:

1,向伺服器傳送的http request請求被DispatcherServerlet捕獲。

2,DispatcherServerlet根據xml檔案中的配置或註解對請求的URL進行解析,得到uri(請求資源識別符號)。然後根據uri呼叫HandlerMapping,獲得處理該請求的Handler和Handler對應的攔截器,最後以HandlerExecutionChain物件的形式返回。

3,DispatcherServerlet根據獲得的Handler選擇一個合適的HandlerAdapter去執行該Handler。

4,HandlerAdapter提取request中的模型資料,填充Handler入參,執行Handler(也稱為Controller)。

5,Handler(Controller)執行完後,向HandlerAdapter返回一個ModelAndView物件,HandlerAdapter再向DispatcherServerlet返回一個ModelAndView物件。

6,根據返回的ModelAndView,DispatcherServerlet請求一個合適的ViewResolver(必須已經註冊到Spring容器中)去進行檢視解析,然後ViewResolver向DispatcherServerlet返回一個真正的檢視View(jsp)。

7,DispatcherServerlet通過Model解析出ModelAndView中的引數進行解析,最終展現完整的view並通過Http response返回給客戶端。

整個過程我們只需編碼Handler和jsp,在WEB-INF/web.xm中配置DispatcherServerlet

前臺post提交亂碼問題如何解決:

可以在web.xml中配置過濾器解決

SpringMVC攔截器

定義攔截器要實現HandlerInterceptor介面,並實現其三個方法:

boolean preHandle:返回值為false表示攔截,true表示放行,在進入Handler方法前執行,可用於身份認證等

void postHandle:執行於進入Handler方法之後和返回ModelAndView之前。其形參中包含ModelAndView,可以用其返回公用的模型資料(公用導航選單欄)給檢視,或者指定統一的返回檢視

void afterCompletion:在Handler方法執行完後執行,可用於統一日記管理,統一異常處理等。

攔截器是根據具體對映器進行配置的,它配置於某個對映器中,也就是說經由某個HandlerMaping對映成功的Handler可以使用該攔截器。

攔截器的執行規律(假如配置三個):

1,三個攔截器同時放行的情況下,preHandle方法的執行順序是:1,2,3。postHandel和afterCompletion方法的執行順序是3,2,1。

2,不過只要三個攔截器中有一個進行攔截,那麼其後面的攔截器的preHandle方法不會執行,而且三個攔截器的postHandle都不會執行,三個攔截器中執行過preHandle並且返回true的會執行afterCompletion方法。

SpringMVC引數繫結

1,預設引數繫結

可以在controller的形參上直接定義以下預設型別的引數,SpringMVC就會自動繫結。

HttpServletRequest

HttpServletResponse

HttpSession

Model/ModelMap物件:model是個介面ModelMap是個介面實現類,作用和ModelAndView類似,是將Model資料填充到request域。

2,簡單引數繫結

引數名得和前臺傳入的值名稱一樣,如若不同得加上@RequestParam

3,POJO型別引數繫結

需要前臺input標籤的name屬性值和POJO中引數名稱一致。若需要傳入date型別的值,則需要轉換。

轉換可以是在前臺用date型別的input,然後在POJO中加上註解@DateTimeFormat(pattern = "yyyy-MM-dd")

注意此種轉換後,存入資料庫的不是yyyy-MM-dd形式,在前臺展示的時候需要controller轉換下傳入前端。

還可以定義一個轉換器類,繼承Converter介面,在實現的convert方法裡將傳入的String型別引數用SimpleDadteFormat轉換為date型別。做好後,在servlet配置檔案中,開啟轉換器和介面卡的那行程式碼中加入轉換器宣告,然後加入轉換器的bean就可以。

如何繫結包裝的POJO型別(POJO裡有另一個POJO):

1,用HttpserverletRequest接收(原始而通用)

2,直接讓包裝型別的POJO接收

重點說第二種:很簡單,直接在前臺將input的name值,設定為另一個POJO的引數名.引數名即可。

4,集合型別的繫結

1)陣列的繫結:例如前臺同時傳入一連串的ID讓後臺批量刪除

前臺:

Controller

2)list的繫結:例如前臺同時傳入一連串的商品資訊提交修改

封裝的POJO類,裡定義一個list屬性。前臺jsp中對每個item的命名方式是包裝類中的list屬性名+下標+對應list中的POJO屬性名,然後controller中直接讓POJO接收即可

3)Map的繫結

Public classQueryVo {

private Map<String,Student> itemInfo = new HashMap<String,Student>();

//get/set方法..

}

<tr>

<td>學生資訊:</td>

<td>

姓名:<inputtype="text"name="itemInfo['name']"/>

年齡:<inputtype="text"name="itemInfo['price']"/>

.. .. ..

</td>

</tr>

SpringMVC異常處理:

思路:dao、service、controller層一層層將異常丟擲,最終由前端控制器交給全域性異常處理器處理。

springMVC中自帶的簡單異常處理器

SimpleMappingExceptionResolver:實現了HandlerExceptionResolver介面。需要在SpringMVC.xml檔案中配置該處理器。

自定義全域性異常處理器:

處理思路:

1,繼承HandlerexceptionResolver介面,解析出異常型別。

2,如果該異常型別是系統自定義的異常,直接取出異常資訊,在錯誤介面顯示。

3,如果該異常型別不是系統自定義的異常,構造出一個自定義的異常型別(資訊為“未知錯誤”)

4,在SpringMVC.xml中配置。

@ExceptionHandler註解實現異常處理

首先寫個baseController類,並在類中使用@ExceptionHandler註解宣告異常處理的方法

public class BaseController {

   @ExceptionHandler 

   public String exp(HttpServletRequest request, Exception ex) {

   //異常處理

   //......

    }

}

然後所有需要處理異常的controller都繼承這個類,不需要配置什麼東西,但是程式碼有侵入性。

SpringMVC和前臺的json互動

SpringMVC和前臺主要有兩種互動形式

一種是key/value一種是json

 


首先準備載入json所需要的jar包,SpringMVC3和SpringMVC4有所差別

SpringMVC4是:

我專案中用的是gson和fastjson

第二件事是配置json轉換器如果使用註解驅動形式:

<mvc:annotation-driven/>則不用其他配置了。

具體互動時:如果前臺傳入json則後臺controller使用@RequestBody接收前臺的json串,用@ResponseBody將bean轉換為json並返回json。

如果前臺請求的事key/value則後臺只需要用@ResponseBody返回json即可。

檔案上傳常用元件有兩個cos fileupload和commons fileupload

Spring已經完全集成了這兩種元件,使用Commonsfileupload的較多一些

首先整合兩個jar包

其次前臺傳入的時候需要註明,form表單需要註明enctype=”multipart/form-data”屬性

在後臺的springMVC中註明multipartfile解析器

<!--上傳檔案 -->

<bean id="multipartResolver"

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

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

<!-- 最大記憶體大小 -->

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

<!-- 最大檔案大小,-1為不限制大小 -->

<property name="maxUploadSize" value="-1" />

</bean>

這樣,一旦某個Request是MultipartRequest,它就會首先被MultipartResolver處理。

然後再轉發相應的controller。

在具體的controller中將HttpservletRequest轉型為MultipartHttservletRequest,就能非常方便的得到檔名和檔案內容。最後呼叫其transferTo(newFile);即可儲存到本地。

如果想將前臺傳入的圖片轉換為縮圖,則不需要藉助第三方軟體,jdk標準庫就包含了影象處理API。

1.     public static void createPreviewImage(String srcFile, String destFile) {  

2.             try {  

3.                 File fi = new File(srcFile); // src   

4.                 File fo = new File(destFile); // dest   

5.                 BufferedImage bis = ImageIO.read(fi);

6.                 int w = bis.getWidth();  

7.                 int h = bis.getHeight();  

8.                 double scale = (double) w / h;  

9.                 int nw = IMAGE_SIZE; // final int IMAGE_SIZE = 120;   

10.              int nh = (nw * h) / w;  

11.              if (nh > IMAGE_SIZE) {  

12.                  nh = IMAGE_SIZE;  

13.                  nw = (nh * w) / h;  

14.              }  

15.              double sx = (double) nw / w;  

16.              double sy = (double) nh / h;  

17.              transform.setToScale(sx, sy);  

18.              AffineTransformOp ato = new AffineTransformOp(transform, null);  

19.              BufferedImage bid = new BufferedImage(nw, nh,  

20.                      BufferedImage.TYPE_3BYTE_BGR);  

21.              ato.filter(bis, bid);  

22.              ImageIO.write(bid, " jpeg ", fo);  

23.          } catch (Exception e) {  

24.              e.printStackTrace();  

25.              throw new RuntimeException(  

26.                      " Failed in create preview image. Error:  "  

27.                              + e.getMessage());  

28.          }  

29.      }