code: public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
              throws IOException, ServletException {
          final HttpServletRequest httpRequest = (HttpServletRequest) request;
          final HttpServletResponse httpResponse = (HttpServletResponse) response;
          final HttpSession session = httpRequest.getSession(true);
  
          synchronized (session.getId().intern()) {
              Stack<Date> times = HttpUtil.getSessionAttribute(session, "times");
              if (times == null) {
                  times = new Stack<>();
                  times.push(new Date(0));
                  session.setAttribute("times", times);
              }
              times.push(new Date());
              if (times.size() >= maximumRequestsPerPeriod) {
                  times.removeElementAt(0);
              }
              final Date newest = times.get(times.size() - 1);
              final Date oldest = times.get(0);
              final long elapsed = newest.getTime() - oldest.getTime();
              if (elapsed < timePeriodSeconds * 1000) {
                  httpResponse.sendError(429);
                  return;
              }
          }
          chain.doFilter(request, response);
      }
docs: Determines if the request rate is below or has exceeded the the maximum requests per second
  for the given time period. If exceeded, a HTTP status code of 429 (too many requests) will
  be send and no further processing of the request will be done. If the request has not exceeded
  the limit, the request will continue on as normal.
  
  @param request a ServletRequest
  @param response a ServletResponse
  @param chain a FilterChain
  @throws IOException a IOException
  @throws ServletException a ServletException