1. 程式人生 > >Spring MVC根據執行引數新增filter代理(啟動時動態新增filter和listener)

Spring MVC根據執行引數新增filter代理(啟動時動態新增filter和listener)

在工作中涉及到開發環境中需要跳過SSO,一開始在Maven中使用profiles在構建的時候加入SSO的filter,而開發環境中的web.xml不配置SSO。因為使用的時候需要在maven構建命令中加入引數,和測試和運營溝通的不便利,決定另尋他法。

這種方法通過實現spring mvc的WebApplicationInitializer介面,在這裡面讀取執行引數,利用這個引數決定是不是不要新增SSO filter(預設新增)。

實現目標:在執行引數中定義 -Dapp.env=dev,啟動的時候能夠 載入config/properties目錄內的env_dev.properties檔案,並根據檔案內的配置項sso.pass=true跳過SSO的filter新增。

1、定義屬性


/**
	 * 配置檔案字首
	 */
	private static final String SETTINGS_FILE_PREFIX = "env_";
	
	/**
	 * 執行環境引數key
	 */
	private static final String ENVIROMENT_KEY = "app.env";
	
	/**
	 * 是否跳過SSO設定key
	 */
	private static final String KEY_IS_PASS_SSO = "sso.pass"; 
	
	/**
	 * 是否跳過SSO
	 */
	private static final Boolean IS_PASS_SSO;

2、獲取執行引數,在static塊中執行

	
String env = System.getProperty(ENVIROMENT_KEY);
Properties prop = new Properties();
		if(env!=null && env.trim().length()>0){
			try {
				InputStream inputStream = ApplicationInitializer.class.getClassLoader().getResourceAsStream("config/properties/"+SETTINGS_FILE_PREFIX + env.trim()+".properties");
				prop.load(inputStream);
			} catch (IOException e) {
				logger.error("引數檔案{}讀取出錯",SETTINGS_FILE_PREFIX+env+".properties");
			}  
		}
		//SSO
		String passSSOValue = prop.getProperty(KEY_IS_PASS_SSO);
		if(StringUtils.isEmpty(passSSOValue)){
			IS_PASS_SSO = false;
		}else{
			IS_PASS_SSO = Boolean.parseBoolean(passSSOValue);
		}

3、實現介面的onStartup方法


//單點登入設定
    	if(IS_PASS_SSO){
    		logger.info("設定為跳過SSO");
    	}else{
    		try {
    			//新增監聽器
    			servletContext.addListener("org.springframework.security.web.session.HttpSessionEventPublisher");
    			
    			//新增filter
    			Dynamic addFilter = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
    			
    			addFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
			} catch (Exception e) {
				logger.error("新增SSO filter出現錯誤");
				throw e;
			}
    	}

完畢。

以下是全部程式碼:

import java.io.IOException;
import java.io.InputStream;
import java.util.EnumSet;
import java.util.Properties;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration.Dynamic;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.filter.DelegatingFilterProxy;

public class ApplicationInitializer implements WebApplicationInitializer {
	
	private final static Logger logger = LoggerFactory.getLogger(ApplicationInitializer.class);
	
	/**
	 * 配置檔案字首
	 */
	private static final String SETTINGS_FILE_PREFIX = "env_";
	
	/**
	 * 執行環境引數key
	 */
	private static final String ENVIROMENT_KEY = "app.env";
	
	/**
	 * 是否跳過SSO設定key
	 */
	private static final String KEY_IS_PASS_SSO = "sso.pass"; 
	
	/**
	 * 是否跳過SSO
	 */
	private static final Boolean IS_PASS_SSO;
	
	
	/**
	 * 根據配置檔案初始化引數
	 * 讀取的配置檔案為"env_"+環境引數+"."
	 */
	static{
		String env = System.getProperty(ENVIROMENT_KEY);
		Properties prop = new Properties();
		if(env!=null && env.trim().length()>0){
			try {
				InputStream inputStream = ApplicationInitializer.class.getClassLoader().getResourceAsStream("config/properties/"+SETTINGS_FILE_PREFIX + env.trim()+".properties");
				prop.load(inputStream);
			} catch (IOException e) {
				logger.error("引數檔案{}讀取出錯",SETTINGS_FILE_PREFIX+env+".properties");
			}  
		}
		//SSO
		String passSSOValue = prop.getProperty(KEY_IS_PASS_SSO);
		if(StringUtils.isEmpty(passSSOValue)){
			IS_PASS_SSO = false;
		}else{
			IS_PASS_SSO = Boolean.parseBoolean(passSSOValue);
		}
	}
	
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
    	
    	//單點登入設定
    	if(IS_PASS_SSO){
    		logger.info("設定為跳過SSO");
    	}else{
    		try {
    			//新增監聽器
    			servletContext.addListener("org.springframework.security.web.session.HttpSessionEventPublisher");
    			
    			//新增filter
    			Dynamic addFilter = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
    			
    			addFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
			} catch (Exception e) {
				logger.error("新增SSO filter出現錯誤");
				throw e;
			}
    	}
    }
}



相關推薦

Spring MVC根據執行引數新增filter代理啟動動態新增filterlistener

在工作中涉及到開發環境中需要跳過SSO,一開始在Maven中使用profiles在構建的時候加入SSO的filter,而開發環境中的web.xml不配置SSO。因為使用的時候需要在maven構建命令中加入引數,和測試和運營溝通的不便利,決定另尋他法。 這種方法通過實現spr

spring mvc tomcat 執行緒池的坑

1 配置tomcat  執行緒池設定為20個執行緒處理請求 2 後臺框架是springmvc   3 模擬10個請求 4  發現tomcat執行緒池沒一個幹活的 5 幹活的是spring自己建立的執行緒 為什麼springmvc

詳解Spring MVC執行流程

Spring MVC的核心在於其執行流程,這是使用Spring MVC框架的基礎,下面看一段程式碼: //註解@Controller表示他是一個控制器 @Controller("myController") //表明當請求的URI在/my下的時候才有該控制器響應 @RequestMappin

spring MVC 時間轉date(四)--mybatis傳入起始時間,但這傳入時間的引數不是bean裡的解法

jsp裡:   <td style="width:150px;height:10%;color:#000;padding-left: 10px;padding-bottom: 10px;">                             <la

[讀書筆記] Spring MVC中的引數繫結

Spring通過ConversionService介面對Controller中的引數進行繫結。 對具體的型別轉換,Spring定義了三個介面:Converter,GenericConverter,ConverterFactory。 Spring還定義了ConverterRe

Spring MVC 中的引數繫結

引數繫結入口 @RequestMapping(value = "/saveUser", method = {RequestMethod.POST }) public ResponseEntity<ResultData> post

Spring MVC之請求引數路徑變數

請求引數和路徑引數都可以用於傳送值給伺服器。二者都是URL的一部分。 一、請求引數   請求引數採用key = value形式,並用“&”分隔。例如下面的URL帶有名為name和pwd的請求引數。   localhost:9090/showU

Spring MVC Controller執行緒安全性問題

Spring MVC預設是單例模式,Controller、Service、Dao都是單例所以在使用不當存在一定的安全隱患。Controller單例模式的好處在與: 1. 提高效能,不用每次建立Con

Spring MVC 中的基於註解的 Controller轉載

med beans 沒有 對象引用 諸多 請求 icon .so 它的 終於來到了基於註解的 Spring MVC 了。之前我們所講到的 handler,需要根據 url 並通過 HandlerMapping 來映射出相應的 handler 並調用相應的

Spring MVC 常用Jar包官方下載地址官方Maven倉庫

term apache water arch release details libs sdn glib http://blog.csdn.net/u014749862/article/details/48894409 spring:http://maven.sprin

Spring mvc服務端消息推送SSE技術

javascrip tro jstl var 通信 主動 form imp title SSE技術是基於單工通信模式,只是單純的客戶端向服務端發送請求,服務端不會主動發送給客戶端。服務端采取的策略是抓住這個請求不放,等數據更新的時候才返回給客戶端,當客戶端接收到消息後,再向

Spring實戰——如何執行第一章的程式碼如何生成一個可執行的jar包

手動建立一個目錄kni,進入kni建立一個build.gradle檔案,內容如下: apply plugin: 'java' jar { baseName = 'knight' version = '0.0.1-SNAPSHOT' } repositories

【unity】NavMesh 執行動態新增 OffMeshLink 線。

遊戲裡 有一些場景內的傳送陣,  做尋路時, 之前要美術預埋 OffMeshLink線。 但策劃會換位置, 兩邊就不一致了。 想著 OffMeshLink好像可以動態加。  網上沒有相關資料,  試了一下是可以的。 編輯器下可以動態加, 程式裡也基本可以

Spring MVC 4.2.4 文件實踐--- 菜鳥從零開始學系列

1 前言 本文後續將開啟一個系列,順著作者學習 Spring MVC 文件的腳步,從零開始搭建一個基於 Spring MVC 的 web 應用,並且根據 Spring MVC 的文件內容,選擇現有的,用的比較多的,實現性比較好的特性,基於其程式碼實現,來講解其原始碼和背後的原理,這既是對自己在 Spring

spring mvc+mybatis返回map型別資料為空值欄位不顯示問題

<select id="getArticleById" resultType="map"> select * from article t </select> 當返回結果resultType為map時,

spring AOP 代理靜態與動態+使用cglib實現

一、沒有代理模式 缺點: 1、工作量特別大,如果專案中有多個類,多個方法,則要修改多次。 2、違背了設計原則:開閉原則(OCP),對擴充套件開放,對修改關閉,而為了增加功能把每個方法都修改了,也不便於維護。 3、違背了設計原則:單一職責(SRP),每個方法除了要完成自己本身的功能,還要計算耗時、延時;

Spring MVC+mybatis 專案入門:旅遊網 dispatcher與controller與Spring MVC

MVC模式         既然在使用Spring MVC,那麼當然要了解什麼是MVC模式。 MVC全名是Model View Controller,是模型(model)-檢視(view)-控制器(controller)的縮寫,一種軟體設計典範,用一種業務邏輯、資料、介

Spring MVC+mybatis 專案入門:旅遊網使用者註冊——控制反轉以及Hibernate Validator資料驗證

註冊原理         其實很簡單,前端頁面顯示一個表單,然後由dispatcher傳遞到controller,controller呼叫資料庫驗證,如果ok,那就寫入資料庫,同時返回註冊成功的檢視,否則可以返回註冊頁,或者是到一個錯誤頁。 依賴注入與控制反轉    

Spring MVC 更靈活的控制 json 返回自定義過濾欄位

前言: 我們要做什麼?         我們要在springmvc的控制層,在返回字串的時候,動態改變一下到底要返回哪些字串,比如我們要返回實體Article,他裡面有4個屬性我們只想返回其中的3個

Spring MVC 中“攔截器”處理模型資料 @ModelAttribute

在這裡強烈建議看看我之前寫的幾篇關於SpringMVC的部落格,都是串通的。 @ModelAttribute這個是SpringMVC中處理模型資料的最難也是最重要的點。相當於以前Struct的攔截器。