public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException { switch (canHandleRequest(req, res)) { case CAN_HANDLE_REQUEST_YES: { HttpServletRequest httpReq = new RequestWrapper((HttpServletRequest) req); HttpServletResponse httpRes = (HttpServletResponse) res; handleRequest(httpReq, httpRes); return; } case CAN_HANDLE_REQUEST_REDIRECT: { HttpServletRequest httpReq = (HttpServletRequest) req; HttpServletResponse httpRes = (HttpServletResponse) res; String url = httpReq.getContextPath() + httpReq.getServletPath(); url = url + "/"; if (!StringUtils.isEmpty(httpReq.getQueryString())) { url = url + "?" + httpReq.getQueryString(); } httpRes.sendRedirect(httpRes.encodeRedirectURL(url)); return; } case CAN_HANDLE_REQUEST_REDIRECT_TO_DEFAULT_CONTROLLER: { Class<?> controllerClass = controllers.get(DEFAULT_CONTROLLER_KEY).controllerClass; Controller annotation = controllerClass.getAnnotation(Controller.class); String ctrlName = annotation != null && !StringUtils.isEmpty(annotation.alias()) ? annotation.alias() : controllerClass.getName(); String url = ctrlName + "/"; // relative url; by appending the '/' this targets the default action for // the controller; otherwise we'd get another redirect that adds just the / // (see above) HttpServletResponse httpRes = (HttpServletResponse) res; httpRes.sendRedirect(httpRes.encodeRedirectURL(url)); return; } default: filterChain.doFilter(req, res); // pass along } }
/** * Scan WEB-INF/lib and WEB-INF/classes for Controller classes and puts all in controllerClasses * map. * * @throws IOException */ @SuppressWarnings("unchecked") private void collectControllers() throws IOException { AnnotationDB adb = new AnnotationDB(); adb.setScanClassAnnotations(true); adb.setScanFieldAnnotations(false); adb.setScanMethodAnnotations(false); adb.setScanParameterAnnotations(false); adb.scanArchives(WarUrlFinder.findWebInfClassesPath(applicationContext)); adb.scanArchives(WarUrlFinder.findWebInfLibClasspaths(applicationContext)); Set<String> ctrls = adb.getAnnotationIndex().get(Controller.class.getName()); for (String fqcn : ctrls) { Class<? extends BaseController> clazz = null; try { clazz = (Class<? extends BaseController>) Class.forName(fqcn); } catch (Exception e) { log.warn("Class " + fqcn + " not found or not derived from Controller class. Ignoring it."); continue; } Controller controllerAnnotation = clazz.getAnnotation(Controller.class); ControllerInfo controllerInfo = new ControllerInfo(); controllerInfo.controllerClass = clazz; controllerInfo.defaultActionName = controllerAnnotation.defaultAction(); controllers.put(fqcn, controllerInfo); boolean isDefaultController = clazz.getAnnotation(Controller.class).isDefaultController(); if (isDefaultController) { controllers.put(DEFAULT_CONTROLLER_KEY, controllerInfo); } String alias = controllerAnnotation.alias(); if (StringUtils.isNotEmpty(alias)) { alias = alias.trim(); if (alias.contains("/")) { log.warn("Controller alias '" + alias + "' contains illegal characters. Ignoring alias."); alias = null; } else if (controllers.containsKey(alias)) { log.warn( "Duplicate Controller alias '" + alias + "' detected. Used by " + fqcn + " and " + controllers.get(alias).controllerClass.getName() + ". Using alias only for the latter."); alias = null; } else { controllers.put(alias, controllerInfo); } } log.debug( (StringUtils.isNotEmpty(alias) ? alias + ", " : "") + fqcn + " -> " + fqcn + (isDefaultController ? " (default controller)" : "")); collectActions(controllerInfo); } }