springMVC:HandlerInterceptor攔截器的使用


1.使用背景

Web項目中需要判斷http接口用戶Post上來的數據是否合法,如果不合法要另做處理,用戶Post上來的數據是Json形式的,我們用了@RequestBody標記自動將json形式的提交封裝為一個Model對象,這樣一來,我們就不能判斷在自動封裝過程中是否出現了異常,此時便想起了springMVC中的interceptor,用於處理請求之前,做一些處理,我們可以取消@RequestBody標記,然后在interceptor中取得請求體,檢查是否符合json要求,即是不是一個valid interceptor,但是這里出現了一個問題:
httpServletRequest的請求內容,只能被讀取一次,在interceptor中讀取了的話,在controller中便不能讀取了,解決方式是,讀取到的請求內容存起來,然后在controller中直接使用。
這里用到了interceptor的一種,HandlerInterceptor,可以寫一個小例子來記一下是怎么使用的!

2.HandlerInterceptor概述

在SpringMVC 中定義一個Interceptor是比較非常簡單,主要有兩種方式:
第一種:實現HandlerInterceptor 接口,或者是繼承實現了HandlerInterceptor 接口的類,例如HandlerInterceptorAdapter;
第二種:實現Spring的WebRequestInterceptor接口,或者是繼承實現了WebRequestInterceptor的類。
現在主要結合一個例子說一下第一種方式:實現HandlerInterceptor接口。
HandlerInterceptor接口主要定義了三個方法:
1. boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handle)方法:該方法將在請求處理之前進行調用,只有該方法返回true,才會繼續執行后續的Interceptor和Controller,當返回值為true 時就會繼續調用下一個Interceptor的preHandle 方法,如果已經是最后一個Interceptor的時候就會是調用當前請求的Controller方法;
2.void postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法:該方法將在請求處理之后,DispatcherServlet進行視圖返回渲染之前進行調用,可以在這個方法中對Controller 處理之后的ModelAndView 對象進行操作。
3.void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法:該方法也是需要當前對應的Interceptor的preHandle方法的返回值為true時才會執行,該方法將在整個請求結束之后,也就是在DispatcherServlet 渲染了對應的視圖之后執行。用於進行資源清理。

3.簡單的一個例子:

1.xml需要配置:兩種配置方式(對所有的請求記性攔截,對特定的請求進行攔截)

<mvc:interceptors>
        <!--對所有的請求記性攔截-->
        <!--<beans:bean class="com.sunp.common.interceptor.Myinterceptor"/>-->
        <!--對特定的請求進行攔截-->
        <mvc:interceptor>
            <mapping path="/kfc/brands/brand1/*"/>
            <beans:bean class="com.sunp.common.interceptor.Myinterceptor"/>
        </mvc:interceptor>
</mvc:interceptors>

2.interceptors類

package com.sunp.common.interceptor;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mkyong.common.model.Shop;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.BufferedReader;
import java.io.IOException;

/** * Created by hzsunpeng on 2016/6/14. */
public class Myinterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("preHandle run!");
        return true;
    }

    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

        System.out.println("postHandle run!");
    }
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

        System.out.println("afterCompletion run!");
    }
}

3.controller類(為了使用@Controller @PathVariable @ResponseBody注釋等需要加一些配置文件,這里不再列出)

package com.sunp.common.controller;
import com.sunp.common.model.Shop;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

/** * Created by hzsunpeng on 2016/6/7. */
@Controller
@RequestMapping("/kfc/brands")
public class JSONController {

    @RequestMapping(value = "/brand1/{name}",method = RequestMethod.GET)
    public @ResponseBody Shop getShopInJSON(@PathVariable String name)
    {
        Shop sp = new Shop();
        sp.setName(name);
        sp.setStaffName(new String[]{"Staffname1","Staffname2"});
        System
        return sp;
    }
    //測試用
    @RequestMapping(value = "/json",method = RequestMethod.POST)
    public String index(HttpServletRequest request)
    {
        return "index";
    }
}

4.model Shop類

package com.sunp.common.model;

import java.io.Serializable;

/** * Created by hzsunpeng on 2016/6/7. */
public class Shop implements Serializable {
    private String name;
    private String[] staffName;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String[] getStaffName() {
        return staffName;
    }

    public void setStaffName(String[] staffName) {
        this.staffName = staffName;
    }

}

運行結果:

這里寫圖片描述
控制台輸出:
這里寫圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM