/* * Created on 2004-12-2 *wap应用对请求地址的限制 filter,也可以用于其他 * */ package org.nightkids.filter.wap;
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Properties;
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; import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
/** * @author weidewang */ public class BlockNotMobileAccess implements Filter { private Log _logger = LogFactory.getLog(this.getClass());
private static final String MODE_SESSION_IP = "BlockNotMobileAccessModeSession";
private static FilterConfig filterConfig;
private HttpServletRequest request;
private HttpServletResponse response;
private HttpSession session;
private static Properties gatewayProperties = new Properties();
private static List gatewayList = new ArrayList();
public void init(FilterConfig fconfig) throws ServletException { filterConfig = fconfig; initGatewayList(filterConfig); }
/** * 加载网关列表 * * @param fc */ private void initGatewayList(FilterConfig fc) { String properRealPath = fc.getServletContext().getRealPath(fc.getInitParameter("gateway-properties")); try { gatewayProperties.load(new FileInputStream(properRealPath)); _logger.debug("已经读取全国网关列表配置文件: " + properRealPath); Enumeration elems = gatewayProperties.elements(); while (elems.hasMoreElements()) { String gateway = (String) elems.nextElement(); // 如果 gateway 里面没有 - 的话 就是一个单一的 IP ,直接加到 list 中,否则 获取 - 左边到 . 的,- 右边到 结束的 字符串,转为数字,然后遍历一下为单一的 ip 加入 list 中 int indexOf = gateway.indexOf("-"); if (indexOf == -1) {// 如果是单一ip,直接加到 list 中 gatewayList.add(gateway); _logger.debug("添加一个网关: " + gateway); } else { // 否则是一个 ip 组,现在只解析最后一段 ip 组 // 首先获取到 - 左边 第一个 . 到开始的字符串 int indexLeftPoint = gateway.lastIndexOf(".", indexOf) + 1;// 获取 - 左边到 . 的 字符串 String prefixStr = gateway.substring(0, indexLeftPoint);// 获取到 - 左边 第一个 . 到开始的字符串 String leftStr = gateway.substring(indexLeftPoint, indexOf).trim();// 得到左边的字符串 String rightStr = gateway.substring(indexOf + 1).trim();// 获取 - 右边到结束的 字符串 // 已经得到字符串之后,就要遍历一下分割成单独的 ip 加入到 list 中 int leftInt = Integer.parseInt(leftStr); int rightInt = Integer.parseInt(rightStr); for (int i = leftInt; i <= rightInt; i++) { String grGateway = prefixStr + i; gatewayList.add(grGateway); _logger.debug("添加一个网关: " + grGateway); } } } _logger.debug("共添加了 " + gatewayList.size() + " 个网关."); } catch (NullPointerException e) { _logger.debug("读取全国网关列表配置文件错误:(没有设置 gateway-properties) " + e); } catch (FileNotFoundException e) { _logger.debug("读取全国网关列表配置文件错误:(找不到配置文件):" + properRealPath + " " + e); } catch (IOException e) { _logger.debug("读取全国网关列表配置文件错误:(IO错误):" + properRealPath + " " + e); } }
/** * */
public void doFilter(ServletRequest _servletRequest, ServletResponse _servletResponse, FilterChain filterChain) throws IOException, ServletException { boolean isActive = false; boolean allowAccess = false; request = (HttpServletRequest) _servletRequest; response = (HttpServletResponse) _servletResponse; session = request.getSession(true); if (null != filterConfig.getInitParameter("active")) { if ("true".equalsIgnoreCase(filterConfig.getInitParameter("active")) || "yes".equalsIgnoreCase(filterConfig.getInitParameter("active"))) { isActive = true; _logger.debug("激活 " + this.getClass().getName()); } }
if (isActive) { allowAccess = doProcess(request); } else { allowAccess = true; }
if (!allowAccess) { error(); return; } filterChain.doFilter(_servletRequest, _servletResponse); }
/** * @param req * @return true 通过,false 不能通过 */ private boolean doProcess(HttpServletRequest req) { String userAgent = null; boolean bRe = true; /** * 设置调试模式 */ String modeName = filterConfig.getInitParameter("mode-name"); String modeValue = filterConfig.getInitParameter("mode-value"); if (modeName != null && modeValue != null) { if (request.getParameter(modeName) != null && modeValue.equals(request.getParameter(modeName)) || modeValue.equals(session.getAttribute(MODE_SESSION_IP))) { session.setAttribute(MODE_SESSION_IP, modeValue); return bRe; } } /* * 首先判断浏览器类型 */ String[] blockUserAgent = { "Mozilla", "ApacheBench" }; userAgent = req.getHeader("User-Agent").toLowerCase();
int indexOf = userAgent.indexOf("/"); if (indexOf == -1) { indexOf = userAgent.indexOf("*"); if (indexOf == -1) { indexOf = userAgent.length(); } } userAgent = userAgent.substring(0, indexOf); for (int i = 0; i < blockUserAgent.length; i++) { String str = blockUserAgent[i].toLowerCase(); if (str.equalsIgnoreCase(userAgent)) { return false; } } String getRemoteAddr = request.getRemoteAddr(); if (!gatewayList.contains(getRemoteAddr)) {// 如果网关列表里没有访问者ip 的话,不允许访问 return false; } return bRe; }
public void destroy() {
}
private void error() throws IOException { response.setContentType(filterConfig.getInitParameter("content-type")); StringBuffer sb = new StringBuffer(); String errorMessage = "对不起,请使用手机访问."; if (filterConfig.getInitParameter("ERROR_MESSAGE") != null) { errorMessage = filterConfig.getInitParameter("ERROR_MESSAGE"); } sb.append("<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\"><wml><card><p align=\"center\">" + errorMessage + "<br/><a href=\"http://wap.monternet.com/\">梦网首页</a></p></card></wml>"); Writer out = response.getWriter(); out.write(sb.toString()); out.close(); }
}

|