基于springmvc开发注解式ip拦截器
一、注解类
- @Documented
- @Target({ElementType.TYPE,ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- public @interface IPFilter {
- /**
- * 访问ip白名单
- * @return
- */
- String[] allow() default {};
- /**
- * 访问ip黑名单
- * @return
- */
- String[] deny() default {};
- }
1. @Documented —— 指明拥有这个注解的元素可以被javadoc此类的工具文档化。这种类型应该用于注解那些影响客户使用带注释的元素声明的类型。如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API。
2. @Target——指明该类型的注解可以注解的程序元素的范围。该元注解的取值可以为TYPE,METHOD,CONSTRUCTOR,FIELD等。如果Target元注解没有出现,那么定义的注解可以应用于程序的任何元素。
3. @Inherited——指明该注解类型被自动继承。如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类。
4.@Retention——指明了该Annotation被保留的时间长短。RetentionPolicy取值为SOURCE,CLASS,RUNTIME。
二、注解实现
- public class AuthorityIPInterceptor extends HandlerInterceptorAdapter {
- private final static Logger logger = LoggerFactory.getLogger(AuthorityIPInterceptor.class);
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- if (handler instanceof HandlerMethod) {
- IPFilter ipFilter = ((HandlerMethod) handler).getMethodAnnotation(IPFilter.class);
- if (ipFilter == null) {
- return true;
- }
- String ipAddress = getIpAddress(request);
- ArrayList<String> deny = Lists.newArrayList(ipFilter.deny());
- ArrayList<String> allow = Lists.newArrayList(ipFilter.allow());
- //设置了黑名单, 黑名单内ip不给通过
- if (CollectionUtils.isNotEmpty(deny)) {
- if (deny.contains(ipAddress)) {
- logger.info("IP: "+ipAddress+" 被拦截");
- response.setStatus(500);
- return false;
- }
- }
- //设置了白名单, 只有白名单内的ip给通过
- if (CollectionUtils.isNotEmpty(allow)) {
- if (allow.contains(ipAddress)) {
- logger.info("IP: "+ipAddress+" 被放行");
- return true;
- }else {
- logger.info("IP: "+ipAddress+" 没有放行权利");
- response.setStatus(500);
- 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;
- }
- }
通过继承springmvc的拦截器,对所有访问当前加了注解的controller接口和方法进行拦截
三、路径拦截
<mvc:interceptor> <mvc:mapping path="/**/xxx/**"/> <bean class="com.xxx..AuthorityIPInterceptor"/> </mvc:interceptor>
通过在mvc的配置文件配置请求的拦截路径,防止所有的请求都被拦截,做到精准控制
基于springmvc开发注解式ip拦截器的更多相关文章
- spring自定义注解实现登陆拦截器
1.spring自定义注解实现登陆拦截器 原理:定义一个注解和一个拦截器,拦截器拦截所有方法请求,判断该方法有没有该注解.没有,放行:有,要进行验证.从而实现方法加注解就需要验证是否登陆. 2.自定义 ...
- springMVC源码分析--HandlerInterceptor拦截器调用过程(二)
在上一篇博客springMVC源码分析--HandlerInterceptor拦截器(一)中我们介绍了HandlerInterceptor拦截器相关的内容,了解到了HandlerInterceptor ...
- SpringMVC(五)-- springmvc的系统学习之拦截器
资源:尚学堂 邹波 springmvc框架视频 一.拦截器简介 使用拦截器时, (1)实现HandlerInterceptor (2)在springmvc配置文件中配置以下信息 <mvc:int ...
- Android流媒体开发之路三:基于NDK开发Android平台RTSP播放器
基于NDK开发Android平台RTSP播放器 最近做了不少android端的开发,有推流.播放.直播.对讲等各种应用,做了RTMP.RTSP.HTTP-FLV.自定义等各种协议,还是有不少收获和心得 ...
- SpringMVC实现注解式权限验证
SpringMVC学习系列(9) 之 实现注解式权限验证 对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servle ...
- SpringMVC实现注解式权限验证(转)
SpringMVC学习系列(9) 之 实现注解式权限验证 对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用serv ...
- SpringMVC -- 梗概--源码--贰--拦截器:Interceptor
附:实体类 1.配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app versi ...
- SpringMVC源码阅读:拦截器
1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...
- SpringMVC 使用注解完成登录拦截
目录 为了实现用户登录拦截你是否写过如下代码呢? 1. 基于Filter 2. 基于Struts 3. 基于SpringMVC 如何使用自定义注解完成自定义拦截呢? 登录注解 SpringMVC 拦截 ...
随机推荐
- (Python OpenGL)【3】着色器 PyOpenGL
(Python OpenGL)现在开始我们使用着色器来进行渲染.着色器是目前做3D图形最流行的方式. OpenGL的渲染管线流程: 数据传输到OpenGL—>顶点处理器—>细分着色—> ...
- P3897 [湖南集训]Crazy Rabbit
\(\color{#0066ff}{ 题目描述 }\) 兔子们决定在自己的城堡里安排一些士兵进行防守. 给出 n 个点的坐标,和城堡里一个圆心在原点的圆形的障碍,兔子们希望从中选出 k 个兔子,使得它 ...
- luogu4151 最大XOR和路径
然后呢这道题其实很简单 我们先考虑一种简单的情况,从1直接走到n(不管怎么走的,反正就是走) 然后就能找到一个路径了 这个走的过程用各种zmj算法都能过 然后呢我们发现如果直接走基本不会得到最优解,考 ...
- mybatis逆向工程工具
mybatis逆向工程 package com.cxy; import java.io.File; import java.util.*; import org.mybatis.generator.a ...
- 了解Linux系统
++++++++++++++++++++++++++++++++++++++++++++++++++++ 有用的参考链接: 带你初识Linux操作系统:https://www.linuxidc.com ...
- JTAG与JLink说明
JTAG接口解读 通常所说的JTAG大致分两类,一类用于测试芯片的电气特性,检测芯片是否有问题:一类用于Debug:一般支持JTAG的CPU内都包含了这两个模块. 一个含有JTAG Debug接口模块 ...
- Appium自动化—浅谈iOS自动化测试环境搭建
在日常的测试工作中,我们会发现有些测试工作重复率极高,测试人员需要花费大量的时间进行这些重复性的测试,浪费了大量的人力与时间.若能够将常用的测试场景进行自动化,那必定能节省许多的人力与时间.作为一个初 ...
- HikariPool连接池的使用
HikariDataSource datasource= new HikariDataSource( xxxx ); Connection cn = datasource.getConnection( ...
- POI 读大文件日志
POI的三个目录 usermodel 包含很多类,方便用户使用,但是占用内存大 eventusermodel 使用xml的SAX事件解析,XSSFReader创建时必须使用OPCPackage,pkg ...
- 傻瓜式Spring教学第一课
首先,把Spring需要的五个包导入项目: commons-logging-1.2.jar spring-beans-4.3.4.RELEASE.jar spring-context-4.3.4.RE ...