springBoot之配置文件的讀取以及過濾器和攔截器的使用

来源:https://www.cnblogs.com/xuwujing/archive/2018/02/28/8485832.html
-Advertisement-
Play Games

前言 在之前的學習 "springBoot" 中,成功的實現了Restful風格的基本服務。但是想將之前的工程作為一個項目來說,那些是僅僅不夠的。可能還需要獲取自定義的配置以及添加過濾器和攔截器。至於為什麼將這些寫在一起,只是因為這些比較簡單而且也會經常用到,所以乾脆就一起寫出來了。 讀取配置文件 ...


前言

在之前的學習springBoot中,成功的實現了Restful風格的基本服務。但是想將之前的工程作為一個項目來說,那些是僅僅不夠的。可能還需要獲取自定義的配置以及添加過濾器和攔截器。至於為什麼將這些寫在一起,只是因為這些比較簡單而且也會經常用到,所以乾脆就一起寫出來了。

讀取配置文件

在使用maven項目中,配置文件會放在resources根目錄下。
我們的springBoot是用Maven搭建的,所以springBoot的預設配置文件和自定義的配置文件都放在此目錄。
springBoot的 預設配置文件為 application.propertiesapplication.yml,這裡我們使用 application.properties

首先在application.properties中添加我們要讀取的數據。
springBoot支持分層結構。
例如:

web:
  pancm:
    title: SpringBoot
    description: test

註意前面的空格!

application.properties添加完之後,我們便在代碼中進行讀取。
這裡我們使用**@Value** 方式。
首先在類中添加 **@Component****@ConfigurationProperties**這兩個註解
第一個註解表示這個類是獲取配置文件,第二個註解表示從配置文件中獲取的數據轉換為對象。因為我們使用了層級結構,獲取web.pancm目錄下的參數,所以我們再加上prefix = "web.pancm"這個表示獲取這之後的數據,就避免了下麵在重覆書寫。
那麼代碼如下:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * 
* Title: MyProperties
* Description:
* 從application.properties 獲取 配置
* Version:1.0.0  
* @author pancm
* @date 2018年1月11日
 */
@Component
@ConfigurationProperties(prefix = "web.pancm")  
public class MyProperties {
    /**
     * 獲取個人標題
     * 
     */
    @Value("${title}")
    private String title;
    
    /**
     * 獲取個人描述
     */
    @Value("${description}")
    private String description;

    /** get和set略 */

}

本類中可以直接獲取該屬性,不過在外部類調用的時候,需要添加**@Autowired**

例如:

@Autowired
MyProperties myProperties;


System.out.println(myProperties.getTitle());
System.out.println(myProperties.getDescription());

上面的是獲取application.properties中的方法。
如果想自定義配置文件和屬性的話,只需再添加一個**@PropertySource**註解就可,然後添加 value屬性,指向文件路徑即可。
例如:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
 * 
* Title: MyConfig
* Description:
* 自定義配置文件 
* Version:1.0.0  
* @author pancm
* @date 2018年1月20日
 */
@Component 
@ConfigurationProperties(prefix = "myconfig") 
@PropertySource(value = "classpath:myconfig.proferties")
public class MyConfig {  
  
    @Value("${test}") 
    private String test;  
  
    public String getTest() {  
        return test;  
    }  
  
    public void setTest(String test) {  
        this.test = test;  
    }  
}

調用方法同上!

註: 之前的springBoot版本的@ConfigurationProperties註解可以使用 locations 方法來指定自定義配置文件路徑,不過在 springBoot 1.5以上的就已經不支持 location屬性,所以這裡使用的是PropertySource。

過濾器

過濾器是什麼?
簡單的來說,過濾器就是過濾的作用,在web開發中過濾一些我們指定的url。
過濾器主要做什麼?
過濾掉一些不需要的東西,例如一些錯誤的請求。
也可以修改請求和相應的內容。

過濾器的代碼實現
過濾器(filter)有三個方法,其中初始化(init)和摧毀(destroy)方法一般不會用到,主要用到的是doFilter這個方法。
而至於怎麼過濾呢?
如果過濾通過,則在doFilter執行filterChain.doFilter(request,response);該方法。

這裡我們在過濾器中設置下請求的時間, 符合就通過。否則返回錯誤信息!
代碼示例:

 class MyFilter implements Filter {
        @Override
        public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
                throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) srequest;
            //執行過濾操作...
            System.out.println("請求的url :"+request.getRequestURI());
            // 獲取系統時間
            Calendar ca = Calendar.getInstance();
            int hour = ca.get(Calendar.HOUR_OF_DAY);
            // 設置限制運行時間 
            if (0<hour && hour < 18) {
                  HttpServletResponse response = (HttpServletResponse) sresponse;
                  response.setCharacterEncoding("UTF-8");
                  response.setContentType("application/json; charset=utf-8");
                  // 消息
                  Map<String, Object> messageMap = new HashMap<>();
                  messageMap.put("status", "1");
                  messageMap.put("message", "此介面可以請求時間為:18-24點");
                  ObjectMapper objectMapper=new ObjectMapper();
                  String writeValueAsString = objectMapper.writeValueAsString(messageMap);
                  response.getWriter().write(writeValueAsString);
                return;
            }
            
            filterChain.doFilter(srequest, sresponse);
        }

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("參數初始化:"+filterConfig);
        }
        
        @Override
        public void destroy() {
            System.out.println("開始銷毀...");
        }
    }

那麼在springBoot中如何使用過濾器呢?
一般是使用Component和WebFilter 這兩個註解,但是這裡我們就直接方法調用。
在該方法中添加Bean註解,springBoot會在啟動的時候進行調用。並指定需要過濾的請求。

代碼示例:

    @Bean
    public FilterRegistrationBean testFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new MyFilter());
        //過濾掉 /getUser 和/hello 的請求
        registration.addUrlPatterns("/getUser","/hello");
        //過濾掉所有請求
//      registration.addUrlPatterns("/*");
        registration.setName("MyFilter");
        registration.setOrder(1);
        return registration;
    }

說明: registration.setOrder() 方法是設置優先順序,數值越大,優先順序越高。

攔截器

攔截器是什麼?
簡單的來說,就是一道閥門,攔截不需要的東西。
攔截器主要做什麼?
對正在運行的流程進行干預。

攔截器的代碼實現。
攔截器也主要有三個方法,其中preHandle是在請求之前就進行調用,如果該請求需要被攔截,則返回false,否則true; postHandle是在請求之後進行調用,無返回值;afterCompletion是在請求結束的時候進行調用,無返回值。

這裡我們就簡單的模擬下攔截非白名單的IP請求。
代碼示例:

class MyInterceptor implements HandlerInterceptor {
        
        @Autowired  
        private IpConfig ipconfig; 
        
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
            String ip = getIpAddr(request);
            // 獲取可以訪問系統的白名單
            String ipStr = ipconfig.getIpWhiteList();
            String[] ipArr = ipStr.split("\\|");
            List<String> ipList = Arrays.asList(ipArr);

            if (ipList.contains(ip)) {
                 System.out.println("該IP: " + ip+"通過!");
                 return true;
            } else {
                System.out.println("該IP: " + ip+"不通過!");
                  response.setCharacterEncoding("UTF-8");
                  response.setContentType("application/json; charset=utf-8");
                  // 消息
                  Map<String, Object> messageMap = new HashMap<>();
                  messageMap.put("status", "1");
                  messageMap.put("message", "您好,ip為" + ip + ",暫時沒有訪問許可權,請聯繫管理員開通訪問許可權。");
                  ObjectMapper objectMapper=new ObjectMapper();
                  String writeValueAsString = objectMapper.writeValueAsString(messageMap);
                  response.getWriter().write(writeValueAsString);
                return false;
            }
        }

        public  String getIpAddr(HttpServletRequest request) {
            String ip = request.getHeader("X-Forwarded-For");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            return ip;
        }

        @Override
        public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
            System.out.println("postHandle被調用");
        }

        @Override
        public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
            System.out.println("afterCompletion被調用");
        }
    }

依舊再啟動springBoot的時候啟動攔截器,並指定攔截的請求。

代碼示例:

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pancm.springboot_config.config.IpConfig;


@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {

    @Bean   
    public HandlerInterceptor getMyInterceptor(){
        return new MyInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // addPathPatterns 用於添加攔截規則, 這裡假設攔截 /url 後面的全部鏈接
        // excludePathPatterns 用戶排除攔截
        registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

結語

關於springBoot配置文件的獲取以及過濾器和攔截器的使用暫時就介紹到這了。如果在某些方面描述的不夠清楚或者說的不太正確,希望讀者能指出。
該項目完整的代碼我放到github上了,有興趣的可以看看。
https://github.com/xuwujing/springBoot


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 因為啟動tomcat有時候操作不當會出現8080被占用的情況 之前一直按百度經驗來,很麻煩 然而2條命令就可以解決 netstat ano|findstr 8080 說明:查看占用8080埠的進程 //pid 是10776 taskkill /pid 10776 /f 說明,運行windows自帶 ...
  • 我之前的文章已經改造了自定義MVC框架中的工具類(驗證碼,圖片上傳,圖像處理,分頁)4個類,接下來,就要改造模型類,模型類肯定要連接資料庫,由於我的Ubuntu Linux是裸裝的php(目前只編譯了一個gd擴展),所以需要編譯安裝mysql,並把它編譯成擴展,這裡,我選用5.7版本帶boost的源 ...
  • 1、什麼是類的載入 類的載入指的是將類的.class文件中的二進位數據讀入到記憶體中,將其放在運行時數據區的方法區內,然後在堆區創建一個java.lang.Class對象,用來封裝類在方法區內的數據結構。類的載入的最終產品是位於堆區中的Class對象,Class對象封裝了類在方法區內的數據結構,並向程 ...
  • 感想 該項目是目前為止,我寫過代碼量最多的項目了.....雖然清楚是沒有含金量的【跟著視頻來寫的】,但感覺自己也在進步中...... 寫的過程中,出了不少的問題.....非常多的Servlet,JSP看得眼花..... 現在,想把該項目好好梳理一下要點,於是有了這篇博文.... E R圖 該項目涉及 ...
  • Verilog_Day1 在CSDN博客上。http://blog.csdn.net/m0_38073085 第三章: 書上基本知識 每個Verilog程式包括4個主要部分:埠定義,I/O說明,內部信號聲明和功能定義。 input/output/inout都預設是wire型而不是reg型變數。 1 ...
  • 一、前言 Python 是一門高級語言,使用起來類似於自然語言,開發的時候自然十分方便快捷,原因是Python在背後為我們默默做了很多事情,其中一件就是垃圾回收,來解決記憶體管理,記憶體泄漏的問題。 記憶體泄漏:當程式不停運行,有一部分對象沒有作用,但所占記憶體沒有被釋放,伺服器記憶體隨時間越來越少,最終導致 ...
  • 首先看看一下閉合函數(closure),見如下代碼: 閉合函數可以用來實現迭代器(iterator)(迭代器用來遍歷集合,每調用一次函數,即返回集合中的下一個元素)。 例如:遍歷一個table的時候,我們經常使用如下方式。 我們可以用while遍歷集合,也可以用for,並且用for會容易很多,下麵看 ...
  • 哈希表(Hash table,也叫散列表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放記錄的數組叫做散列表。 順序搜索以及二叉樹搜索樹中,元素存儲位置和元素各關鍵碼之間沒有對應 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...