SpringMVC:通过拦截器实现IP黑名单

以前没有遇到这个需要,后面在网上找了很久,参考了很多文档给出的方案。

1.配置拦截器

这里使用全局拦截:

 <mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.nps.base.filter.LoginInterceptor"></bean></mvc:interceptor></mvc:interceptors>

拦截器LoginInterceptor代码:

package com.nps.base.filter;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.nps.utils.IpInterceptUtils;/*** 验证拦截器* @author HUANG*/
public class LoginInterceptor implements HandlerInterceptor {
private final static Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);@Override
public void afterCompletion(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2, Exception arg3)throws Exception {}@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2, ModelAndView arg3) throws Exception {}@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {String ip = getIpAddress(request);if (IpInterceptUtils.chickIpBreak(ip)) {return false;}Map<String, String> map = getParameterMap(request);// 获取url中的所有参数String servletUrl = request.getServletPath();// servlet地址String url = getRealUrl(servletUrl, map);if (url.indexOf("/user/") == 0) {Object user = request.getSession().getAttribute("User");if (user == null) {// System.out.println("尚未登录,调到登录页面");response.sendRedirect(request.getContextPath() + "/loginOut.do");return false;}}return true;
}/*** 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址;* * @param request* @return* @throws IOException*/
public final static String getIpAddress(HttpServletRequest request)throws IOException {// 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址String ip = request.getHeader("X-Forwarded-For");// if (logger.isInfoEnabled()) {// logger.info("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip="// + ip);// }if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {if (ip == null || ip.length() == 0|| "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");// if (logger.isInfoEnabled()) {// logger.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip="// + ip);// }}if (ip == null || ip.length() == 0|| "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");// if (logger.isInfoEnabled()) {// logger.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip="// + ip);// }}if (ip == null || ip.length() == 0|| "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_CLIENT_IP");// if (logger.isInfoEnabled()) {// logger.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip="// + ip);// }}if (ip == null || ip.length() == 0|| "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");// if (logger.isInfoEnabled()) {// logger.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip="// + ip);// }}if (ip == null || ip.length() == 0|| "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();// if (logger.isInfoEnabled()) {// logger.info("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip="// + ip);// }}} else if (ip.length() > 15) {String[] ips = ip.split(",");for (int index = 0; index < ips.length; index++) {String strIp = (String) ips[index];if (!("unknown".equalsIgnoreCase(strIp))) {ip = strIp;break;}}}return ip;
}/*** 根据request获取所有的参数集* * @param request* @return*/
protected Map<String, String> getParameterMap(HttpServletRequest request) {Enumeration<String> names = request.getParameterNames();String name;Map<String, String> map = new HashMap<String, String>();while (names.hasMoreElements()) {name = names.nextElement();map.put(name, request.getParameter(name).trim().replaceAll("'", ""));}return map;
}/*** 获取url* * @param uri* @param params* @return*/
String getRealUrl(String uri, Map<String, String> params) {StringBuffer sb = new StringBuffer(uri);if (params != null) {int i = 0;for (String key : params.keySet()) {i++;if (i == 1) {sb.append("?" + key + "=" + params.get(key));} else {sb.append("&" + key + "=" + params.get(key));}}}return sb.toString();
}
}

2.校验IP工具

public class IpInterceptUtils {
private static String date ;
private static PropertiesUtil p=null;/**** 校验IP是否加入黑名单* @param ip* @return true 是在黑名单 * @throws IOException*/public static boolean chickIpBreak(String ip) throws IOException{if(p == null){p = new PropertiesUtil("conf/ip-black.properties");}else{String str = new SimpleDateFormat("MMddHHmmss").format(new Date());  str=str.substring(0,9);if(date==null || !date.equals(str)){  date = str; p = new PropertiesUtil("conf/ip-black.properties");}}Enumeration en = p.getProps().propertyNames();while (en.hasMoreElements()) {String key = (String) en.nextElement();if(key.equals(ip)){return true;}}return false;}
}

3.配置文件读取类

PropertiesUtil

package com.nps.base.model;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;import org.springframework.stereotype.Component;/*** 读取Properties综合类,默认绑定到classpath下的config.properties文件。* @author */
@Component("PropertiesUtil")
public class PropertiesUtil {//配置文件的路径private String configPath=null;/*** 配置文件对象*/private Properties props=null;/*** 默认构造函数,用于sh运行,自动找到classpath下的config.properties。*/public PropertiesUtil() throws IOException{if(props==null){InputStream in = PropertiesUtil.class.getClassLoader().getResourceAsStream("conf/application.properties");props = new Properties();props.load(in);//关闭资源in.close();}}/*** 默认构造函数,用于sh运行,自动找到classpath下的config.properties。*/public PropertiesUtil(String path) throws IOException{if(props==null){InputStream in = PropertiesUtil.class.getClassLoader().getResourceAsStream(path);props = new Properties();props.load(in);//关闭资源in.close();}}/*** 根据key值读取配置的值* Jun 26, 2010 9:15:43 PM* @author 朱志杰* @param key key值* @return key 键对应的值 * @throws IOException */public String readValue(String key) throws IOException {return  props.getProperty(key);}/*** 读取properties的全部信息* @throws FileNotFoundException 配置文件没有找到* @throws IOException 关闭资源文件,或者加载配置文件错误* */public Map<String,String> readAllProperties() throws FileNotFoundException,IOException  {//保存所有的键值Map<String,String> map=new HashMap<String,String>();Enumeration en = props.propertyNames();while (en.hasMoreElements()) {String key = (String) en.nextElement();String Property = props.getProperty(key);map.put(key, Property);}return map;}/*** 设置某个key的值,并保存至文件。* @param key key值* @return key 键对应的值 * @throws IOException */public void setValue(String key,String value) throws IOException {Properties prop = new Properties();InputStream fis = new FileInputStream(this.configPath);// 从输入流中读取属性列表(键和元素对)prop.load(fis);// 调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。// 强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。OutputStream fos = new FileOutputStream(this.configPath);prop.setProperty(key, value);// 以适合使用 load 方法加载到 Properties 表中的格式,// 将此 Properties 表中的属性列表(键和元素对)写入输出流prop.store(fos,"last update");//关闭文件fis.close();fos.close();}/*** @return the props*/public Properties getProps() {return props;}public static void main(String[] args) {PropertiesUtil p;try {p = new PropertiesUtil("conf/ip-black.properties");Enumeration en = p.props.propertyNames();String str="";while (en.hasMoreElements()) {String key = (String) en.nextElement();System.out.println(key);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

附上黑名单IP文件格式

ip-black.properties 配置文件

45.119.99.35
103.253.2.165
157.65.166.51
202.57.55.242
119.82.252.122
140.227.53.126
140.227.211.20
140.227.208.20
116.253.84.183

附加

之所以使用配置文件读取黑名单IP是为了加快数据读取速度,因为每次访问服务器都会被校验,使用数据库会加大数据库的压力,这个方法中每10秒就会重新读取配置文件缓存其实更好,不使用缓存主要是为了,因为放在缓存中还要写对应的操作方法,如果有什么更好的方法欢迎大家讨论

JAVA通过拦截器实现IP黑名单相关推荐

  1. Springboot拦截器实现IP黑名单

    Springboot拦截器实现IP黑名单 一·业务场景和需要实现的功能 以redis作为IP存储地址实现.业务场景:针对秒杀活动或者常规电商业务场景等,防止恶意脚本不停的刷接口.实现功能:写一个拦截器 ...

  2. Java EE拦截器

    历史 我认为重要的是要看一下Java EE中的Interceptor的发展,因为它是从EJB特定的项目开始的,后来又演变成一个单独的规范,现在可供其他Java EE规范扩展,这一事实很简单. 版本1. ...

  3. [JAVA EE] 拦截器

    拦截器 ◼ 拦截器(Interceptor)主要用于拦截用户请求并作相应的处理. ◼ 基于Java的反射机制,属于面向切面编程(AOP)的一种运用. ◼ 应用场景:验证用户登录状态.权限验证.记录系统 ...

  4. java面试 拦截器问题_面试必问:给我说一下Spring MVC拦截器的原理?

    拦截器是每个Web框架必备的功能,也是个老生常谈的主题了.本文将分析SpringMVC的拦截器功能是如何设计的,让读者了解该功能设计的原理. 重要接口及类介绍1. HandlerExecutionCh ...

  5. Java filter拦截器的使用

    1.web.xml配置 <!-- 验证是否登录 拦截功能 --><filter><filter-name>isLogin</filter-name>&l ...

  6. java spring 拦截器_Spring MVC拦截器(Interceptor)的配置及使用

    在开发一个网站时可能有这样的需求:某些页面只希望几个特定的用户浏览.对于这样的访问权限控制,应该如何实现呢?拦截器就可以实现上述需求.在 Struts 2 框架中,拦截器是其重要的组成部分,Sprin ...

  7. Java 注解 拦截器

    场景描述:现在需要对部分Controller或者Controller里面的服务方法进行权限拦截.如果存在我们自定义的注解,通过自定义注解提取所需的权限值,然后对比session中的权限判断当前用户是否 ...

  8. java中拦截器 过滤器 监听器都有什么区别

    过滤器,是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts2的action进行业务逻辑,比如过滤掉非法u ...

  9. Java中拦截器和过滤器的声明用途和区别

    过滤器: 1.基于Servlet框架 2.Oracle公司的任何Java Web框架都可以用 3.可以拦截任何资源,包括 .jsp .java .html等等 拦截器: 1.基于SpringMvc框架 ...

最新文章

  1. 毕业 2 年成为首席架构师,他是怎么做到的?
  2. oracle备库重启后失去连接,关于dataguard备库宕机后重启后的问题
  3. [Elasticsearch2.x] 多字段搜索 (三) - multi_match查询和多数字段 译
  4. 设计模式之_Iterator_02
  5. centos 下载文件很慢_【已解决】Mac中从远程CentOS服务器中加速下载大文件
  6. 【转载】特殊宏://{{AFX_MSG、//{{AFX_VIRTUAL、//{{AFX_MSG_MAP、//{{AFX_DATA_INIT
  7. git github配置
  8. iBATIS事务处理
  9. [Java] 蓝桥杯ADV-214 算法提高 3-3求圆面积表面积体积
  10. Linux 命令(97)—— info 命令
  11. BZOJ 1211: [HNOI2004]树的计数 purfer序列
  12. mysql查询连续次数_Mysql如何查询连续的时间次数
  13. 使用Flask在Raspberry Pi上构建物联网服务器
  14. FSL ICA-FIX配置及处理流程
  15. Linux centos安装chromium
  16. 《开源安全运维平台-OSSIM最佳实践》将于2015年底出版
  17. iOS音乐播放器实现后台播放锁屏界面控制
  18. php 坦克大战,js坦克大战以实现炮弹击中目标消失并且记分
  19. 如何读懂EDIFACT报文?
  20. linux查看进程占用pcu,ksoftirq占用PCU较高,电脑使用较卡,该如何排查问题和解决?...

热门文章

  1. 在谷歌浏览器下table的td border显示的问题
  2. Linux--git
  3. 学习js在线html(富文本)编辑器
  4. HDU1068Girls and Boys
  5. 初探交换机虚拟化技术m-lag
  6. Windows无法访问\\ 请检查名称的拼写。否则,网络可能有问题。
  7. android 蓝牙之数据传输
  8. leetCode1047
  9. PHP连锁美业收银系统源码
  10. 自己制作crowd counting数据集