wap應用對請求地址的限制 filter,也可以用於其他

/*
 * 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();
 }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章