Filter内部转发实现

package com.funinbook.filter;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;

import com.funinbook.service.IApiService;
import com.funinbook.util.HttpUtils;

/**
 * ClassName: ApiFilter</br> Function: Filter内部转发实现</br>
 * 
 * @author zeping.li</br>
 * @version 1.0</br>
 * @Date 2016-9-22 下午1:49:28</br>
 */
@WebFilter(urlPatterns = { "/app/*" })
public class AppFilter implements Filter
{
	
	/**
	 * 接口对外发布地址及内部servlet服务地址映射map 用此方式,可以将接口外部地址定义为 REST风格,并隐藏我们服务实际地址 key: 对外发布接口地址最后一个斜线地址(包括斜线)
	 * val: 内部servlet实际服务地址
	 */
	private Map<String, String> urlMap = new ConcurrentHashMap<String, String>();
	
	@Override
	public void init(FilterConfig arg0) throws ServletException
	{
	
		// 用户注册
		urlMap.put("/regist", "/regist");
		// 用户登录
		urlMap.put("/login", "/login");
		
		
	}
	
	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
	        FilterChain chain) throws IOException, ServletException
	{
	
		// 设置字符集
		req.setCharacterEncoding("UTF-8");
		res.setCharacterEncoding("UTF-8");
		
		// 获取http对象
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		
		// 封装接收到的参数
		Map<String, Object> params = new ConcurrentHashMap<String, Object>();
		
		// 从request中取出所有GET方式传送过来的参数(对于接口来说存在很多安全因素,并且不易被处理)
		// params.putAll(request.getParameterMap());
		
		// 请求开始时间(纳秒 = 1ms/1000/1000 )
		long l1 = System.nanoTime();
		params.put(IApiService.MAP_PARAM_START_TIME, l1);
		
		// 获取请求的ip
		params.put(IApiService.MAP_PARAM_IP, getIpAddr(request));
		
		// 放置一个唯一序列号(mongodb objectId格式)
		params.put(IApiService.MAP_PARAM_REQ_SERIAL_NO, String.valueOf(new ObjectId()));
		
		// 封装数据
		request.setAttribute(IApiService.REQUEST_PARAMS, params);
		
		// 判断接口地址路径
		String uri = request.getRequestURI();
		
		// 我们现在定义:项目发布为ROOT项目,所有请求均是/app/开头,后面为具体的接口请求地址
		String reqPath = uri.replace("/app", "");
		
		// 获取系统服务地址映射
		if (StringUtils.isBlank(urlMap.get(reqPath.replace("/app", "")))) {
			// 错误请求地址
			response.sendError(404);
			return;
		}
		
		// 跳转到内部实际服务地址
		request.getRequestDispatcher(urlMap.get(reqPath.replace("/app", ""))).forward(request, response);
		return;
	}
	
	@Override
	public void destroy()
	{
	
	}
	
	/**
	 * 获取request对象的IP地址
	 * 
	 * @param request
	 * @return
	 */
	public String getIpAddr(HttpServletRequest request)
	{
	
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)
		        || ip.equals("127.0.0.1")) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)
		        || ip.equals("127.0.0.1")) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)
		        || ip.equals("127.0.0.1")) {
			ip = request.getRemoteAddr();
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)
		        || ip.equals("127.0.0.1")) {
			ip = request.getHeader("http_client_ip");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)
		        || ip.equals("127.0.0.1")) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = "127.0.0.1";
		}
		// 判断获取到的ip是不是一个字符串
		if (ip.contains(",")) {
			// 去除空格,并拆分
			ip = ip.replaceAll(" ", "");
			String[] ips = ip.split(",");
			// 循环每一个进行处理,过滤内网地址
			for (String temp : ips) {
				long num = HttpUtils.ipToLong(temp);
				if (num >= 167772160l && num <= 184549375l) {
					// 10.0.0.0 - 10.255.255.255
					continue;
				} else if (num >= 2886729728l && num <= 2887778303l) {
					// 172.16.0.0 - 172.31.255.255
					continue;
				} else if (num >= 3232235520l && num <= 3232301055l) {
					// 192.168.0.0 - 192.168.255.255
					continue;
				} else if (num == 2130706433l) {
					// 127.0.0.1
					continue;
				}
				ip = temp;
				break;
			}
		}
		return ip;
	}
	
	
}

 

转载于:https://my.oschina.net/zepinglidoc/blog/750879

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值