1. 程式人生 > >SpringMVC學習記錄七——sjon數據交互和攔截器

SpringMVC學習記錄七——sjon數據交互和攔截器

1.4 技術 nta app image 登陸 Go 文件 rest風格

21 json數據交互

21.1 為什麽要進行json數據交互

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

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

21.2 springmvc進行json交互

技術分享圖片

1、請求json、輸出json,要求請求的是json串,所以在前端頁面中需要將請求的內容轉成json,不太方便。

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

21.3 環境準備

21.3.1 加載json轉的jar包

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

技術分享圖片

21.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 /> 則不用定義上邊的內容。

21.4 json交互測試

21.4.1 輸入json串,輸出是json串

21.4.1.1 jsp頁面

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

技術分享圖片

21.4.1.2 controller

技術分享圖片

21.4.1.3 測試結果

技術分享圖片

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

21.4.2.1 jsp頁面

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

技術分享圖片

21.4.2.2 controller

技術分享圖片

21.4.2.3 測試

技術分享圖片

22 RESTful支持

22.1 什麽是RESTful

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

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

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

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

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

特點:url簡潔,將參數通過url傳到服務端

2、http的方法規範

不管是刪除、添加、更新。。使用url是一致的,如果進行刪除,需要設置http的方法為delete,同理添加。。。

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

3、對http的contentType規範

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

22.2 REST的例子

2.2.1 需求

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

2.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不用指定名稱。

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

在web.xml配置:

技術分享圖片

22.3 對靜態資源的解析

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

技術分享圖片

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

技術分享圖片

23 攔截器

23.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 {
   }

}

23.2 攔截器配置

23.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"/>

一般不推薦使用。

23.2.2 類似全局的攔截器

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

技術分享圖片

23.3 攔截測試

23.3.1 測試需求

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

23.3.2 編寫兩個攔截

技術分享圖片

23.3.3 兩個攔截器都放行

HandlerInterceptor1...preHandle

HandlerInterceptor2...preHandle

HandlerInterceptor2...postHandle

HandlerInterceptor1...postHandle

HandlerInterceptor2...afterCompletion

HandlerInterceptor1...afterCompletion

總結:

preHandle方法按順序執行,

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

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

HandlerInterceptor1...preHandle

HandlerInterceptor2...preHandle

HandlerInterceptor1...afterCompletion

總結:

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

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

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

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

HandlerInterceptor1...preHandle

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

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

23.3.2 小結

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

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

比如:登陸認證攔截器,放在攔截器鏈接中第一個位置。權限校驗攔截器,放在登陸認證攔截器之後。(因為登陸通過後才校驗權限)

23.4 攔截器應用(實現登陸認證)

23.4.1 需求

1、用戶請求url

2、攔截器進行攔截校驗

如果請求的url是公開地址(無需登陸即可訪問的url),讓放行

如果用戶session 不存在跳轉到登陸頁面

如果用戶session存在放行,繼續操作。

23.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";

   }
}

23.4.3 登陸認證攔截實現

23.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;

   }

23.4.3.2 攔截器配置

技術分享圖片

SpringMVC學習記錄七——sjon數據交互和攔截器