一。攔截器的作用
攔截器提供了一種機制,在訪問action前後進行一些操作,因爲攔截器的這個特性,那麼我們就可以利用攔截器做一些事情,比如監控訪問人數,攔截一些非法請求,記錄訪問日誌,身份驗證之類的
二。.構建攔截器
2.1 創建攔截器
1.創建類實現HandlerInterceptor
接口
2.HandlerInterceptor有三種攔截方式
-
`preHandle` :在訪問controller調用之前
-
`postHandle` :請求訪問controller之後,渲染視圖之前
-
`afterCompletion` :請求訪問controller之後,渲染視圖之後
3.返回值爲boolean
- true: 請求在經過驗證校驗以後,是OK的,是可以放行的
- false: 請求被攔截,被駁回,驗證出現問題
代碼示例:
package com.imooc.interceptor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
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.IOException;
import java.io.OutputStream;
import static com.imooc.controller.BaseController.REDIS_USER_TOKEN;
public class UserTokenInterceptor implements HandlerInterceptor {
/**
* 攔截請求,在訪問controller調用之前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("進入攔截器");
/**
* false: 請求被攔截,被駁回,驗證出現問題
* true: 請求在經過驗證校驗以後,是OK的,是可以放行的
*/
return true;
}
/**
* 請求訪問controller之後,渲染視圖之前
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 請求訪問controller之後,渲染視圖之後
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2.2 註冊攔截器
1.創建類實現WebMvcConfigurer
接口
2.註冊創建的攔截器
@Bean
public UserTokenInterceptor userTokenInterceptor() {
return new UserTokenInterceptor();
}
3.重寫addInterceptors
添加監聽的路徑
addPathPatterns
添加監聽的路徑地址excludePathPatterns
排除一些路徑
代碼示例:
package com.imooc.config;
import com.imooc.interceptor.UserTokenInterceptor;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public UserTokenInterceptor userTokenInterceptor() {
return new UserTokenInterceptor();
}
/**
* 註冊攔截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userTokenInterceptor())
.addPathPatterns("/hello")
.addPathPatterns("/shopcart/add")
.addPathPatterns("/shopcart/del")
.addPathPatterns("/address/list")
.addPathPatterns("/address/add")
.addPathPatterns("/address/update")
.addPathPatterns("/address/setDefalut")
.addPathPatterns("/address/delete")
.addPathPatterns("/orders/*")
.addPathPatterns("/center/*")
.addPathPatterns("/userInfo/*")
.addPathPatterns("/myorders/*")
.addPathPatterns("/mycomments/*")
.excludePathPatterns("/myorders/deliver")
.excludePathPatterns("/orders/notifyMerchantOrderPaid");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
三。攔截器錯誤信息返回前端
因爲攔截器返回的結果是布爾類型的,所有不能直接返回信息,那怎麼辦呢,我們可以利用output輸出流來寫入response中,這樣前臺就可以獲取到了。
代碼如下:
public void returnErrorResponse(HttpServletResponse response,
String result) {
OutputStream out = null;
try {
response.setCharacterEncoding("utf-8");
response.setContentType("text/json");
out = response.getOutputStream();
out.write(result.getBytes("utf-8"));
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}