@Override
 protected void doFilterInternal(
     HttpServletRequest request, HttpServletResponse response, FilterChain chain)
     throws ServletException, IOException {
   UrlPathHelper helper = new UrlPathHelper();
   String suffix = helper.getPathWithinApplication(request);
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   try {
     chain.doFilter(request, response);
   } finally {
     stopWatch.stop();
     int status = getStatus(response);
     Object bestMatchingPattern =
         request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
     HttpStatus httpStatus = HttpStatus.OK;
     try {
       httpStatus = HttpStatus.valueOf(status);
     } catch (Exception ex) {
       // not convertible
     }
     if (bestMatchingPattern != null) {
       suffix = bestMatchingPattern.toString().replaceAll("[{}]", "-");
     } else if (httpStatus.is4xxClientError()) {
       suffix = UNKNOWN_PATH_SUFFIX;
     }
     String gaugeKey = getKey("response" + suffix);
     MetricFilterAutoConfiguration.this.gaugeService.submit(
         gaugeKey, stopWatch.getTotalTimeMillis());
     String counterKey = getKey("status." + status + suffix);
     MetricFilterAutoConfiguration.this.counterService.increment(counterKey);
   }
 }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.springframework.web.servlet.mvc.Controller#handleRequest(javax.servlet
   * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
   */
  public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
      throws Exception {

    String requestedPath =
        (StringUtils.isEmpty(mapping))
            ? helper.getPathWithinApplication(request)
            : helper.getPathWithinServletMapping(request);

    if (StringUtils.isNotEmpty(controllerMapping)) {
      requestedPath = requestedPath.substring(controllerMapping.length());
    }

    requestHandler.processRequest(requestedPath, request, response);
    return null;
  }
  @Override
  protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
    String url = URL_PATH_HELPER.getPathWithinApplication(request);

    UrlMatch match = routeSet.getBestMatch(request, url);
    if (match != null) {
      routeSet.setCurrentMatch(request, match);
      Object controller = specialRoutes.get(match.getRoute());

      if (controller == null) {
        String controllerName = match.getParameters().get(controllerParameterName);

        if (controllerName != null) {
          return controllerName + controllerNameSuffix;
        }
      }

      return controller;
    }

    return null;
  }
  /**
   * Overrides the default behaviour to establish the handler from the GrailsApplication instance
   *
   * @param request The request
   * @param cache Whether to cache the Handler in the request
   * @return The HandlerExecutionChain
   * @throws Exception
   */
  protected HandlerExecutionChain getHandler(HttpServletRequest request, boolean cache)
      throws Exception {
    String uri = urlHelper.getPathWithinApplication(request);
    if (logger.isDebugEnabled()) {
      logger.debug("Looking up Grails controller for URI [" + uri + "]");
    }
    GrailsControllerClass controllerClass =
        (GrailsControllerClass)
            application.getArtefactForFeature(ControllerArtefactHandler.TYPE, uri);
    final String actionName =
        (String) request.getAttribute(GrailsApplicationAttributes.ACTION_NAME_ATTRIBUTE);

    if (controllerClass != null) {
      HandlerInterceptor[] interceptors;
      // if we're in a development environment we want to re-establish interceptors just in case
      // they
      // have changed at runtime

      if (GrailsUtil.isDevelopmentEnv()) {
        interceptors = establishInterceptors(getWebApplicationContext());
      } else {
        interceptors = this.interceptors;
      }
      if (controllerClass.isFlowAction(actionName)) {
        FlowHandler flowHandler =
            new AbstractFlowHandler() {
              public String getFlowId() {
                return actionName;
              }
            };
        return new HandlerExecutionChain(flowHandler, interceptors);
      } else {
        return new HandlerExecutionChain(mainController, interceptors);
      }
    }
    return null;
  }