SpringMVC筆記三

課程安排:

第一天:springmvc的基礎知識

什麼是springmvc?

springmvc框架原理(掌握)

         前端控制器、處理器映射器、處理器適配器、視圖解析器

springmvc入門程序

         目的:對前端控制器、處理器映射器、處理器適配器、視圖解析器學習

         非註解的處理器映射器、處理器適配器

         註解的處理器映射器、處理器適配器(掌握)

springmvc和mybatis整合(掌握)

 

springmvc註解開發:(掌握)

         經常使用的註解學習

         參數綁定(簡單類型、pojo、集合類型(明天講))

         自定義參數綁定(掌握)

springmvc和struts2區別

 

次日:springmvc的高級應用

         參數綁定(集合類型)

         數據回顯

         上傳圖片

         json數據交互

         RESTful支持

         攔截器
View Code

springmvc框架

1.1什麼是springmvc

springmvc是spring框架的一個模塊,springmvc和spring無需經過中間整合層進行整合。html

springmvc是一個基於mvc的web框架。前端

 

 

1.2      mvc在b/s系統 下的應用

mvc是一個設計模式,mvc在b/s系統 下的應用:java

1.3      springmvc框架

 

第一步:發起請求到前端控制器(DispatcherServlet)mysql

第二步:前端控制器請求HandlerMapping查找 Handler   能夠根據xml配置、註解進行查找jquery

第三步:處理器映射器HandlerMapping向前端控制器返回Handler程序員

第四步:前端控制器調用處理器適配器去執行Handlerweb

第五步:處理器適配器去執行Handlerajax

第六步:Handler執行完成給適配器返回ModelAndViewspring

第七步:處理器適配器向前端控制器返回ModelAndView, ModelAndView是springmvc框架的一個底層對象,包括 Model和viewsql

第八步:前端控制器請求視圖解析器去進行視圖解析 根據邏輯視圖名解析成真正的視圖(jsp)

第九步:視圖解析器向前端控制器返回View

第十步:前端控制器進行視圖渲染 視圖渲染將模型數據(在ModelAndView對象中)填充到request域

第十一步:前端控制器向用戶響應結果

組件:

一、前端控制器DispatcherServlet(不須要程序員開發)

做用接收請求,響應結果,至關於轉發器,中央處理器。

有了DispatcherServlet減小了其它組件之間的耦合度。

 

二、處理器映射器HandlerMapping(不須要程序員開發)

做用:根據請求的url查找Handler

 

三、處理器適配器HandlerAdapter

做用:按照特定規則(HandlerAdapter要求的規則)去執行Handler

 

四、處理器Handler(須要程序員開發)

注意:編寫Handler時按照HandlerAdapter的要求去作,這樣適配器才能夠去正確執行Handler

 

五、視圖解析器View resolver(不須要程序員開發)

做用:進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)

 

六、視圖View(須要程序員開發jsp)

View是一個接口,實現類支持不一樣的View類型(jsp、freemarker、pdf...)

入門程序

2.1      需求

以案例做爲驅動。

springmvc和mybaits使用一個案例(商品訂單管理)。

功能需求:商品列表查詢

2.2      環境準備

數據庫環境:mysql5.1

 

java環境:

jdk1.7.0_72

eclipse indigo

springmvc版本:spring3.2

須要spring3.2全部jar(必定包括spring-webmvc-3.2.0.RELEASE.jar)

 

2.3      配置前端控制器

在web.xml中配置前端控制器。

 

2.4      配置處理器適配器

在classpath下的springmvc.xml中配置處理器適配器

 

經過查看原代碼:

 

此適配器能執行實現 Controller接口的Handler。

 

2.5      開發Handler

須要實現 controller接口,才能由org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter適配器執行。

public class ItemsController1 implements Controller {

 

   @Override

   public ModelAndView handleRequest(HttpServletRequest request,

         HttpServletResponse response) throws Exception {

     

      //調用service查找 數據庫,查詢商品列表,這裏使用靜態數據模擬

      List<Items> itemsList = new ArrayList<Items>();

      //向list中填充靜態數據

     

      Items items_1 = new Items();

      items_1.setName("聯想筆記本");

      items_1.setPrice(6000f);

      items_1.setDetail("ThinkPad T430 聯想筆記本電腦!");

     

      Items items_2 = new Items();

      items_2.setName("蘋果手機");

      items_2.setPrice(5000f);

      items_2.setDetail("iphone6蘋果手機!");

     

      itemsList.add(items_1);

      itemsList.add(items_2);

 

      //返回ModelAndView

      ModelAndView modelAndView =  new ModelAndView();

      //至關 於request的setAttribut,在jsp頁面中經過itemsList取數據

      modelAndView.addObject("itemsList", itemsList);

     

      //指定視圖

      modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");

 

      return modelAndView;

   }

 

}
View Code

2.6      視圖編寫

 

2.7      配置Handler

將編寫Handler在spring容器加載。

 

2.8      配置處理器映射器

在classpath下的springmvc.xml中配置處理器映射器

 

2.9      配置視圖解析器

須要配置解析jsp的視圖解析器。

 

2.10 部署調試

訪問地址:http://localhost:8080/springmvcfirst1208/queryItems.action

處理器映射器根據url找不到Handler,報下邊的錯誤。說明url錯誤。

 

處理器映射器根據url找到了Handler,轉發的jsp頁面找到,報下邊的錯誤,說明jsp頁面地址錯誤了。

 

非註解的處理器映射器和適配器

3.1      非註解的處理器映射器

處理器映射器:

org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping

另外一個映射器:

org.springframework.web.servlet.handler.SimpleUrlHandlerMapping

 

多個映射器能夠並存,前端控制器判斷url能讓哪些映射器映射,就讓正確的映射器處理。

3.2      非註解的處理器適配器

org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter

要求編寫的Handler實現 Controller接口。

org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter

要求編寫的Handler實現 HttpRequestHandler接口。

 

      //使用此方法能夠經過修改response,設置響應的數據格式,好比響應json數據

 

 

/*
      response.setCharacterEncoding("utf-8");

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

      response.getWriter().write("json串");
*/

 

DispatcherSerlvet.properties

 

前端控制器從上邊的文件中加載處理映射器、適配器、視圖解析器等組件,若是不在springmvc.xml中配置,使用默認加載的。

註解的處理器映射器和適配器

在spring3.1以前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping註解映射器。

在spring3.1以後使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping註解映射器。

在spring3.1以前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter註解適配器。

在spring3.1以後使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter註解適配器。

5.1      配置註解映射器和適配器。

 

<!-- 使用 mvc:annotation-driven代替上邊註解映射器和註解適配器配置

   mvc:annotation-driven默認加載不少的參數綁定方法,

   好比json轉換解析器就默認加載了,若是使用mvc:annotation-driven不用配置上邊的RequestMappingHandlerMapping和RequestMappingHandlerAdapter

   實際開發時使用mvc:annotation-driven

    -->

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

5.2      開發註解Handler

使用註解的映射器和註解的適配器。(註解的映射器和註解的適配器必須配對使用)

//使用Controller標識 它是一個控制器

@Controller

public class ItemsController3 {

  

   //商品查詢列表

   //@RequestMapping實現 對queryItems方法和url進行映射,一個方法對應一個url

   //通常建議將url和方法寫成同樣

   @RequestMapping("/queryItems")

   public ModelAndView queryItems()throws Exception{

     

      //調用service查找 數據庫,查詢商品列表,這裏使用靜態數據模擬

      List<Items> itemsList = new ArrayList<Items>();

      //向list中填充靜態數據

     

      Items items_1 = new Items();

      items_1.setName("聯想筆記本");

      items_1.setPrice(6000f);

      items_1.setDetail("ThinkPad T430 聯想筆記本電腦!");

     

      Items items_2 = new Items();

      items_2.setName("蘋果手機");

      items_2.setPrice(5000f);

      items_2.setDetail("iphone6蘋果手機!");

     

      itemsList.add(items_1);

      itemsList.add(items_2);

     

      //返回ModelAndView

      ModelAndView modelAndView =  new ModelAndView();

      //至關 於request的setAttribut,在jsp頁面中經過itemsList取數據

      modelAndView.addObject("itemsList", itemsList);

     

      //指定視圖

      modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");

     

      return modelAndView;

     

   }
View Code

5.3      在spring容器中加載Handler

   <!-- 對於註解的Handler能夠單個配置

   實際開發中建議使用組件掃描

    -->

   <!-- <bean class="cn.itcast.ssm.controller.ItemsController3" /> -->

   <!-- 能夠掃描controller、service、...

   這裏讓掃描controller,指定controller的包

    -->

   <context:component-scan base-package="cn.itcast.ssm.controller"></context:component-scan>

5.4      部署調試

訪問:http://localhost:8080/springmvcfirst1208/queryItems.action

源碼分析(瞭解)

經過前端控制器源碼分析springmvc的執行過程。

第一步:前端控制器接收請求

調用doDiapatch

 

第二步:前端控制器調用處理器映射器查找 Handler

 

第三步:調用處理器適配器執行Handler,獲得執行結果ModelAndView

 

第四步:視圖渲染,將model數據填充到request域。

視圖解析,獲得view:

 

 

 

調用view的渲染方法,將model數據填充到request域

 

渲染方法:

 

 

入門程序小結

經過入門程序理解springmvc前端控制器、處理器映射器、處理器適配器、視圖解析器用法。

前端控制器配置:

第一種:*.action,訪問以.action結尾 由DispatcherServlet進行解析

第二種:/,因此訪問的地址都由DispatcherServlet進行解析,對於靜態文件的解析須要配置不讓DispatcherServlet進行解析

使用此種方式能夠實現 RESTful風格的url

處理器映射器:

非註解處理器映射器(瞭解)

註解的處理器映射器(掌握)

         對標記@Controller類中標識有@RequestMapping的方法進行映射。在@RequestMapping裏邊定義映射的url。使用註解的映射器不用在xml中配置url和Handler的映射關係。

處理器適配器:

非註解處理器適配器(瞭解)

註解的處理器適配器(掌握)

         註解處理器適配器和註解的處理器映射器是配對使用。理解爲不能使用非註解映射器進行映射。

<mvc:annotation-driven></mvc:annotation-driven>能夠代替下邊的配置:

 

   <!--註解映射器 -->

   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

   <!--註解適配器 -->

   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
View Code

實際開發使用:mvc:annotation-driven

視圖解析器配置前綴和後綴:

 

程序中不用指定前綴和後綴:

 

springmvc和mybatis整合

8.1      需求

使用springmvc和mybatis完成商品列表查詢。

8.2      整合思路

springmvc+mybaits的系統架構:

 

 

第一步:整合dao層

         mybatis和spring整合,經過spring管理mapper接口。

         使用mapper的掃描器自動掃描mapper接口在spring中進行註冊。

 

第二步:整合service層

         經過spring管理 service接口。

         使用配置方式將service接口配置在spring配置文件中。

         實現事務控制。

 

第三步:整合springmvc

         因爲springmvc是spring的模塊,不須要整合。

8.3      準備環境

數據庫環境:mysql5.1

 

java環境:

jdk1.7.0_72

eclipse indigo

springmvc版本:spring3.2

所須要的jar包:

數據庫驅動包:mysql5.1

mybatis的jar包

mybatis和spring整合包

log4j包

dbcp數據庫鏈接池包

spring3.2全部jar包

jstl包

參考:

工程結構:

 

8.4      整合dao

mybatis和spring進行整合。

8.4.1      sqlMapConfig.xml

mybatis本身的配置文件。

 

8.4.2      applicationContext-dao.xml

配置:

數據源

SqlSessionFactory

mapper掃描器

 

8.4.3      逆向工程生成po類及mapper(單表增刪改查)

 

將生成的文件拷貝至工程 中。

8.4.4      手動定義商品查詢mapper

針對綜合查詢mapper,通常狀況會有關聯查詢,建議自定義mapper

8.4.4.1             ItemsMapperCustom.xml

sql語句:

         SELECT * FROM items  WHERE items.name LIKE '%筆記本%'

 

8.4.4.2             ItemsMapperCustom.java

 

8.5      整合service

讓spring管理service接口。

8.5.1      定義service接口

 

8.5.2      在spring容器配置service(applicationContext-service.xml)

 

建立applicationContext-service.xml,文件中配置service。

 

8.5.3      事務控制(applicationContext-transaction.xml)

在applicationContext-transaction.xml中使用spring聲明式事務控制方法。

 

8.6      整合springmvc

8.6.1      springmvc.xml

建立springmvc.xml文件,配置處理器映射器、適配器、視圖解析器。

 

<!-- 能夠掃描controller、service、...這裏讓掃描controller,指定controller的包-->

   <context:component-scan base-package="cn.itcast.ssm.controller"></context:component-scan>

 

   <!--註解映射器 -->

   <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> -->

   <!--註解適配器 -->

   <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> -->

  

   <!-- 使用 mvc:annotation-driven代替上邊註解映射器和註解適配器配置

   mvc:annotation-driven默認加載不少的參數綁定方法,

   好比json轉換解析器就默認加載了,若是使用mvc:annotation-driven不用配置上邊的RequestMappingHandlerMapping和RequestMappingHandlerAdapter

   實際開發時使用mvc:annotation-driven

    -->

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

  

 

   <!-- 視圖解析器

   解析jsp解析,默認使用jstl標籤,classpath下的得有jstl的包

    -->

   <bean

      class="org.springframework.web.servlet.view.InternalResourceViewResolver">

      <!-- 配置jsp路徑的前綴 -->

      <property name="prefix" value="/WEB-INF/jsp/"/>

      <!-- 配置jsp路徑的後綴 -->

      <property name="suffix" value=".jsp"/>

   </bean>
springmvc.xml

 

 

8.6.2      配置前端控制器

 

參考入門程序。

 

8.6.3      編寫Controller(就是Handler)

 

8.6.4      編寫jsp

 

8.7      加載spring容器

將mapper、service、controller加載到spring容器中。

 

建議使用通配符加載上邊的配置文件。

在web.xml中,添加spring容器監聽器,加載spring容器。

 

商品修改功能開發

9.1      需求

操做流程:

一、進入商品查詢列表頁面

二、點擊修改,進入商品修改頁面,頁面中顯示了要修改的商品(從數據庫查詢), 要修改的商品從數據庫查詢,根據商品id(主鍵)查詢商品信息

三、在商品修改頁面,修改商品信息,修改後,點擊提交

9.2      開發mapper

mapper:

         根據id查詢商品信息

         根據id更新Items表的數據

不用開發了,使用逆向工程生成的代碼。

 

9.3      開發service

接口功能:

         根據id查詢商品信息

         修改商品信息

 

9.4      開發controller

方法:

         商品信息修改頁面顯示

         商品信息修改提交

@RequestMapping

n  url映射

定義controller方法對應的url,進行處理器映射使用。

n  窄化請求映射

 

n  限制http請求方法

出於安全性考慮,對http的連接進行方法限制。

若是限制請求爲post方法,進行get請求,報錯:

 

controller方法的返回值

n  返回ModelAndView

須要方法結束時,定義ModelAndView,將model和view分別進行設置。

 

n  返回string

若是controller方法返回string,

 

一、表示返回邏輯視圖名。

真正視圖(jsp路徑)=前綴+邏輯視圖名+後綴

 

 

二、redirect重定向

商品修改提交後,重定向到商品查詢列表。

redirect重定向特色:瀏覽器地址欄中的url會變化。修改提交的request數據沒法傳到重定向的地址。由於重定向後從新進行request(request沒法共享)

 

 

 

三、forward頁面轉發

經過forward進行頁面轉發,瀏覽器地址欄url不變,request能夠共享。

 

n  返回void

 

在controller方法形參上能夠定義request和response,使用request或response指定響應結果:

一、使用request轉向頁面,以下:

request.getRequestDispatcher("頁面路徑").forward(request, response);

 

二、也能夠經過response頁面重定向:

response.sendRedirect("url")

 

三、也能夠經過response指定響應結果,例如響應json數據以下:

response.setCharacterEncoding("utf-8");

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

response.getWriter().write("json串");

參數綁定

12.1 spring參數綁定過程

從客戶端請求key/value數據,通過參數綁定,將key/value數據綁定到controller方法的形參上。

 

springmvc中,接收頁面提交的數據是經過方法形參來接收。而不是在controller類定義成員變動接收!!!!

 

 

12.2 默認支持的類型

直接在controller方法形參上定義下邊類型的對象,就可使用這些對象。在參數綁定過程當中,若是遇到下邊類型直接進行綁定。

1.2.1.1 HttpServletRequest

經過request對象獲取請求信息

1.2.1.2 HttpServletResponse

經過response處理響應信息

1.2.1.3 HttpSession

經過session對象獲得session中存放的對象

1.2.1.4 Model/ModelMap

model是一個接口,modelMap是一個接口實現 。

做用:將model數據填充到request域。

 

12.3 簡單類型

經過@RequestParam對簡單類型的參數進行綁定。

若是不使用@RequestParam,要求request傳入參數名稱和controller方法的形參名稱一致,方可綁定成功。

 

若是使用@RequestParam,不用限制request傳入參數名稱和controller方法的形參名稱一致。

 

經過required屬性指定參數是否必需要傳入,若是設置爲true,沒有傳入參數,報下邊錯誤:

 

 

 

參考教案 對其它簡單類型綁定進行測試。

12.4 pojo綁定

頁面中input的name和controller的pojo形參中的屬性名稱一致,將頁面中數據綁定到pojo。

頁面定義:

 

controller的pojo形參的定義:

 

12.5 自定義參數綁定實現日期類型綁定

對於controller形參中pojo對象,若是屬性中有日期類型,須要自定義參數綁定。

將請求日期數據串傳成 日期類型,要轉換的日期類型和pojo中日期屬性的類型保持一致。

 

因此自定義參數綁定將日期串轉成java.util.Date類型。

須要向處理器適配器中注入自定義的參數綁定組件。

 

12.5.1自定義日期類型綁定

 

12.5.2配置方式

 

 

 

springmvc和struts2的區別

一、springmvc基於方法開發的,struts2基於類開發的。

springmvc將url和controller方法映射。映射成功後springmvc生成一個Handler對象,對象中只包括了一個method。方法執行結束,形參數據銷燬。springmvc的controller開發相似service開發。

二、springmvc能夠進行單例開發,而且建議使用單例開發,struts2經過類的成員變量接收參數,沒法使用單例,只能使用多例。

三、通過實際測試,struts2速度慢,在於使用struts標籤,若是使用struts建議使用jstl。

問題

 

14.1 post亂碼

在web.xml添加post亂碼filter

在web.xml中加入:

<filter>

<filter-name>CharacterEncodingFilter</filter-name>

<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>utf-8</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>CharacterEncodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>
web.xml

以上能夠解決post請求亂碼問題。

對於get請求中文參數出現亂碼解決方法有兩個:

 

修改tomcat配置文件添加編碼與工程編碼一致,以下:

 

<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

 

另一種方法對參數進行從新編碼:

String userName new

String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

 

ISO8859-1是tomcat默認編碼,須要將tomcat編碼後的內容按utf-8編碼

 --------------------------------------------------------------------------------------------------------------------------------------------------

複習:

 

springmvc框架:

         DispatcherServlet前端控制器:接收request,進行response

         HandlerMapping處理器映射器:根據url查找Handler。(能夠經過xml配置方式,註解方式)

         HandlerAdapter處理器適配器:根據特定規則去執行Handler,編寫Handler時須要按照HandlerAdapter的要求去編寫。

         Handler處理器(後端控制器):須要程序員去編寫,經常使用註解開發方式。

                   Handler處理器執行後結果 是ModelAndView,具體開發時Handler返回方法值類型包括 :ModelAndView、String(邏輯視圖名)、void(經過在Handler形參中添加request和response,相似原始 servlet開發方式,注意:能夠經過指定response響應的結果類型實現json數據輸出)

         View resolver視圖解析器:根據邏輯視圖名生成真正的視圖(在springmvc中使用View對象表示)

         View視圖:jsp頁面,僅是數據展現,沒有業務邏輯。

 

註解開發:

         使用註解方式的處理器映射器和適配器:

         <!--註解映射器 -->

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

<!--註解適配器 -->

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

 

在實際開發,使用<mvc:annotation-driven>代替上邊處理器映射器和適配器配置。

 

@controller註解必需要加,做用標識類是一個Handler處理器。

@requestMapping註解必需要加,做用:

         一、對url和Handler的方法進行映射。

         二、能夠窄化請求映射,設置Handler的根路徑,url就是根路徑+子路徑請求方式

         三、能夠限制http請求的方法

映射成功後,springmvc框架生成一個Handler對象,對象中只包括 一個映射成功的method。

 

註解開發中參數綁定:

         將request請求過來的key/value的數據(理解一個串),經過轉換(參數綁定的一部分),將key/value串轉成形參,將轉換後的結果傳給形參(整個參數綁定過程)。

         springmvc所支持參數綁定:

                   一、默認支持不少類型,HttpServletRequest、response、session、

                            model/modelMap(將模型數據填充到request域)

                   二、支持簡單數據類型,整型、字符串、日期。。

                            只要保證request請求的參數名和形參名稱一致,自動綁定成功

                            若是request請求的參數名和形參名稱不一致,可使用@RequestParam(指定request請求的參數名),@RequestParam加在形參的前邊。

                   三、支持pojo類型

                            只要保證request請求的參數名稱和pojo中的屬性名一致,自動將request請求的參數設置到pojo的屬性中。

                  注意:形參中即有pojo類型又有簡單類型,參數綁定互不影響。

                   自定義參數綁定:

                            日期類型綁定自定義:

                                     定義的Converter<源類型,目標類型>接口實現類,好比:

                                     Converter<String,Date>表示:將請求的日期數據串轉成java中的日期類型。

                                     注意:要轉換的目標類型必定和接收的pojo中的屬性類型一致。

                                     將定義的Converter實現類注入處處理器適配器中。

                                     <mvc:annotation-driven conversion-service="conversionService">

</mvc:annotation-driven>

<!-- conversionService -->

    <bean id="conversionService"

        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

       <!-- 轉換器 -->

       <property name="converters">

           <list>

              <bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/>

           </list>

       </property>

    </bean>

 

 

springmvc和struts2區別:

springmvc面向方法開發的(更接近service接口的開發方式),struts2面向類開發。

springmvc能夠單例開發,struts2只能是多例開發。
View Code

 

 

課程安排

 

上午:

         在商品查詢和商品修改功能案例驅動下進行學習:

                   包裝類型pojo參數綁定(掌握)。

                   集合類型的參數綁定:數組、list、map..

                   商品修改添加校驗,學習springmvc提供校驗validation(使用的是hibernate校驗框架)

                   數據回顯

                   統一異常處理(掌握)

下午:

         上傳圖片

         json數據交互

         RESTful支持

         攔截器

 

包裝類型pojo參數綁定

2.1      需求

         商品查詢controller方法中實現商品查詢條件傳入。

2.2      實現方法

第一種方法:在形參中 添加HttpServletRequest request參數,經過request接收查詢條件參數。

第二種方法:在形參中讓包裝類型的pojo接收查詢條件參數。

         分析:

         頁面傳參數的特色:複雜,多樣性。條件包括 :用戶帳號、商品編號、訂單信息。。。

         若是將用戶帳號、商品編號、訂單信息等放在簡單pojo(屬性是簡單類型)中,pojo類屬性比較多,比較亂。

         建議使用包裝類型的pojo,pojo中屬性是pojo。

        

2.3      頁面參數和controller方法形參定義

 

頁面參數:

 

         商品名稱:<input name="itemsCustom.name" />

         注意:itemsCustom和包裝pojo中的屬性一致便可。

 

controller方法形參:

         public ModelAndView queryItems(HttpServletRequest request,ItemsQueryVo itemsQueryVo) throws Exception

 

        

集合類型綁定

3.1      數組綁定

3.1.1      需求

商品批量刪除,用戶在頁面選擇多個商品,批量刪除。

3.1.2      表現層實現

關鍵:將頁面選擇(多選)的商品id,傳到controller方法的形參,方法形參使用數組接收頁面請求的多個商品id。

controller方法定義:

 

頁面定義:

 

3.2      list綁定

3.2.1      需求

一般在須要批量提交數據時,將提交的數據綁定到list<pojo>中,好比:成績錄入(錄入多門課成績,批量提交),

本例子需求:批量商品修改,在頁面輸入多個商品信息,將多個商品信息提交到controller方法中。

3.2.2      表現層實現

controller方法定義:

         一、進入批量商品修改頁面(頁面樣式參考商品列表實現)

         二、批量修改商品提交

         使用List接收頁面提交的批量數據,經過包裝pojo接收,在包裝pojo中定義list<pojo>屬性

 

 

 

 

 

頁面定義:

 

 

 

3.3      map綁定

也經過在包裝pojo中定義map類型屬性。

 

在包裝類中定義Map對象,並添加get/set方法,action使用包裝對象接收。

包裝類中定義Map對象以下:

Public class QueryVo {

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

  //get/set方法..

}
View Code

頁面定義以下:

<tr>

<td>學生信息:</td>

<td>

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

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

.. .. ..

</td>

</tr>
View Code

 

Contrller方法定義以下:

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{

System.out.println(queryVo.getStudentinfo());

}
View Code

springmvc校驗

4.1      校驗理解

項目中,一般使用較可能是前端的校驗,好比頁面中js校驗。對於安全要求較高點建議在服務端進行校驗。

 

服務端校驗:

         控制層conroller:校驗頁面請求的參數的合法性。在服務端控制層conroller校驗,不區分客戶端類型(瀏覽器、手機客戶端、遠程調用)

         業務層service(使用較多):主要校驗關鍵業務參數,僅限於service接口中使用的參數。

         持久層dao:通常是不校驗的。

 

4.2      springmvc校驗需求

 

springmvc使用hibernate的校驗框架validation(和hibernate沒有任何關係)。

 

校驗思路:

         頁面提交請求的參數,請求到controller方法中,使用validation進行校驗。若是校驗出錯,將錯誤信息展現到頁面。

具體需求:

         商品修改,添加校驗(校驗商品名稱長度,生產日期的非空校驗),若是校驗出錯,在商品修改頁面顯示錯誤信息。

 

4.3      環境準備

hibernate的校驗框架validation所須要jar包:

 

4.4      配置校驗器

 

 

4.5      校驗器注入處處理器適配器中

 

4.6      在pojo中添加校驗規則

在ItemsCustom.java中添加校驗規則:

 

4.7      CustomValidationMessages.properties

在CustomValidationMessages.properties配置校驗錯誤信息:

 

4.8      捕獲校驗錯誤信息

 

//在須要校驗的pojo前邊添加@Validated,在須要校驗的pojo後邊添加BindingResult bindingResult接收校驗出錯信息

//注意:@Validated和BindingResult bindingResult是配對出現,而且形參順序是固定的(一前一後)。

4.9      在頁面顯示校驗錯誤信息

在controller中將錯誤信息傳到頁面便可。

 

頁面顯示錯誤信息:

4.10 分組校驗

4.10.1需求

在pojo中定義校驗規則,而pojo是被多個 controller所共用,當不一樣的controller方法對同一個pojo進行校驗,可是每一個controller方法須要不一樣的校驗。

 

解決方法:

定義多個校驗分組(實際上是一個java接口),分組中定義有哪些規則

每一個controller方法使用不一樣的校驗分組

4.10.2校驗分組

 

4.10.3在校驗規則中添加分組

 

4.10.4在controller方法使用指定分組的校驗

 

數據回顯

5.1      什麼數據回顯

提交後,若是出現錯誤,將剛纔提交的數據回顯到剛纔的提交頁面。

 

5.2      pojo數據回顯方法

一、springmvc默認對pojo數據進行回顯。

pojo數據傳入controller方法後,springmvc自動將pojo數據放到request域,key等於pojo類型(首字母小寫)

 

使用@ModelAttribute指定pojo回顯到頁面在request中的key

 

二、@ModelAttribute還能夠將方法的返回值傳到頁面

 

在商品查詢列表頁面,經過商品類型查詢商品信息。

在controller中定義商品類型查詢方法,最終將商品類型傳到頁面。

 

 

頁面上能夠獲得itemTypes數據。

 

三、使用最簡單方法使用model,能夠不用@ModelAttribute

 

5.3      簡單類型數據回顯

 

使用最簡單方法使用model。

model.addAttribute("id", id);

 

異常處理

6.1      異常處理思路

 

系統中異常包括兩類:預期異常和運行時異常RuntimeException,前者經過捕獲異常從而獲取異常信息,後者主要經過規範代碼開發、測試經過手段減小運行時異常的發生。

         系統的dao、service、controller出現都經過throws Exception向上拋出,最後由springmvc前端控制器交由異常處理器進行異常處理,以下圖:

 

springmvc提供全局異常處理器(一個系統只有一個異常處理器)進行統一異常處理。

6.2      自定義異常類

對不一樣的異常類型定義異常類,繼承Exception。

 

6.3      全局異常處理器

思路:

         系統遇到異常,在程序中手動拋出,dao拋給service、service給controller、controller拋給前端控制器,前端控制器調用全局異常處理器。

         全局異常處理器處理思路:

                  解析出異常類型

                  若是該 異常類型是系統 自定義的異常,直接取出異常信息,在錯誤頁面展現

                  若是該 異常類型不是系統 自定義的異常,構造一個自定義的異常類型(信息爲「未知錯誤」)

springmvc提供一個HandlerExceptionResolver接口

@Override

   public ModelAndView resolveException(HttpServletRequest request,

         HttpServletResponse response, Object handler, Exception ex) {

      //handler就是處理器適配器要執行Handler對象(只有method)

 

//    解析出異常類型

//    若是該 異常類型是系統 自定義的異常,直接取出異常信息,在錯誤頁面展現

//    String message = null;

//    if(ex instanceof CustomException){

//       message = ((CustomException)ex).getMessage();

//    }else{

////         若是該 異常類型不是系統 自定義的異常,構造一個自定義的異常類型(信息爲「未知錯誤」)

//       message="未知錯誤";

//    }

     

      //上邊代碼變爲

      CustomException customException = null;

      if(ex instanceof CustomException){

         customException = (CustomException)ex;

      }else{

         customException = new CustomException("未知錯誤");

      }

     

      //錯誤信息

      String message = customException.getMessage();

     

     

      ModelAndView modelAndView = new ModelAndView();

     

      //將錯誤信息傳到頁面

      modelAndView.addObject("message", message);

     

      //指向錯誤頁面

      modelAndView.setViewName("error");

 

     

      return modelAndView;

   }
View Code

 

 

6.4      錯誤頁面

 

6.5      在springmvc.xml配置全局異常處理器

 

6.6      異常測試

在controller、service、dao中任意一處須要手動拋出異常。

若是是程序中手動拋出的異常,在錯誤頁面中顯示自定義的異常信息,若是不是手動拋出異常說明是一個運行時異常,在錯誤頁面只顯示「未知錯誤」。

 

在商品修改的controller方法中拋出異常 .

 

 

在service接口中拋出異常:

 

 

若是與業務功能相關的異常,建議在service中拋出異常。

與業務功能沒有關係的異常,建議在controller中拋出。

 

上邊的功能,建議在service中拋出異常。

 

上傳圖片

7.1      需求

在修改商品頁面,添加上傳商品圖片功能。

7.2      springmvc中對多部件類型解析

 

在 頁面form中提交enctype="multipart/form-data"的數據時,須要springmvc對multipart類型的數據進行解析。

 

在springmvc.xml中配置multipart類型解析器。

 

7.3      加入上傳圖片的jar

上邊的解析內部使用下邊的jar進行圖片上傳。

 

7.4      建立圖片虛擬 目錄 存儲圖片

經過圖形界面配置:

 

 

也能夠直接修改tomcat的配置:

 

在conf/server.xml文件,添加虛擬 目錄 :

 

注意:在圖片虛擬目錄 中,必定將圖片目錄分級建立(提升i/o性能),通常咱們採用按日期(年、月、日)進行分級建立。

7.5      上傳圖片代碼

7.5.1      頁面

 

 

7.5.2      controller方法

修改:商品修改controller方法:

 

 

 

 

 

 

 

 

json數據交互

 

8.1      爲何要進行json數據交互

 

json數據格式在接口調用中、html頁面中較經常使用,json格式比較簡單,解析還比較方便。

好比:webservice接口,傳輸json數據.

 

8.2      springmvc進行json交互

 

 

 

一、請求json、輸出json,要求請求的是json串,因此在前端頁面中須要將請求的內容轉成json,不太方便。

 

二、請求key/value、輸出json。此方法比較經常使用。

 

8.3      環境準備

 

8.3.1      加載json轉的jar包

springmvc中使用jackson的包進行json轉換(@requestBody和@responseBody使用下邊的包進行json轉),以下:

 

 

 

8.3.2      配置json轉換器

 

在註解適配器中加入messageConverters

 

<!--註解適配器 -->

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">

       <property name="messageConverters">

       <list>

       <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>

       </list>

       </property>

    </bean>

 

注意:若是使用<mvc:annotation-driven /> 則不用定義上邊的內容。

 

 

8.4      json交互測試

 

8.4.1      輸入json串,輸出是json串

8.4.1.1             jsp頁面

使用jquery的ajax提交json串,對輸出的json結果進行解析。

 

 

 

 

 

 

 

8.4.1.2             controller

 

 

 

8.4.1.3             測試結果

 

 

8.4.2      輸入key/value,輸出是json串

 

8.4.2.1             jsp頁面

使用jquery的ajax提交key/value串,對輸出的json結果進行解析。

 

 

 

 

 

8.4.2.2             controller

 

 

 

 

8.4.2.3             測試

 

 

 

 

 

RESTful支持

 

9.1      什麼是RESTful

RESTful架構,就是目前最流行的一種互聯網軟件架構。它結構清晰、符合標準、易於理解、擴展方便,因此正獲得愈來愈多網站的採用。

 

RESTful(即Representational State Transfer的縮寫)實際上是一個開發理念,是對http的很好的詮釋。

 

 

一、對url進行規範,寫RESTful格式的url

 

非REST的url:http://...../queryItems.action?id=001&type=T01

REST的url風格:http://..../items/001

         特色:url簡潔,將參數經過url傳到服務端

二、http的方法規範

不論是刪除、添加、更新。。使用url是一致的,若是進行刪除,須要設置http的方法爲delete,同理添加。。。

 

後臺controller方法:判斷http方法,若是是delete執行刪除,若是是post執行添加。

 

三、對http的contentType規範

請求時指定contentType,要json數據,設置成json格式的type。。

 

9.2      REST的例子

9.2.1      需求

查詢商品信息,返回json數據。

 

9.2.2      controller

定義方法,進行url映射使用REST風格的url,將查詢商品信息的id傳入controller .

 

輸出json使用@ResponseBody將java對象輸出json。

 

 

 

 

@RequestMapping(value="/ itemsView/{id}"):{×××}佔位符,請求的URL能夠是「/viewItems/1」或「/viewItems/2」,經過在方法中使用@PathVariable獲取{×××}中的×××變量。

@PathVariable用於將請求URL中的模板變量映射到功能處理方法的參數上。

若是RequestMapping中表示爲"/ itemsView /{id}",id和形參名稱一致,@PathVariable不用指定名稱。

 

 

9.2.3      REST方法的前端控制器配置

 

在web.xml配置:

 

 

 

 

9.3      對靜態資源的解析

 

配置前端控制器的url-parttern中指定/,對靜態資源的解析出現問題:

 

 

 

在springmvc.xml中添加靜態資源解析方法。

 

 

 

 

攔截器

10.1 攔截定義

 

定義攔截器,實現HandlerInterceptor接口。接口中提供三個方法。

 

public class HandlerInterceptor1 implements HandlerInterceptor {

 

  

   //進入 Handler方法以前執行

   //用於身份認證、身份受權

   //好比身份認證,若是認證經過表示當前用戶沒有登錄,須要此方法攔截再也不向下執行

   @Override

   public boolean preHandle(HttpServletRequest request,

         HttpServletResponse response, Object handler) throws Exception {

     

      //return false表示攔截,不向下執行

      //return true表示放行

      return false;

   }

 

   //進入Handler方法以後,返回modelAndView以前執行

   //應用場景從modelAndView出發:將公用的模型數據(好比菜單導航)在這裏傳到視圖,也能夠在這裏統一指定視圖

   @Override

   public void postHandle(HttpServletRequest request,

         HttpServletResponse response, Object handler,

         ModelAndView modelAndView) throws Exception {

     

     

   }

 

   //執行Handler完成執行此方法

   //應用場景:統一異常處理,統一日誌處理

   @Override

   public void afterCompletion(HttpServletRequest request,

         HttpServletResponse response, Object handler, Exception ex)

         throws Exception {

     

     

   }

 

}

10.2 攔截器配置

 

 

10.2.1針對HandlerMapping配置

springmvc攔截器針對HandlerMapping進行攔截設置,若是在某個HandlerMapping中配置攔截,通過該 HandlerMapping映射成功的handler最終使用該 攔截器。

<bean

    class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">

    <property name="interceptors">

       <list>

           <ref bean="handlerInterceptor1"/>

           <ref bean="handlerInterceptor2"/>

       </list>

    </property>

</bean>

    <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>

    <bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>

通常不推薦使用。

 

10.2.2相似全局的攔截器

springmvc配置相似全局的攔截器,springmvc框架將配置的相似全局的攔截器注入到每一個HandlerMapping中。

 

10.3 攔截測試

10.3.1測試需求

測試多個攔截器各各方法執行時機。

 

 

10.3.2編寫兩個攔截

 

 

 

10.3.3兩個攔截器都放行

 

HandlerInterceptor1...preHandle

HandlerInterceptor2...preHandle

 

HandlerInterceptor2...postHandle

HandlerInterceptor1...postHandle

 

HandlerInterceptor2...afterCompletion

HandlerInterceptor1...afterCompletion

 

總結:

preHandle方法按順序執行,

postHandle和afterCompletion按攔截器配置的逆向順序執行。

 

10.3.4攔截器1放行,攔截器2不放行

HandlerInterceptor1...preHandle

HandlerInterceptor2...preHandle

HandlerInterceptor1...afterCompletion

 

總結:

攔截器1放行,攔截器2 preHandle纔會執行。

攔截器2 preHandle不放行,攔截器2 postHandle和afterCompletion不會執行。

只要有一個攔截器不放行,postHandle不會執行。

 

10.3.1攔截器1不放行,攔截器2不放行

HandlerInterceptor1...preHandle

 

攔截器1 preHandle不放行,postHandle和afterCompletion不會執行。

攔截器1 preHandle不放行,攔截器2不執行。

 

 

10.3.2小結

 

根據測試結果,對攔截器應用。

 

好比:統一日誌處理攔截器,須要該 攔截器preHandle必定要放行,且將它放在攔截器連接中第一個位置。

 

好比:登錄認證攔截器,放在攔截器連接中第一個位置。權限校驗攔截器,放在登錄認證攔截器以後。(由於登錄經過後才校驗權限)

 

10.4 攔截器應用(實現登錄認證)

 

10.4.1需求

 

一、用戶請求url

二、攔截器進行攔截校驗

         若是請求的url是公開地址(無需登錄便可訪問的url),讓放行

         若是用戶session 不存在跳轉到登錄頁面

         若是用戶session存在放行,繼續操做。

 

10.4.2登錄controller方法

 

@Controller

public class LoginController {

 

   // 登錄

   @RequestMapping("/login")

   public String login(HttpSession session, String username, String password)

         throws Exception {

 

      // 調用service進行用戶身份驗證

      // ...

 

      // 在session中保存用戶身份信息

      session.setAttribute("username", username);

      // 重定向到商品列表頁面

      return "redirect:/items/queryItems.action";

   }

 

   // 退出

   @RequestMapping("/logout")

   public String logout(HttpSession session) throws Exception {

 

      // 清除session

      session.invalidate();

 

      // 重定向到商品列表頁面

      return "redirect:/items/queryItems.action";

   }

 

}
View Code

 

 

10.4.3           登錄認證攔截實現

 

10.4.3.1        代碼實現

public class LoginInterceptor implements HandlerInterceptor {

 

  

   //進入 Handler方法以前執行

   //用於身份認證、身份受權

   //好比身份認證,若是認證經過表示當前用戶沒有登錄,須要此方法攔截再也不向下執行

   @Override

   public boolean preHandle(HttpServletRequest request,

         HttpServletResponse response, Object handler) throws Exception {

     

      //獲取請求的url

      String url = request.getRequestURI();

      //判斷url是不是公開 地址(實際使用時將公開 地址配置配置文件中)

      //這裏公開地址是登錄提交的地址

      if(url.indexOf("login.action")>=0){

         //若是進行登錄提交,放行

         return true;

      }

     

      //判斷session

      HttpSession session  = request.getSession();

      //從session中取出用戶身份信息

      String username = (String) session.getAttribute("username");

     

      if(username != null){

         //身份存在,放行

         return true;

      }

     

      //執行這裏表示用戶身份須要認證,跳轉登錄頁面

      request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);

     

      //return false表示攔截,不向下執行

      //return true表示放行

      return false;

   }
View Code

10.4.3.2        攔截器配置

 

 

 關於RequestMaping註解url的斜槓問題

1./斜槓:表明在在根路徑下

2.不帶斜槓:表明去當前的路徑下查找

案例:

當前路徑:

<a href="/user/login">帶斜槓的路徑</a>

結果:http://localhost:8080/user/login

<a href="user/login">不帶斜槓的路徑</a> 

結果:http://localhost:8080/user/user/login

相關文章
相關標籤/搜索