最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java Web如何限制訪問的IP的兩種方法

 更新時間:2020年10月23日 10:59:04   作者:lytao123  
這篇文章主要介紹了詳解Java Web如何限制訪問的IP的兩種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前一陣子因為在做項目時碰到了這個功能,現(xiàn)在好好總結(jié)一下,至于為什么要限制IP訪問,我就不多說了。然后百度了一下,現(xiàn)在主要有兩種方式去限制IP訪問,第一種是最簡單的方便的,第二種是通過過濾器來限制訪問。下面我簡單介紹一下第一種方式,著重介紹第二種。

第一種方式(Tomcat配置項配置允許或限制IP訪問)

這種是最簡單的快捷的,主要就涉及Tomcat的server.xml配置。

第一步:找到server.xml文件在哪,在Tomcat的目錄下的conf文件夾下。
第二步:打開server.xml文件,找到Host節(jié)點,在其中加上:

<Valve className="org.apache.catalina.valves.RemoteAddrValve" 
	allow="127.0.0.1" 
	deny=""/>

其中:
className:表示java類名,必須是
org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve;
allow:表示允許的IP,支持模糊(* )、正則,多個用,隔開;
deny:表示限制的IP,支持模糊(
*)、正則;多個用,隔開。
注:如果是限制某一個站點(網(wǎng)站)則在Context節(jié)點中添加。
第三步:重啟Tomcat。

第二種方式(通過Filter過濾器來配置允許或限制IP訪問)

(1)代碼實現(xiàn)的思路
  通過增加配置文件properties,將允許訪問的IP按一定規(guī)則配置進去;接下來再對配置文件(這里尚且叫做配置文件)進行加載;然后再對配置文件的格式要求通過正則進行校驗;其次將配置的IP通過一個集合進行收集,可收集單條IP或一個IP的正則,因為我們這里需要用到模糊;最后對訪問者的IP與集合中的進行比對,比對通過則正常訪問,否則。反之。
  在配置文件中提供三種最常見的IP配置方式:

單個IP地址的配置,多個之間用逗號或分好隔開;
例如:192.168.1.50;127.0.0.1;IP地址區(qū)間方式的配置,多個區(qū)間用逗號或分好隔開;
例如:172.20.32.10-172.20.32.11;172.20.32.88-172.20.32.89通配符,多個用逗號或分好隔開。
例如:172.20.30.*

(2)具體實現(xiàn)代碼
第一步:編寫配置文件/Test/src/com/config/ipConfig.properties;

#單個IP地址的配置,多個之間用逗號或分好隔開
allowIP=192.168.1.50;127.0.0.1;

#IP地址區(qū)間方式的配置,多個區(qū)間用逗號或分好隔開
allowIPRange=172.20.32.10-172.20.32.11;172.20.32.88-172.20.32.89

#通配符,多個用逗號或分好隔開
allowIPWildcard=172.20.30.*;

第二步:新建Java類實現(xiàn)Filter;
第三步:在web.xml中配置過濾器;

<!-- 過濾器 -->
 
 <!-- ip過濾器,過濾所有請求地址 -->
 <filter>
 	<filter-name>IPFilter</filter-name>
 	<filter-class>com.filter.IpFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>IPFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 
 <!-- 結(jié)束過濾器 -->

第四步:我們需要聲明一個全局變量List來存放允許訪問的IP或正則式;

//聲明的代碼:
//用來存放允許訪問的ip
private List<String> allowList = new ArrayList<String>();

第五步:需要對配置文件進行加載;在方法init中

//加載的代碼:
//將文件轉(zhuǎn)化成流
InputStream inputStream = IpFilter.class.getResourceAsStream("../config/ipConfig.properties");
		
Properties properties = new Properties();
		
//通過Properties對象實例加載流
properties.load(inputStream);
		
//獲取三種配置方式的值
String allowIP = properties.getProperty("allowIP");
String allowIPRange = properties.getProperty("allowIPRange");
String allowIPWildcard = properties.getProperty("allowIPWildcard");

第六步:校驗配置文件格式;在方法init中

//校驗的部分代碼
//如果為空,說明用戶沒添加該項,不做處理
if(allow == null || "".equals(allow.trim())) {
	return true;
} else {
	//在最后面沒有,或;的給添上
	if(!allow.endsWith(";") && !allow.endsWith(",")) {
		allow += ";";
	}
	//如果匹配,則返回true
	if(pattern.matcher(allow).matches()) {
		return true;
	}
}

第七步:獲取每種配置方式的IP;在方法init中

/*
 * 將每一種配置方法放置到allowList中
 */
//將第一種配置方法放到allowList中
if(null != allowIP && !"".equals(allowIP.trim())) {
	String[] allowIPs = allowIP.split(",|;");
	for(String ip : allowIPs) {
		allowList.add(ip);
	}
}

//將第二種配置方法放到allowList中
if(null != allowIPRange && 
		!"".equals(allowIPRange.trim())) {
	//先進行每一段的分割
	String[] allowIPRanges = allowIPRange.split(",|;");
	
	if(allowIPRanges.length > 0) {
		//對每一段進行遍歷
		for(String allowRanges : allowIPRanges) {
			if(allowRanges != null && 
					!"".equals(allowRanges.trim())) {
				//對該段的ip進行解析
				String[] ips = allowRanges.split("-");
				if(ips.length > 0 && ips.length < 3) {
					String from = ips[0];//得到該段的起始ip
					String to = ips[1]; //得到該段的結(jié)束ip
					
					//獲取該ip段地址的前三段,因為起始和結(jié)束的ip的前三段一樣
					String share = from.substring(0, from.lastIndexOf(".")+1);
					
					//獲取該ip段的起始ip的最后一段
					int start = Integer.parseInt(from.substring(from.lastIndexOf(".")+1, 
														from.length()));
					//獲取該ip段的結(jié)束ip的最后一段
					int end = Integer.parseInt(to.substring(to.lastIndexOf(".")+1, 
														to.length()));
					for(int i=start; i<=end; i++) {
						String ip = share + String.valueOf(i);
						allowList.add(ip);
					}
				} else {
					throw new RuntimeException("配置文件有錯,請檢查!");
				}
			}
			
		}
	}
	
}

//將第三種配置方法放到allowList中
if(allowIPWildcard != null && 
		!"".equals(allowIPWildcard)) {
	//獲取每個含通配符的ip地址
	String[] allowIPWildcards = allowIPWildcard.split(",|;");
	
	if(allowIPWildcards.length > 0) {
		for(String ip : allowIPWildcards) {
			if(ip.indexOf("*") != -1) {
				//對*進行替換
				ip = ip.replaceAll("\\*", "(25[0-5]|2[0-4]\\\\d|[0-1]\\\\d{2}|[1-9]?\\\\d)");
				
				allowList.add(ip);
			} else {
				throw new RuntimeException("配置文件有錯,請檢查!");
			}
			
		}
		
	}
}

第八步:IP比對,成功匹配就正常訪問,反之則跳到錯誤頁面。這個因為是在用戶訪問時才進行的步驟,需要在doFilter方法的編寫。

//獲取訪問的IP地址
String remoteAddr = request.getRemoteAddr();
//System.out.println("===============" + remoteAddr);
//如果allowList為空,則認為沒做限制,不為空則檢查是否限制
if(allowList.size() == 0 || allowList == null) {
	filterChain.doFilter(request, response);
} else {
	Boolean flag = false; //訪問標志,默認為false,限制訪問
	//進行逐個檢查
	for(String regex : allowList){
		if(remoteAddr.matches(regex)){
			//ip沒被限制,正常訪問
			filterChain.doFilter(request, response);
			flag = true; //置為true,表示不限制訪問
			break;
		}
	}
	if(!flag) {
		//ip被限制,跳到指定頁面
		request.getRequestDispatcher("WEB-INF/success/error.jsp").forward(request, response);
	}
}

附成功后截圖:

訪問成功

訪問失敗

附完整代碼:

package com.filter;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 過濾器
 * 功能:對訪問者IP進行限制訪問
 * @author ouyang
 * @serial 20180728
 * @version 1.0
 */
public class IpFilter implements Filter{

	//用來存放允許訪問的ip
	private List<String> allowList = new ArrayList<String>();
	
	@Override
	public void init(FilterConfig arg0) throws ServletException {
		try {
			System.out.println("過濾器IpFilter開始初始化,功能:IP訪問限制");
			initConfig();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
			throws IOException, ServletException {
		
		//獲取訪問的IP地址
		String remoteAddr = request.getRemoteAddr();
		//System.out.println("===============" + remoteAddr);
		//如果allowList為空,則認為沒做限制,不為空則檢查是否限制
		if(allowList.size() == 0 || allowList == null) {
			filterChain.doFilter(request, response);
		} else {
			Boolean flag = false; //訪問標志,默認為false,限制訪問
			//進行逐個檢查
			for(String regex : allowList){
				if(remoteAddr.matches(regex)){
					//ip沒被限制,正常訪問
					filterChain.doFilter(request, response);
					flag = true; //置為true,表示不限制訪問
					break;
				}
			}
			if(!flag) {
				//ip被限制,跳到指定頁面
				request.getRequestDispatcher("WEB-INF/success/error.jsp").forward(request, response);
			}
		}
		
	}
	
	@Override
	public void destroy() {
		System.out.println("過濾器IpFilter結(jié)束。");
	}

	/**
	 * 對配置文件進行初始化并校驗
	 * @author 歐陽
	 * @serialData 20180728
	 * @throws IOException
	 */
	public void initConfig() throws IOException {
		//將文件轉(zhuǎn)化成流
		InputStream inputStream = IpFilter.class.getResourceAsStream("../config/ipConfig.properties");
		
		Properties properties = new Properties();
		
		//通過Properties對象實例加載流
		properties.load(inputStream);
		
		//獲取三種配置方式的值
		String allowIP = properties.getProperty("allowIP");
		String allowIPRange = properties.getProperty("allowIPRange");
		String allowIPWildcard = properties.getProperty("allowIPWildcard");
		
		//校驗,校驗失敗后拋出異常
		if(!validate(allowIP, allowIPRange, allowIPWildcard)) {
			throw new RuntimeException("配置文件有錯,請檢查!");
		}
		
		/*
		 * 將每一種配置方法放置到allowList中
		 */
		//將第一種配置方法放到allowList中
		if(null != allowIP && !"".equals(allowIP.trim())) {
			String[] allowIPs = allowIP.split(",|;");
			for(String ip : allowIPs) {
				allowList.add(ip);
			}
		}
		
		//將第二種配置方法放到allowList中
		if(null != allowIPRange && 
				!"".equals(allowIPRange.trim())) {
			//先進行每一段的分割
			String[] allowIPRanges = allowIPRange.split(",|;");
			
			if(allowIPRanges.length > 0) {
				//對每一段進行遍歷
				for(String allowRanges : allowIPRanges) {
					if(allowRanges != null && 
							!"".equals(allowRanges.trim())) {
						//對該段的ip進行解析
						String[] ips = allowRanges.split("-");
						if(ips.length > 0 && ips.length < 3) {
							String from = ips[0];//得到該段的起始ip
							String to = ips[1]; //得到該段的結(jié)束ip
							
							//獲取該ip段地址的前三段,因為起始和結(jié)束的ip的前三段一樣
							String share = from.substring(0, from.lastIndexOf(".")+1);
							
							//獲取該ip段的起始ip的最后一段
							int start = Integer.parseInt(from.substring(from.lastIndexOf(".")+1, 
																from.length()));
							//獲取該ip段的結(jié)束ip的最后一段
							int end = Integer.parseInt(to.substring(to.lastIndexOf(".")+1, 
																to.length()));
							for(int i=start; i<=end; i++) {
								String ip = share + String.valueOf(i);
								allowList.add(ip);
							}
						} else {
							throw new RuntimeException("配置文件有錯,請檢查!");
						}
					}
					
				}
			}
			
		}
		
		//將第三種配置方法放到allowList中
		if(allowIPWildcard != null && 
				!"".equals(allowIPWildcard)) {
			//獲取每個含通配符的ip地址
			String[] allowIPWildcards = allowIPWildcard.split(",|;");
			
			if(allowIPWildcards.length > 0) {
				for(String ip : allowIPWildcards) {
					if(ip.indexOf("*") != -1) {
						//對*進行替換
						ip = ip.replaceAll("\\*", "(25[0-5]|2[0-4]\\\\d|[0-1]\\\\d{2}|[1-9]?\\\\d)");
						
						allowList.add(ip);
					} else {
						throw new RuntimeException("配置文件有錯,請檢查!");
					}
					
				}
				
			}
		}
		
		//打印輸出allowList
		for(String str : allowList) {
			System.out.println(str);
		}
		
	}
	
	/**
	 * 對配置文件進行校驗
	 * @author ouyang
	 * @serialData 20180728
	 * @param allowIP
	 * @param allowIPRange
	 * @param allowIPWildcard
	 * @return
	 */
	public Boolean validate(String allowIP, String allowIPRange, String allowIPWildcard) {
		Boolean result = false;
		//IP地址每一段的正則
		String regx = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
		//整個ip的正則
		String ipRegx = regx + "\\." + regx + "\\."+ regx + "\\." + regx;
		
		//對第一種方式進行校驗
		Pattern pattern = Pattern.compile("("+ipRegx+")|("+ipRegx+"(,|;))*");
		if(this.isNullorMatches(allowIP, pattern)){
			result = true; //匹配成功
		} else {
			result = false;
		}
		
		//對第二種方式進行校驗
		pattern = Pattern.compile("("+ipRegx+")\\-("+ipRegx+")|" + 
						"(("+ipRegx+")\\-("+ipRegx+")(,|;))*");
		if(this.isNullorMatches(allowIPRange, pattern)){
			result = true; //匹配成功
		} else {
			result = false;
		}
		
		//對第三種方式進行校驗
		pattern = Pattern.compile("("+regx+"\\."+ regx+"\\."+regx+"\\."+ "\\*)|" + 
						"("+regx+"\\."+regx+"\\."+regx+"\\."+ "\\*(,|;))*");
		if(this.isNullorMatches(allowIPWildcard, pattern)){
			result = true; //匹配成功
		} else {
			result = false;
		}
		
		return result;
	}
	
	/**
	 * 進行正則匹配
	 * @author 歐陽
	 * @serialData 20180728
	 * @param allow
	 * @return
	 */
	public Boolean isNullorMatches(String allow, Pattern pattern) {
		//如果為空,說明用戶沒添加該項,不做處理
		if(allow == null || "".equals(allow.trim())) {
			return true;
		} else {
			//在最后面沒有,或;的給添上
			if(!allow.endsWith(";") && !allow.endsWith(",")) {
				allow += ";";
			}
			//如果匹配,則返回true
			if(pattern.matcher(allow).matches()) {
				return true;
			}
		}
		
		return false;
	}
}

到此這篇關(guān)于詳解Java Web如何限制訪問的IP的兩種方法的文章就介紹到這了,更多相關(guān)Java 限制訪問的IP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 里氏代換原則_動力節(jié)點Java學院整理

    里氏代換原則_動力節(jié)點Java學院整理

    這篇文章主要為大家詳細介紹了里氏代換原則的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Java實戰(zhàn)之王者榮耀的英雄是怎么產(chǎn)生的?

    Java實戰(zhàn)之王者榮耀的英雄是怎么產(chǎn)生的?

    這篇文章主要介紹了Java實戰(zhàn)之王者榮耀的英雄是怎么產(chǎn)生的?文中有非常詳細的代碼示例,對正在學習java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Java中單例模式的7種寫法

    Java中單例模式的7種寫法

    這篇文章主要介紹了Java中單例模式的7種寫法,本文分別給出每種方式的實現(xiàn)代碼,需要的朋友可以參考下
    2015-05-05
  • 詳解如何在SpringBoot中使用WebMvc

    詳解如何在SpringBoot中使用WebMvc

    Spring?Boot?是一個快速、簡單的開發(fā)框架,在?Spring?Boot?中,我們可以使用?WebMvc?來構(gòu)建?Web?應(yīng)用程序,所以本文就來講講如何在SpringBoot中使用WebMvc吧
    2023-06-06
  • 新手入門Jvm--jvm概覽

    新手入門Jvm--jvm概覽

    JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用于計算設(shè)備的規(guī)范,它是一個虛構(gòu)出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現(xiàn)的
    2021-06-06
  • 基于ComponentScan注解的掃描范圍及源碼解析

    基于ComponentScan注解的掃描范圍及源碼解析

    這篇文章主要介紹了基于ComponentScan注解的掃描范圍及源碼解析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • java Scanner類的使用示例代碼

    java Scanner類的使用示例代碼

    這篇文章主要介紹了java Scanner類的使用,Scanner類還可以任意地對字符串和基本類型(如int和double)的數(shù)據(jù)進行分析。借助于Scanner,可以針對任何要處理的文本內(nèi)容編寫自定義的語法分析器,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • 詳解Spring Boot 添加JSP支持

    詳解Spring Boot 添加JSP支持

    本篇文章主要介紹了詳解Spring Boot 添加JSP支持,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Java計算代碼段執(zhí)行時間的詳細過程

    Java計算代碼段執(zhí)行時間的詳細過程

    java里計算代碼段執(zhí)行時間可以有兩種方法,一種是毫秒級別的計算,另一種是更精確的納秒級別的計算,這篇文章主要介紹了java計算代碼段執(zhí)行時間,需要的朋友可以參考下
    2023-02-02
  • MyBatis中resultType屬性的使用

    MyBatis中resultType屬性的使用

    這篇文章主要介紹了MyBatis中resultType屬性的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-09-09

最新評論

策勒县| 叙永县| 宁国市| 读书| 平昌县| 上饶县| 修水县| 东兰县| 台南市| 绥棱县| 宁远县| 防城港市| 沙雅县| 定边县| 巴楚县| 青浦区| 辽阳县| 康乐县| 阿鲁科尔沁旗| 清水县| 肇东市| 方城县| 油尖旺区| 临朐县| 松原市| 河源市| 石首市| 长顺县| 苗栗市| 饶河县| 仙桃市| 麟游县| 辽阳市| 济源市| 南雄市| 西昌市| 张家口市| 颍上县| 沂源县| 含山县| 武夷山市|