Spring Interceptor

Spring 的 Interceptor 機制。

在用spring寫網頁程式時,我們常常會需要寫一些檢核機制。

而這些檢核機制通常會在進入controller做該次request要求的動作前執行。

eg,檢查此次request, 該使用者是否要求了他不該使用的功能(使用者知道你伺服器的功能url,直接在瀏覽器上key url,不是從你網頁的功能點入)。

又或者,進入controller之前需先檢查使用者是否有登入,在有登入的狀態下,才允許放行使用者使用他有權限的controller。

以下就簡介 Interceptor 的純 Java config 用法。

1.撰寫 Interceptoer 類別。

就如同他的名字一樣。Interceptor,攔截器,要攔截什麼樣的資訊?怎樣攔截?什麼時候進行攔截,這必須由開發者自行定義。

寫一個 MipInterceptor 類別繼承 HandlerInterceptorAdapter 類別。

分別實作preHandle(request發生前執行)、postHandle(request發生後執行)、afterCompletion(最後執行)並在每個步驟印出log。

public class TkuInterceptor extends HandlerInterceptorAdapter  {
	
	@Autowired AppException appException;
	
	private static final long serialVersionUID = 1L;
	private static Logger logger = Logger.getLogger(TkuInterceptor.class);
	
	@Override
	public boolean preHandle(HttpServletRequest req, 
								HttpServletResponse resp, 
								Object handler) throws Exception { // 覆寫preHandle方法,在請求發生前執行
		
		logger.info("request url: " + req.getRequestURI());
		logger.info("preHandle...");
		
		logger.info("appException.getMessage()="+appException.getMessage());
		
		return true;
	}
	@Override
	public void postHandle(HttpServletRequest request, 
							HttpServletResponse response, 
							Object handler, 
							ModelAndView modelAndView) throws Exception { // 覆寫postHandle方法,在請求發生後執行
		
		logger.info("postHandle...");
	}
	@Override
	public void afterCompletion(HttpServletRequest request, 
									HttpServletResponse response, 
									Object handler, 
									Exception ex) throws Exception {//最後執行
		
		logger.info("afterCompletion...");

	}  

} 

2.實作 WebMvcConfigurerAdapter,設定自己所創造的 Interceptor 類別。

@ComponentScan("com.spring.tku")
public class WebConfig extends WebMvcConfigurerAdapter {
	

	@Bean
	public ViewResolver viewResolver() {
		InternalResourceViewResolver bean = new InternalResourceViewResolver();

		/**
		 * we’ve registered a ViewResolver bean that will return .jsp views from the /WEB-INF/view directory
		 */

		//輸入http://localhost:8080/spring_ryuichi/sample時, 會自動回傳WEB-INF/view下的sample.jsp
		bean.setPrefix("/WEB-INF/view/");
		bean.setSuffix(".jsp");

		return bean;
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/static/**").addResourceLocations("/static/");//可直接在url上access的資源
		registry.addResourceHandler("/*").addResourceLocations("/");//增加此行使其可以讀webcontent下的靜態資源

		//registry.addResourceHandler("/view/**").addResourceLocations("/WEB-INF/view/");//增加此行使其可以讀WEB-INF/view下的東西
	}

	@Bean
	// 配置攔截器
	public TkuInterceptor tkuInterceptor() {
		return new TkuInterceptor();
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) { // 覆寫addInterceptors方法,註冊攔截器
		registry.addInterceptor(tkuInterceptor());
	}

}

3.寫一個Controller執行。

@Controller
@ComponentScan("com.spring.tku")
public class TkuController {

	private static Logger logger = Logger.getLogger(TkuController.class);

	@RequestMapping("/sample")
	public String sample() {

		logger.info("進入Sample Controller");
		return "sample";
	}
}

4.執行結果。