Spring 4 REST+AngularJS应用并发用户数限制及弹窗实现问询
针对你遇到的Spring 4 REST应用搭配AngularJS前端的并发用户限制需求,我整理了一套落地性强的实现方案,分成后端控制和前端提示两部分来做,刚好能满足你在完善监控体系前的临时需求:
后端:Spring 4 实现并发用户数监控与限制
1. 实现线程安全的在线用户计数器
首先需要一个全局的、线程安全的计数器来维护当前在线用户数,这里用AtomicInteger就能很好地避免并发计数错误:
import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import java.util.concurrent.atomic.AtomicInteger; public class OnlineUserCounter implements HttpSessionListener { // 静态变量保证全局唯一,AtomicInteger保证线程安全 private static final AtomicInteger onlineUserCount = new AtomicInteger(0); @Override public void sessionCreated(HttpSessionEvent se) { // 用户会话创建时计数+1 onlineUserCount.incrementAndGet(); } @Override public void sessionDestroyed(HttpSessionEvent se) { // 用户会话销毁时计数-1 onlineUserCount.decrementAndGet(); } // 提供获取当前在线数的静态方法 public static int getOnlineUserCount() { return onlineUserCount.get(); } }
然后在web.xml中注册这个监听器,让它能监听会话的创建和销毁:
<listener> <listener-class>com.yourpackage.OnlineUserCounter</listener-class> </listener>
2. 添加请求拦截器做并发校验
接下来通过Spring的拦截器,在所有REST请求进入前校验当前在线用户数是否超过上限,若超限则返回特定状态码:
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ConcurrentUserInterceptor implements HandlerInterceptor { // 自定义最大在线用户数,可根据实际情况调整 private static final int MAX_ONLINE_USERS = 100; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { int currentCount = OnlineUserCounter.getOnlineUserCount(); if (currentCount > MAX_ONLINE_USERS) { // 返回HTTP 429(请求过多)状态码,同时返回提示文本 response.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS); response.getWriter().write("当前在线用户数已达上限,请稍后再试"); return false; // 中断请求流程 } return true; // 正常放行请求 } // postHandle和afterCompletion方法留空即可 }
最后在Spring MVC配置文件中注册这个拦截器,让它对所有REST接口生效:
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.yourpackage.ConcurrentUserInterceptor"/> </mvc:interceptor> </mvc:interceptors>
前端:AngularJS 捕获超限提示并弹出模态框
1. 全局拦截HTTP响应
用AngularJS的$httpInterceptor全局捕获后端返回的429状态码,触发模态框提示:
angular.module('yourApp').factory('concurrentUserInterceptor', ['$q', '$modal', function($q, $modal) { return { responseError: function(rejection) { // 捕获429状态码 if (rejection.status === 429) { // 弹出提示模态框(依赖ui-bootstrap的$modal组件) $modal.open({ templateUrl: 'templates/too-many-users-modal.html', controller: 'TooManyUsersModalCtrl', size: 'sm' }); } return $q.reject(rejection); } }; }]);
然后把这个拦截器注册到$httpProvider中:
angular.module('yourApp').config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push('concurrentUserInterceptor'); }]);
2. 实现模态框模板与控制器
创建模态框的HTML模板too-many-users-modal.html:
<div class="modal-header"> <h3 class="modal-title">系统提示</h3> </div> <div class="modal-body"> <p>当前在线用户数已达上限,请稍后再尝试登录或操作</p> </div> <div class="modal-footer"> <button class="btn btn-primary" ng-click="confirm()">确定</button> </div>
对应的控制器:
angular.module('yourApp').controller('TooManyUsersModalCtrl', ['$scope', '$modalInstance', function($scope, $modalInstance) { $scope.confirm = function() { $modalInstance.close(); }; }]);
额外注意事项
- 确保会话超时配置正确:在
web.xml中设置<session-config><session-timeout>30</session-timeout></session-config>(单位分钟),避免用户退出后计数器未及时递减。 - 若应用有集群部署需求,这个方案的内存级计数器会失效,需要改用Redis等分布式存储来维护在线用户数。
- 后续完善监控体系时,可以基于这个计数器扩展,对接监控面板实时展示在线用户趋势、系统负载等指标。
内容的提问来源于stack exchange,提问作者sepointes
相关产品推荐
相关产品推荐

