📄 filterdispatcher.java
字号:
* retrieve the servlet context from other sources. * * @return the servlet context. */ protected ServletContext getServletContext() { return filterConfig.getServletContext(); } /** * Expose the FilterConfig instance. * * @return Our FilterConfit instance */ protected FilterConfig getFilterConfig() { return filterConfig; } /** * Wrap and return the given request, if needed, so as to to transparently * handle multipart data as a wrapped class around the given request. * * @param request Our ServletRequest object * @param response Our ServerResponse object * @return Wrapped HttpServletRequest object * @throws ServletException on any error */ protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException { Dispatcher du = Dispatcher.getInstance(); // Prepare and wrap the request if the cleanup filter hasn't already, cleanup filter should be // configured first before struts2 dispatcher filter, hence when its cleanup filter's turn, // static instance of Dispatcher should be null. if (du == null) { Dispatcher.setInstance(dispatcher); // prepare the request no matter what - this ensures that the proper character encoding // is used before invoking the mapper (see WW-9127) dispatcher.prepare(request, response); } else { dispatcher = du; } try { // Wrap request first, just in case it is multipart/form-data // parameters might not be accessible through before encoding (ww-1278) request = dispatcher.wrapRequest(request, getServletContext()); } catch (IOException e) { String message = "Could not wrap servlet request with MultipartRequestWrapper!"; LOG.error(message, e); throw new ServletException(message, e); } return request; } /** * Create a string array from a comma-delimited list of packages. * * @param packages A comma-delimited String listing packages * @return A string array of packages */ protected String[] parse(String packages) { if (packages == null) { return null; } List<String> pathPrefixes = new ArrayList<String>(); StringTokenizer st = new StringTokenizer(packages, ", \n\t"); while (st.hasMoreTokens()) { String pathPrefix = st.nextToken().replace('.', '/'); if (!pathPrefix.endsWith("/")) { pathPrefix += "/"; } pathPrefixes.add(pathPrefix); } return pathPrefixes.toArray(new String[pathPrefixes.size()]); } /** * Process an action or handle a request a static resource. * <p/> * The filter tries to match the request to an action mapping. * If mapping is found, the action processes is delegated to the dispatcher's serviceAction method. * If action processing fails, doFilter will try to create an error page via the dispatcher. * <p/> * Otherwise, if the request is for a static resource, * the resource is copied directly to the response, with the appropriate caching headers set. * <p/> * If the request does not match an action mapping, or a static resource page, * then it passes through. * * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) */ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; ServletContext servletContext = getServletContext(); String timerKey = "FilterDispatcher_doFilter: "; try { UtilTimerStack.push(timerKey); request = prepareDispatcherAndWrapRequest(request, response); ActionMapping mapping; try { mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager()); } catch (Exception ex) { LOG.error("error getting ActionMapping", ex); dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex); return; } if (mapping == null) { // there is no action in this request, should we look for a static resource? String resourcePath = RequestUtils.getServletPath(request); if ("".equals(resourcePath) && null != request.getPathInfo()) { resourcePath = request.getPathInfo(); } if (serveStatic && resourcePath.startsWith("/struts")) { String name = resourcePath.substring("/struts".length()); findStaticResource(name, request, response); } else { // this is a normal request, let it pass through chain.doFilter(request, response); } // The framework did its job here return; } dispatcher.serviceAction(request, response, servletContext, mapping); } finally { try { ActionContextCleanUp.cleanUp(req); } finally { UtilTimerStack.pop(timerKey); } } } /** * Locate a static resource and copy directly to the response, * setting the appropriate caching headers. * * @param name The resource name * @param request The request * @param response The response * @throws IOException If anything goes wrong */ protected void findStaticResource(String name, HttpServletRequest request, HttpServletResponse response) throws IOException { if (!name.endsWith(".class")) { for (String pathPrefix : pathPrefixes) { InputStream is = findInputStream(name, pathPrefix); if (is != null) { Calendar cal = Calendar.getInstance(); // check for if-modified-since, prior to any other headers long ifModifiedSince = 0; try { ifModifiedSince = request.getDateHeader("If-Modified-Since"); } catch (Exception e) { LOG.warn("Invalid If-Modified-Since header value: '" + request.getHeader("If-Modified-Since") + "', ignoring"); } long lastModifiedMillis = lastModifiedCal.getTimeInMillis(); long now = cal.getTimeInMillis(); cal.add(Calendar.DAY_OF_MONTH, 1); long expires = cal.getTimeInMillis(); if (ifModifiedSince > 0 && ifModifiedSince <= lastModifiedMillis) { // not modified, content is not sent - only basic headers and status SC_NOT_MODIFIED response.setDateHeader("Expires", expires); response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); is.close(); return; } // set the content-type header String contentType = getContentType(name); if (contentType != null) { response.setContentType(contentType); } if (serveStaticBrowserCache) { // set heading information for caching static content response.setDateHeader("Date", now); response.setDateHeader("Expires", expires); response.setDateHeader("Retry-After", expires); response.setHeader("Cache-Control", "public"); response.setDateHeader("Last-Modified", lastModifiedMillis); } else { response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setHeader("Expires", "-1"); } try { copy(is, response.getOutputStream()); } finally { is.close(); } return; } } } response.sendError(HttpServletResponse.SC_NOT_FOUND); } /** * Determine the content type for the resource name. * * @param name The resource name * @return The mime type */ protected String getContentType(String name) { // NOT using the code provided activation.jar to avoid adding yet another dependency // this is generally OK, since these are the main files we server up if (name.endsWith(".js")) { return "text/javascript"; } else if (name.endsWith(".css")) { return "text/css"; } else if (name.endsWith(".html")) { return "text/html"; } else if (name.endsWith(".txt")) { return "text/plain"; } else if (name.endsWith(".gif")) { return "image/gif"; } else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) { return "image/jpeg"; } else if (name.endsWith(".png")) { return "image/png"; } else { return null; } } /** * Copy bytes from the input stream to the output stream. * * @param input The input stream * @param output The output stream * @throws IOException If anything goes wrong */ protected void copy(InputStream input, OutputStream output) throws IOException { final byte[] buffer = new byte[4096]; int n; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); } output.flush(); // WW-1526 } /** * Look for a static resource in the classpath. * * @param name The resource name * @param packagePrefix The package prefix to use to locate the resource * @return The inputstream of the resource * @throws IOException If there is a problem locating the resource */ protected InputStream findInputStream(String name, String packagePrefix) throws IOException { String resourcePath; if (packagePrefix.endsWith("/") && name.startsWith("/")) { resourcePath = packagePrefix + name.substring(1); } else { resourcePath = packagePrefix + name; } resourcePath = URLDecoder.decode(resourcePath, encoding); return ClassLoaderUtil.getResourceAsStream(resourcePath, getClass()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -