- 浏览: 632841 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (819)
- java开发 (110)
- 数据库 (56)
- javascript (30)
- 生活、哲理 (17)
- jquery (36)
- 杂谈 (15)
- linux (62)
- spring (52)
- kafka (11)
- http协议 (22)
- 架构 (18)
- ZooKeeper (18)
- eclipse (13)
- ngork (2)
- dubbo框架 (6)
- Mybatis (9)
- 缓存 (28)
- maven (20)
- MongoDB (3)
- 设计模式 (3)
- shiro (10)
- taokeeper (1)
- 锁和多线程 (3)
- Tomcat7集群 (12)
- Nginx (34)
- nodejs (1)
- MDC (1)
- Netty (7)
- solr (15)
- JSON (8)
- rabbitmq (32)
- disconf (7)
- PowerDesigne (0)
- Spring Boot (31)
- 日志系统 (6)
- erlang (2)
- Swagger (3)
- 测试工具 (3)
- docker (17)
- ELK (2)
- TCC分布式事务 (2)
- marathon (12)
- phpMyAdmin (12)
- git (3)
- Atomix (1)
- Calico (1)
- Lua (7)
- 泛解析 (2)
- OpenResty (2)
- spring mvc (19)
- 前端 (3)
- spring cloud (15)
- Netflix (1)
- zipkin (3)
- JVM 内存模型 (5)
- websocket (1)
- Eureka (4)
- apollo (2)
- idea (2)
- go (1)
- 业务 (0)
- idea开发工具 (1)
最新评论
-
sichunli_030:
对于频繁调用的话,建议采用连接池机制
配置TOMCAT及httpClient的keepalive以高效利用长连接 -
11想念99不见:
你好,我看不太懂。假如我的项目中会频繁调用rest接口,是要用 ...
配置TOMCAT及httpClient的keepalive以高效利用长连接
辅助类,用于存储每个请求的访问数
拦截器
xml配置
http://localhost/web.limit文件
{"IndexController.index":500,
"ProductController.searchProducts":500
}
http://blog.csdn.net/soleave/article/details/50388549
http://blog.csdn.net/ye_sheng/article/details/48395663
http://www.cnblogs.com/sunp823/p/5601396.html
public class AccessCounts { public static final String CALLPATH = "AccessCounts.CALLPATH"; private ConcurrentHashMap<Object, AtomicInteger> map = new ConcurrentHashMap<Object, AtomicInteger>(); private AccessCounts() { } private static class Instance { static AccessCounts counts = new AccessCounts(); } public static AccessCounts getInstance() { return Instance.counts; } public int get(Object key) { AtomicInteger counter = map.get(key); if (counter == null) { counter = new AtomicInteger(0); map.put(key, counter); } return counter.intValue(); } public int incrementAndGet(Object key) { AtomicInteger counter = map.get(key); if (counter == null) { counter = new AtomicInteger(0); map.put(key, counter); } return counter.incrementAndGet(); } public int decrementAndGet(Object key) { AtomicInteger counter = map.get(key); if (counter == null) { return 0; } return counter.decrementAndGet(); } public String status(){ return map.toString(); } }
拦截器
/** *限流拦截器 **/ public class InServiceAccessInterceptor extends HandlerInterceptorAdapter { private static final Logger logger = Logger.getLogger(InServiceAccessInterceptor.class); private ConcurrentHashMap<String, Integer> config = new ConcurrentHashMap<String, Integer>(); // setting private int defaultLimit = 100; private String configUrl = null; private int loadInterval = 1, loadDelay=5; private boolean valid; public InServiceAccessInterceptor(int defaultLimit, String configUrl, int loadInterval, int loadDelay, boolean valid) { this.defaultLimit = defaultLimit; this.configUrl = configUrl; this.loadInterval = loadInterval; this.loadDelay = loadDelay; this.valid = valid; if(valid){ task(); } } //before the actual handler will be executed @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if(valid){ if(handler instanceof HandlerMethod){ HandlerMethod handlerMethod = (HandlerMethod) handler; String callpath = handlerMethod.getMethod().getDeclaringClass().getSimpleName()+"."+handlerMethod.getMethod().getName(); System.out.println(callpath); int counter = AccessCounts.getInstance().get(callpath); boolean limit = limit(callpath, counter); if (limit) { throw new IllegalAccessException("Flowing Limit." + callpath + "=" +counter ); } MDC.put(AccessCounts.CALLPATH, callpath); AccessCounts.getInstance().incrementAndGet(callpath); } } return true; } //after the handler is executed @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if(valid){ Object callpath = MDC.get(AccessCounts.CALLPATH); if (null != callpath) { AccessCounts.getInstance().decrementAndGet( callpath); } MDC.remove(AccessCounts.CALLPATH); } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub } private boolean limit(String callpath, int counter) { Integer obj = config.get(callpath); int limit = defaultLimit; if (obj != null) { limit = obj.intValue(); } if (logger.isDebugEnabled() ) { logger.debug("check callpath:" + callpath + " limit:" + limit); } if (counter >= limit) { logger.warn("the call[" + callpath + "] is over limit:" + limit + " counter:" + counter); return true; } return false; } public static String sendGet(String url, String param) { String result = ""; BufferedReader in = null; try { String urlNameString = url + (param == null ? "" : "?" + param); URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 /*Map<String, List<String>> map = connection.getHeaderFields(); for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); }*/ // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { logger.error("request url fail="+url, e); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e) { } } return result; } public void task() { TimerTask task = new TimerTask() { @Override public void run() { if (null == configUrl ) return; String text = sendGet(configUrl, null); logger.info("load config:" + text ); if ( null == text || "".equals(text.trim())) return; text = text.replaceAll("[\\{\\}\"\n]", ""); config.clear(); for (String line : text.split(",")) { String fields[] = line.split(":"); if ( fields.length < 2) continue; try { config.put(fields[0].trim(), Integer.valueOf(fields[1].trim())); } catch (Exception e) { logger.error("load config fail.", e); } } } }; Timer timer = new Timer(); long delay = 1000 * loadDelay; long intevalPeriod = 1000 * loadInterval; // schedules the task to be run in an interval logger.info("Task setting delay:" + delay + " intevalPeriod:" + intevalPeriod); timer.scheduleAtFixedRate(task, delay, intevalPeriod); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(60*1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("AccessCounts status:" + AccessCounts.getInstance().status()); } } }).start(); } }
xml配置
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /> <beans:bean class="xxx.xxx.xxx.intercept.InServiceAccessInterceptor"> <beans:constructor-arg index="0" value="1000" /> <!-- defaultLimit 默认设置 --> <beans:constructor-arg index="1" value="http://localhost/web.limit" /> <!-- configUrl --> <beans:constructor-arg index="2" value="60" /> <!-- loadInterval unit : second --> <beans:constructor-arg index="3" value="5" /> <!-- loadDelay unit : second --> <beans:constructor-arg index="4" value="false" /> <!-- valid true: used --> </beans:bean> </mvc:interceptor> </mvc:interceptors>
http://localhost/web.limit文件
{"IndexController.index":500,
"ProductController.searchProducts":500
}
http://blog.csdn.net/soleave/article/details/50388549
http://blog.csdn.net/ye_sheng/article/details/48395663
http://www.cnblogs.com/sunp823/p/5601396.html
发表评论
-
动手写一个异步Controller方法
2017-11-23 15:30 427http://twincle.iteye.com/blog/1 ... -
SpringMVC @ResponseBody 415错误处理
2017-11-22 11:23 811http://blog.csdn.net/yixiaoping ... -
Spring MVC DispatcherServlet配置
2017-11-03 09:02 348第三章 DispatcherServlet详解 ——跟开涛学S ... -
基于Spring MVC的Web应用开发(6) - Response
2017-08-29 18:27 426http://stephansun.iteye.com/blo ... -
Spring 4 官方文档学习(十一)Web MVC 框架之URI Builder
2017-08-10 10:39 393http://www.cnblogs.com/larryzea ... -
SpringMVC加载WebApplicationContext源码分析
2017-08-07 20:40 513SpringMVC加载WebApplicationContex ... -
定制jackson的自定义序列化(null值的处理)
2017-08-01 20:52 17http://www.cnblogs.com/lic309/p ... -
HandlerMethodArgumentResolver
2017-08-01 20:56 479https://sdqali.in/blog/2016/01/ ... -
spring rest mvc使用RestTemplate调用
2017-07-22 16:42 860import java.util.HashMap; impo ... -
Spring mvc 各种注解
2017-07-19 16:01 431http://blog.csdn.net/sudiluo_ja ... -
@RequestMapping 用法详解之地址映射
2017-07-14 18:36 350引言: 前段时间项目中用到了RESTful模式来开发程序,但是 ... -
SpringMVC的拦截器(Interceptor)和过滤器(Filter)的区别与联系
2017-07-11 19:16 16481.过滤器: 依赖于se ... -
springMvc--静态资源拦截
2017-07-10 18:38 412http://www.cnblogs.com/liucongl ... -
springMvc--接受日期类型参数处理
2017-07-10 18:33 9711.controller /** * 接收日期类型 ... -
SpringMVC 深度解析@RequestMapping(一)
2017-02-27 16:09 409参考:http://blog.csdn.net/congcon ... -
深入解析 Spring MVC的配置文件
2017-01-20 13:46 4141.关于mvc annotation-driven 中出入参数 ... -
spring3 的restful API RequestMapping介绍
2016-09-28 16:05 690spring3 的restful API RequestM ... -
@RequestParam @RequestBody @PathVariable 等参数绑定注解详解
2016-09-28 15:36 413引言: 接上一篇文章,对@RequestMapping进行地址 ... -
SpringMVC注解@RequestParam全面解析
2016-08-19 11:33 730在SpringMVC后台控制层获取参数的方式主要有两种,一种是 ...
相关推荐
本实验报告将探讨如何利用 SpringMVC 的拦截器(Interceptor)来实现用户登录权限验证,确保只有已登录的用户才能访问特定的受保护资源。 首先,我们来看一下实验的基本步骤: 1. 创建 `User` 类:这是表示用户...
- 使用Java配置时,可以通过`@EnableWebMvc` 注解启用Web MVC配置,并在`WebMvcConfigurer` 实现类中重写`addInterceptors()` 方法来注册拦截器。 3. **自定义拦截器**: - 自定义拦截器需要继承`...
通过实现`HandlerInterceptor`接口或者继承`HandlerInterceptorAdapter`抽象类,开发者可以定义自己的拦截器。拦截器通常用于实现如登录检查、权限验证、日志记录、性能统计等跨切面的功能。 1. 拦截器的注册:拦截...
1. **定义拦截器类**:创建一个实现了Spring MVC的`HandlerInterceptor`接口的类,或者继承`HandlerInterceptorAdapter`抽象类。在这个类中,你需要重写`preHandle()`方法,进行登录验证逻辑。 2. **实现登录验证...
Spring MVC的拦截器基于AOP(面向切面编程)原理,它们通过实现`HandlerInterceptor`接口或继承`HandlerInterceptorAdapter`抽象类来定义。拦截器链的概念使得多个拦截器可以按照特定顺序执行,每个拦截器都可以决定...
在Spring MVC框架中,Interceptor(拦截器)是一个强大的工具,用于在请求被控制器处理之前或之后执行特定的逻辑。它们可以用来实现通用的功能,如权限验证、日志记录、性能统计等,避免在每个控制器方法中重复编写...
在 SpringMVC 中实现限流,可以通过多种方式,例如使用拦截器(Interceptor)、AOP(面向切面编程)或者第三方库。本篇文章将重点介绍如何利用 Google 的 Guava 库在 SpringMVC 中实现限流。 **Guava 限流机制** ...
以下是对自定义拦截器实现步骤的详细解释: ### 1. 自定义拦截器类 #### 1.1 继承 `HandlerInterceptorAdapter` 你可以选择继承`HandlerInterceptorAdapter`这个抽象类,这是一个已经实现了`HandlerInterceptor`...
下面是一个具体的登录状态检测拦截器实现示例,该示例展示了如何使用`HandlerInterceptor`接口来实现登录状态检查功能: ```java public class LoginInterceptor implements HandlerInterceptor { @Override ...
要创建自定义拦截器,你需要继承 `HandlerInterceptor` 或实现 `HandlerInterceptorAdapter` 类。这两个类都提供了三个核心方法: 1. `preHandle(HttpServletRequest request, HttpServletResponse response, ...
1. **HandlerInterceptorAdapter**: Spring MVC的拦截器通过实现`HandlerInterceptorAdapter`接口,重写`preHandle`、`postHandle`和`afterCompletion`方法,实现请求前、后处理和异常处理。 2. **全局异常处理**: ...
在Spring MVC中,拦截器是通过实现`HandlerInterceptor`接口或者继承`HandlerInterceptorAdapter`抽象类来创建的。 `HandlerInterceptor`接口定义了三个方法: 1. `preHandle(HttpServletRequest request, ...
同时,多个拦截器可以按照指定顺序执行,通过`HandlerInterceptorAdapter`还可以简化拦截器的实现。 在实际开发中,`Interceptor_demo`这个压缩包文件可能包含了示例代码,包括Interceptor的实现以及相关的配置文件...
在Spring MVC中,拦截器接口由`HandlerInterceptor`定义,而`HandlerInterceptorAdapter`类则提供了一个适配器模式的默认实现,简化了拦截器的开发过程。`HandlerInterceptor`接口包含以下三个核心方法: 1. **`...
首先,我们需要创建一个自定义的拦截器类,该类通常会实现Spring MVC提供的`HandlerInterceptor`接口或继承`HandlerInterceptorAdapter`抽象类。在这个示例中,我们可以定义一个名为`LoginInterceptor`的类,如下: ...
在这个"SpringMVC拦截器"的实践中,我们将探讨如何实现一个用于登录验证的拦截器。 首先,我们需要创建一个自定义的拦截器类,该类需要继承自Spring MVC的`HandlerInterceptor`接口或实现`...
创建一个Spring MVC拦截器需要实现`HandlerInterceptor`接口或者继承`HandlerInterceptorAdapter`抽象类。例如,我们创建一个名为`LoggingInterceptor`的拦截器: ```java public class LoggingInterceptor extends...
在"springmvc-chapter2"这个文件中,可能包含了项目的源代码,包括Spring MVC配置文件(如`servlet-context.xml`)、拦截器实现类、Session管理相关代码以及控制器类。通过阅读和理解这些代码,可以更深入地了解...
在Spring MVC中,Interceptor(拦截器)是一种强大的机制,它允许开发者在请求处理前后执行自定义逻辑,而不必侵入到Controller代码中。本篇文章主要探讨了Interceptor的使用及其源码解析,帮助深入理解其工作原理。...
SpringMVC实现简单的拦截器 SpringMVC中实现简单的拦截器是通过HandlerInterceptor来实现的。要定义一个Interceptor,主要有两种方式:第一种方式是定义的Interceptor类要实现了Spring的HandlerInterceptor接口,...