OneCoder的第一反映就是實現一個filter,配置可訪問的IP規則,通過正則進行匹配。通過的正常進入系統,不通過的redirect到指定歡迎頁面。
整個代碼沒什麼難度,核心就是一個IP規則的檢驗功能。考慮到配置的簡便性,即一般熟悉192.168.1.*和192.168.2.1-23,這種全部匹配和範圍匹配的配置方式。OneCoder決定採用拆分解析匹配的方式。規則之間用分號;分隔,是或的關係。代碼實現如下:
| 代碼如下 |
複製代碼 |
/** * IP規則正則處理工具類 * * @author OneCoder * @date 2014年10月23日 下午1:23:09 */ public class IPRegexUtil {
/**
* 校正所給IP是否滿足給定規則
*
* @author li_hongzhe @nhn.com
* @date 2014年10月23日 下午1:38:37
* @param ipStr
* 待校正IP
* @param ipPattern
* IP匹配規則。支援 * 匹配所有和 - 匹配範圍。用分號分隔 <br>
* 例如:10.34.163.*;10.34.162.1 -128
* @return
*/
public static boolean validateIP(String ipStr, String ipPattern) {
if ( ipStr == null || ipPattern == null) {
return false;
}
String[] patternList = ipPattern.split( ";");
for (String pattern : patternList) {
if ( passValidate(ipStr, pattern)) {
return true;
}
}
return false;
}
private static boolean passValidate(String ipStr, String pattern) {
String[] ipStrArr = ipStr.split( ".");
String[] patternArr = pattern.split( ".");
if ( ipStrArr. length != 4 || patternArr. length != 4) {
return false;
}
int end = ipStrArr. length;
if ( patternArr[3].contains( "-")) {
end = 3;
String[] rangeArr = patternArr[3].split( "-");
int from = Integer.valueOf(rangeArr[0]).intValue();
int to = Integer.valueOf(rangeArr[1]).intValue();
int value = Integer.valueOf(ipStrArr[3]).intValue();
if ( value < from || value > to) {
return false;
}
}
for ( int i = 0; i < end; i++) {
if ( patternArr[ i].equals( "*")) {
continue;
}
if (!patternArr[ i].equalsIgnoreCase( ipStrArr[ i])) {
return false;
}
}
return true;
}
} |
實現過濾器如下:
| 代碼如下 |
複製代碼 |
import java.io.IOException;
import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
/** * IP地址過濾器,如果IP地址在過濾的範圍內,則允許訪問。<br> * 如果沒在範圍內,則跳轉到禁止頁面。 * * @author OneCoder * @date 2014年10月24日 上午9:54:33 */ public class IPFilter implements Filter {
private String ipPattern;
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
String ip = request.getRemoteHost();
String reqUrl = ((HttpServletRequest) request).getRequestURI();
if (reqUrl.contains("forbidden")) {
filterChain.doFilter(request, response);
return;
}
if (IPRegexUtil.validateIP(ip, ipPattern)) {
filterChain.doFilter(request, response);
} else {
((HttpServletResponse) response).sendRedirect("/shurnim/forbidden");
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.ipPattern = filterConfig.getInitParameter("ip-pattern");
}
public String getIpPattern() {
return ipPattern;
}
public void setIpPattern(String ipPattern) {
this.ipPattern = ipPattern;
}
} |
web.xml配置如下: <pre class="brush:xml"> <filter> <filter-name >IPFilter </filter-name > <filter-class >com.coderli.web.filter.ip.IPFilter </filter-class > <init-param > <param-name >ip-pattern</ param-name> <param-value >10.34.163.169;10.34.163.1-254 </param-value > </init-param > </filter > <filter-mapping > <filter-name >IPFilter </filter-name > <url-pattern >/* </url-pattern > </filter-mapping > </pre>
代碼似乎沒什麼好解釋的,目前看似乎是滿足了需求了。