一、注解類

1 @Documented 2 @Target({ElementType.TYPE,ElementType.METHOD}) 3 @Retention(RetentionPolicy.RUNTIME) 4 public @interface IPFilter { 5 6 /** 7 * 訪問ip白名單 8 * @return 9 */ 10 String[] allow() default {}; 11 12 /** 13 * 訪問ip黑名單 14 * @return 15 */ 16 String[] deny() default {}; 17 }
1. @Documented —— 指明擁有這個注解的元素可以被javadoc此類的工具文檔化。這種類型應該用於注解那些影響客戶使用帶注釋的元素聲明的類型。如果一種聲明使用Documented進行注解,這種類型的注解被作為被標注的程序成員的公共API。
2. @Target——指明該類型的注解可以注解的程序元素的范圍。該元注解的取值可以為TYPE,METHOD,CONSTRUCTOR,FIELD等。如果Target元注解沒有出現,那么定義的注解可以應用於程序的任何元素。
3. @Inherited——指明該注解類型被自動繼承。如果用戶在當前類中查詢這個元注解類型並且當前類的聲明中不包含這個元注解類型,那么也將自動查詢當前類的父類是否存在Inherited元注解,這個動作將被重復執行知道這個標注類型被找到,或者是查詢到頂層的父類。
4.@Retention——指明了該Annotation被保留的時間長短。RetentionPolicy取值為SOURCE,CLASS,RUNTIME。
二、注解實現

1 public class AuthorityIPInterceptor extends HandlerInterceptorAdapter { 2 private final static Logger logger = LoggerFactory.getLogger(AuthorityIPInterceptor.class); 3 4 @Override 5 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 6 throws Exception { 7 if (handler instanceof HandlerMethod) { 8 IPFilter ipFilter = ((HandlerMethod) handler).getMethodAnnotation(IPFilter.class); 9 if (ipFilter == null) { 10 return true; 11 } 12 String ipAddress = getIpAddress(request); 13 ArrayList<String> deny = Lists.newArrayList(ipFilter.deny()); 14 ArrayList<String> allow = Lists.newArrayList(ipFilter.allow()); 15 16 //設置了黑名單, 黑名單內ip不給通過 17 if (CollectionUtils.isNotEmpty(deny)) { 18 if (deny.contains(ipAddress)) { 19 logger.info("IP: "+ipAddress+" 被攔截"); 20 response.setStatus(500); 21 return false; 22 } 23 } 24 //設置了白名單, 只有白名單內的ip給通過 25 if (CollectionUtils.isNotEmpty(allow)) { 26 if (allow.contains(ipAddress)) { 27 logger.info("IP: "+ipAddress+" 被放行"); 28 return true; 29 }else { 30 logger.info("IP: "+ipAddress+" 沒有放行權利"); 31 response.setStatus(500); 32 return false; 33 } 34 } 35 } 36 return true; 37 } 38 39 /** 40 * 獲取請求主機IP地址,如果通過代理進來,則透過防火牆獲取真實IP地址; 41 * 42 * @param request 43 * @return 44 * @throws IOException 45 */ 46 public final static String getIpAddress(HttpServletRequest request) throws IOException { 47 // 獲取請求主機IP地址,如果通過代理進來,則透過防火牆獲取真實IP地址 48 49 String ip = request.getHeader("X-Forwarded-For"); 50 if (logger.isInfoEnabled()) { 51 logger.info("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip=" + ip); 52 } 53 54 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 55 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 56 ip = request.getHeader("Proxy-Client-IP"); 57 if (logger.isInfoEnabled()) { 58 logger.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=" + ip); 59 } 60 } 61 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 62 ip = request.getHeader("WL-Proxy-Client-IP"); 63 if (logger.isInfoEnabled()) { 64 logger.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=" + ip); 65 } 66 } 67 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 68 ip = request.getHeader("HTTP_CLIENT_IP"); 69 if (logger.isInfoEnabled()) { 70 logger.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=" + ip); 71 } 72 } 73 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 74 ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 75 if (logger.isInfoEnabled()) { 76 logger.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=" + ip); 77 } 78 } 79 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 80 ip = request.getRemoteAddr(); 81 if (logger.isInfoEnabled()) { 82 logger.info("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip=" + ip); 83 } 84 } 85 } else if (ip.length() > 15) { 86 String[] ips = ip.split(","); 87 for (int index = 0; index < ips.length; index++) { 88 String strIp = (String) ips[index]; 89 if (!("unknown".equalsIgnoreCase(strIp))) { 90 ip = strIp; 91 break; 92 } 93 } 94 } 95 return ip; 96 } 97 }
通過繼承springmvc的攔截器,對所有訪問當前加了注解的controller接口和方法進行攔截
三、路徑攔截
1 <mvc:interceptor> 2 <mvc:mapping path="/**/xxx/**"/> 3 <bean class="com.xxx..AuthorityIPInterceptor"/> 4 </mvc:interceptor>
通過在mvc的配置文件配置請求的攔截路徑,防止所有的請求都被攔截,做到精准控制