wap应用对请求地址的限制 filter,也可以用于其他

本文介绍了一种Servlet过滤器,用于阻止非移动设备访问特定的Web应用,确保只有来自移动设备的请求才能通过。

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

欧姆龙FINS(工厂集成网络系统)协议是专为该公司自动化设备间数据交互而设计的网络通信标准。该协议构建于TCP/IP基础之上,允许用户借助常规网络接口执行远程监控、程序编写及信息传输任务。本文档所附的“欧ronFins.zip”压缩包提供了基于C与C++语言开发的FINS协议实现代码库,旨在协助开发人员便捷地建立与欧姆龙可编程逻辑控制器的通信连接。 FINS协议的消息框架由指令头部、地址字段、操作代码及数据区段构成。指令头部用于声明消息类别与长度信息;地址字段明确目标设备所处的网络位置与节点标识;操作代码定义了具体的通信行为,例如数据读取、写入或控制器指令执行;数据区段则承载实际交互的信息内容。 在采用C或C++语言实施FINS协议时,需重点关注以下技术环节: 1. **网络参数设置**:建立与欧姆龙可编程逻辑控制器的通信前,必须获取控制器的网络地址、子网划分参数及路由网关地址,这些配置信息通常记载于设备技术手册或系统设置界面。 2. **通信链路建立**:通过套接字编程技术创建TCP连接至控制器。该过程涉及初始化套接字实例、绑定本地通信端口,并向控制器网络地址发起连接请求。 3. **协议报文构建**:依据操作代码与目标功能构造符合规范的FINS协议数据单元。例如执行输入寄存器读取操作时,需准确配置对应的操作代码与存储器地址参数。 4. **数据格式转换**:协议通信过程中需进行二进制数据的编码与解码处理,包括将控制器的位状态信息或数值参数转换为字节序列进行传输,并在接收端执行逆向解析。 5. **异常状况处理**:完善应对通信过程中可能出现的各类异常情况,包括连接建立失败、响应超时及错误状态码返回等问题的处理机制。 6. **数据传输管理**:运用数据发送与接收函数完成信息交换。需注意FINS协议可能涉及数据包的分割传输与重组机制,因单个协议报文可能被拆分为多个TCP数据段进行传送。 7. **响应信息解析**:接收到控制器返回的数据后,需对FINS响应报文进行结构化解析,以确认操作执行状态并提取有效返回数据。 在代码资源包中,通常包含以下组成部分:展示连接建立与数据读写操作的示范程序;实现协议报文构建、传输接收及解析功能的源代码文件;说明库函数调用方式与接口规范的指导文档;用于验证功能完整性的测试案例。开发人员可通过研究这些材料掌握如何将FINS协议集成至实际项目中,从而实现与欧姆龙可编程逻辑控制器的高效可靠通信。在工程实践中,还需综合考虑网络环境稳定性、通信速率优化及故障恢复机制等要素,以确保整个控制系统的持续可靠运行。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值