⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webappservlet.java

📁 用java开发的
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
			if ("yes".equals(System.getProperty(WAR_NAME_AS_CONTEXTPATH)) == false)
				result.contextName = (String) xp.evaluate(prefix + "display-name", document, XPathConstants.STRING);
			if (result.contextName == null || result.contextName.length() == 0)
				result.contextName = context;
			else
				result.contextPath = "/" + result.contextName;
			// context parameters
			NodeList nodes = (NodeList) xp.evaluate(prefix + "context-param", document, XPathConstants.NODESET);
			int nodesLen = nodes.getLength();
			for (int p = 0; p < nodesLen; p++) {
				result.contextParameters.put((String) xp.evaluate(prefix + "param-name", nodes.item(p),
						XPathConstants.STRING), (String) xp.evaluate(prefix + "param-value", nodes.item(p),
						XPathConstants.STRING));
			}
			// session-config <session-timeout>
			Number num = (Number) xp.evaluate(prefix + "session-config/" + prefix + "session-timeout", document,
					XPathConstants.NUMBER);
			if (num != null)
				result.sessionTimeout = num.intValue();
			if (result.sessionTimeout < 0)
				result.sessionTimeout = 0;
			else
				result.sessionTimeout *= 60;
			Thread.currentThread().setContextClassLoader(result.ucl);
			// listeners listener-class
			nodes = (NodeList) xp.evaluate(prefix + "listener/" + prefix + "listener-class", document,
					XPathConstants.NODESET);
			nodesLen = nodes.getLength();
			if (nodesLen > 0) {
				result.listeners = new ArrayList<EventListener>(nodesLen);
				for (int i = 0; i < nodesLen; i++)
					try {
						EventListener eventListener = (EventListener) result.ucl.loadClass(
								nodes.item(i).getTextContent().trim()).newInstance();
						if (eventListener instanceof HttpSessionListener) {
							if (result.sessionListeners == null)
								result.sessionListeners = new ArrayList<HttpSessionListener>(nodesLen);
							result.sessionListeners.add((HttpSessionListener) eventListener);
						}
						result.listeners.add(eventListener); // because the same class can implement other listener interfaces
					} catch (Exception e) {
						result.log("Event listener " + nodes.item(i).getTextContent() + " can't be created.", e);
					} catch (Error e) {
						result.log("Event listener " + nodes.item(i).getTextContent() + " can't be created.", e);
					}
			}

			// restore sessions for this context
			// serve.sessions.restore for the current context

			// notify context listeners
			if (result.listeners != null)
				for (EventListener listener : result.listeners) {
					if (listener instanceof ServletContextListener)
						try {
							((ServletContextListener) listener).contextInitialized(new ServletContextEvent(result));
						} catch (Exception e) {
							throw new ServletException("A problem in a context listener initialization.", e);
						}
				}
			// process filters
			nodes = (NodeList) xp.evaluate(prefix + "filter", document, XPathConstants.NODESET);
			nodesLen = nodes.getLength();
			result.filters = new ArrayList<FilterAccessDescriptor>(nodesLen);
			for (int i = 0; i < nodesLen; i++) {
				Node n = nodes.item(i);
				FilterAccessDescriptor fad = result.createFilterDescriptor();
				fad.name = (String) xp.evaluate(prefix + "filter-name", n, XPathConstants.STRING);
				fad.className = (String) xp.evaluate(prefix + "filter-class", n, XPathConstants.STRING);
				if (fad.className == null)
					throw new ServletException(String.format("Filter %s specified without or empty class.", fad.name));
				else
					fad.className = fad.className.trim();
				fad.label = (String) xp.evaluate(prefix + "display-name", n, XPathConstants.STRING);
				fad.descr = (String) xp.evaluate(prefix + "description", n, XPathConstants.STRING);
				NodeList params = (NodeList) xp.evaluate(prefix + "init-param", n, XPathConstants.NODESET);
				fad.initParams = new HashMap<String, String>(params.getLength());
				for (int p = 0; p < params.getLength(); p++) {
					fad.initParams.put((String) xp.evaluate(prefix + "param-name", params.item(p),
							XPathConstants.STRING), (String) xp.evaluate(prefix + "param-value", params.item(p),
							XPathConstants.STRING));
				}
				result.filters.add(fad);
			}
			// process filter's mapping
			for (FilterAccessDescriptor fad : result.filters) {
				nodes = (NodeList) xp.evaluate(prefix + "filter-mapping[" + prefix + "filter-name=\"" + fad.name
						+ "\"]", document, XPathConstants.NODESET);
				nodesLen = nodes.getLength();
				if (nodesLen == 0)
					throw new ServletException(String.format("No mappings were found for filter %s", fad.name));
				for (int i = 0; i < nodesLen; i++) {
					Node n = nodes.item(i);
					NodeList clarifications = (NodeList) xp.evaluate(prefix + "url-pattern", n, XPathConstants.NODESET);
					int claLen = clarifications.getLength();
					for (int j = 0; j < claLen; j++) {
						String mapUrl = clarifications.item(j).getTextContent();
						if (mapUrl == null || mapUrl.length() == 0)
							continue;
						fad.add(new MappingEntry(clearPath(mapUrl), buildREbyPathPatt(mapUrl)));
					}
					clarifications = (NodeList) xp.evaluate(prefix + "dispatcher", n, XPathConstants.NODESET);
					claLen = clarifications.getLength();
					for (int j = 0; j < claLen; j++) {
						String filterType = clarifications.item(j).getTextContent();
						if (filterType == null || filterType.length() == 0)
							fad.add(DispatchFilterType.REQUEST);
						else
							fad.add(DispatchFilterType.valueOf(filterType));
					}
					clarifications = (NodeList) xp.evaluate(prefix + "servlet-name", n, XPathConstants.NODESET);
					claLen = clarifications.getLength();
					for (int j = 0; j < claLen; j++) {
						// adding servlet name
						fad.add(clarifications.item(j).getTextContent());
					}
				}
				result.newFilterInstance(fad);
			}
			// servlets
			nodes = (NodeList) xp.evaluate(prefix + "servlet", document, XPathConstants.NODESET);
			nodesLen = nodes.getLength();
			result.servlets = new ArrayList<ServletAccessDescr>(nodesLen + 1); // +jsp
			for (int i = 0; i < nodesLen; i++) {
				Node n = nodes.item(i);
				ServletAccessDescr sad = result.createDescriptor();
				sad.name = (String) xp.evaluate(prefix + "servlet-name", n, XPathConstants.STRING);
				sad.className = (String) xp.evaluate(prefix + "servlet-class", n, XPathConstants.STRING);
				if (sad.className == null || sad.className.length() == 0) {
					String jspFile = (String) xp.evaluate(prefix + "jsp-file", n, XPathConstants.STRING);
					if (jspFile != null) {
						result.log(String.format("Not supported servlet option jsp-file %s for %s, ignored.", jspFile,
								sad.name));
						continue;
					} else
						throw new ServletException(String.format("Servlet %s specified without class or jsp file.",
								sad.name));
				} else
					sad.className = sad.className.trim();
				sad.label = (String) xp.evaluate(prefix + "display-name", n, XPathConstants.STRING);
				sad.descr = (String) xp.evaluate(prefix + "description", n, XPathConstants.STRING);
				String loadOnStartVal = (String) xp.evaluate(prefix + "load-on-startup", n, XPathConstants.STRING);
				sad.loadOnStart = loadOnStartVal != null && loadOnStartVal.length() > 0;
				NodeList params = (NodeList) xp.evaluate(prefix + "init-param", n, XPathConstants.NODESET);
				sad.initParams = new HashMap<String, String>(params.getLength());
				for (int p = 0; p < params.getLength(); p++) {
					sad.initParams.put((String) xp.evaluate(prefix + "param-name", params.item(p),
							XPathConstants.STRING), (String) xp.evaluate(prefix + "param-value", params.item(p),
							XPathConstants.STRING));
				}
				result.servlets.add(sad);
			}
			// get mappings
			ServletAccessDescr wasDefault = null;
			for (ServletAccessDescr sad : result.servlets) {
				nodes = (NodeList) xp.evaluate(prefix + "servlet-mapping[" + prefix + "servlet-name=\"" + sad.name
						+ "\"]", document, XPathConstants.NODESET);
				nodesLen = nodes.getLength();
				// System.err.printf("Found %d mappings for %s%n", nodesLen, sad);
				if (nodesLen == 0) {
					// no mapping at all
					String urlPat = "/" + sad.name + "/*";
					sad.add(new MappingEntry(clearPath(urlPat), buildREbyPathPatt(urlPat)));
				} else
					for (int i = 0; i < nodesLen; i++) {
						NodeList maps = (NodeList) xp.evaluate(prefix + "url-pattern", nodes.item(i),
								XPathConstants.NODESET);
						int mapsLen = maps.getLength();
						// System.err.printf("Found %d patterns for %s%n", mapsLen, sad);
						if (mapsLen == 0) {
							// mapping with empty pattern
							String urlPat = "/" + sad.name + "/*";
							sad.add(new MappingEntry(clearPath(urlPat), buildREbyPathPatt(urlPat)));
						} else {
							for (int j = 0; j < mapsLen; j++) {
								String urlPat = maps.item(j).getTextContent();
								if (urlPat.equals("/"))
									if (wasDefault != null)
										throw new ServletException("More than one default servlets defined " + sad);
									else
										wasDefault = sad;
								sad.add(new MappingEntry(clearPath(urlPat), buildREbyPathPatt(urlPat)));
							}
						}
					}
				// System.err.printf("Servlet %s, path:%s\n", sad, sad.servPath);
				if (sad.loadOnStart)
					result.newInstance(sad);
			}
			// additional jsp mapping
			nodes = (NodeList) xp.evaluate(prefix + "jsp-config/" + prefix + "jsp-property-group/" + prefix
					+ "url-pattern", document, XPathConstants.NODESET);
			nodesLen = nodes.getLength();
			if (nodesLen > 0) {
				List<String> jspPats = new ArrayList<String>(nodesLen);
				for (int i = 0; i < nodesLen; i++) {
					jspPats.add(nodes.item(i).getTextContent());
				}
				result.addJSPServlet(jspPats);
			} else
				result.addJSPServlet(null);
			if (wasDefault != null) {
				// re-add at the end
				result.servlets.remove(wasDefault);
				result.servlets.add(wasDefault);
			}
			// welcome files
			nodes = (NodeList) xp.evaluate(prefix + "welcome-file-list/" + prefix + "welcome-file", document,
					XPathConstants.NODESET);
			result.welcomeFiles = new ArrayList<String>(nodes.getLength() + 1);
			nodesLen = nodes.getLength();
			if (nodesLen > 0)
				for (int wfi = 0; wfi < nodesLen; wfi++)
					result.welcomeFiles.add(nodes.item(wfi).getTextContent());
			else {
				result.welcomeFiles.add("index.html");
				result.welcomeFiles.add("index.jsp");
			}
			// error pages
			nodes = (NodeList) xp.evaluate(prefix + "error-page", document, XPathConstants.NODESET);
			nodesLen = nodes.getLength();
			if (nodesLen > 0) {
				result.errorPages = new ArrayList<ErrorPageDescr>(nodesLen);
				for (int i = 0; i < nodesLen; i++) {
					Node n = nodes.item(i);
					result.errorPages.add(new WebAppServlet.ErrorPageDescr((String) xp.evaluate(prefix + "location", n,
							XPathConstants.STRING), (String) xp.evaluate(prefix + "exception-type", n,
							XPathConstants.STRING), (String) xp.evaluate(prefix + "error-code", n,
							XPathConstants.STRING)));
				}
			}
			// mime types
			nodes = (NodeList) xp.evaluate(prefix + "mime-mapping", document, XPathConstants.NODESET);
			nodesLen = nodes.getLength();
			if (nodesLen > 0) {
				result.mimes = new HashMap<String, String>(nodesLen);
				for (int i = 0; i < nodesLen; i++) {
					Node n = nodes.item(i);
					result.mimes.put(((String) xp.evaluate(prefix + "extension", n, XPathConstants.STRING))
							.toLowerCase(), (String) xp.evaluate(prefix + "mime-type", n, XPathConstants.STRING));
				}
			}
		} catch (IOException ioe) {
			throw new ServletException("A problem in reading web.xml.", ioe);
		} catch (XPathExpressionException xpe) {
			xpe.printStackTrace();
			throw new ServletException("A problem in parsing web.xml.", xpe);
		} // finally { // streams will be closed by InputSource
		return result;
	}

	static <D extends ServletAccessDescr> void addMultiple(NodeList list, D d) {
		// TODO can be solution for more compact code
	}

	static public String buildREbyPathPatt(String pathPat) {
		if (pathPat.equals("/"))
			return "/.*";
		if (pathPat.startsWith("*."))
			return pathPat.replace(".", "\\.").replace("?", ".").replace("*", ".*").replace("|", "\\|"); // +"\\??.*";
		// TODO think more
		int wcp = pathPat.indexOf('*');
		if (wcp > 0 && pathPat.charAt(wcp - 1) == '/')
			pathPat = pathPat.substring(0, wcp - 1) + '*';
		pathPat = pathPat.replace(".", "\\.").replace("?", ".").replace("*", ".*");
		if (wcp < 0)
			if (pathPat.endsWith("/") == false)
				pathPat += "/?";
		return pathPat;
	}

	static public String clearPath(String pathMask) {
		if (pathMask.equals("/"))
			return pathMask;
		if (pathMask.startsWith("*."))
			return "/";
		int wcp = pathMask.indexOf('*');
		if (wcp < 0)
			return pathMask;
		return pathMask.substring(0, wcp);
	}

	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		// new Exception("call trace").printStackTrace();
		// TODO check access rights
		Thread.currentThread().setContextClassLoader(ucl);
		if (req.isSecure())
			fillSecureAttrs(req);
		final HttpServletRequest hreq = (HttpServletRequest) req;
		String path = hreq.getPathInfo();
		// TODO: wrap request to implement methods like getRequestDispatcher()
		// which supports relative path, no leading / means relative to currently called
		if (_DEBUG)
			System.err.printf("Full req:%s, ContextPath: %s, ServletPath:%s, pathInfo:%s\n", hreq.getRequestURI(), hreq
					.getContextPath(), hreq.getServletPath(), path);
		SimpleFilterChain sfc = new SimpleFilterChain();
		if (path != null) {
			// note a limitation, servlet name can't start with /WEB-INF
			if (path.regionMatches(true, 0, "/WEB-INF", 0, "/WEB-INF".length())) {
				((HttpServletResponse) res).sendError(HttpServletResponse.SC_FORBIDDEN);
				return;
			}
			for (FilterAccessDescriptor fad : filters)
				if (fad.matchDispatcher(DispatchFilterType.REQUEST) && fad.matchPath(path) >= 0)
					sfc.add(fad);
			for (ServletAccessDescr sad : servlets) {
				if (_DEBUG)
					System.err.println("Trying match " + path + " to " + Arrays.toString(sad.mapping) + " = "
							+ sad.matchPath(path));
				int patIndex;
				if ((patIndex = sad.matchPath(path)) >= 0) {
					if (sad.instance == null) {
						if (sad.loadOnStart == false)
							synchronized (sad) {
								if (sad.instance == null)
									newInstance(sad);
							}
						if (sad.instance == null) {
							sad.loadOnStart |= true; // mark unsuccessful instantiation and ban the servlet?
							((HttpServletResponse) res).sendError(HttpServletResponse.SC_GONE, "Servlet " + sad.name
									+ " hasn't been instantiated successfully or has been unloaded.");
							return;
						}
					} else {
						if (sad.timeToReactivate > 0) {
							if (sad.timeToReactivate > System.currentTimeMillis()) {
								((HttpServletResponse) res).setIntHeader("Retry-After", (int)(sad.timeToReactivate - System.currentTimeMillis())/1000+1);
								//((HttpServletResponse) res).setDateHeader("Retry-After", new Date(sad.timeToReactivate));
								((HttpServletResponse) res).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
								return;
							} else
								sad.timeToReactivate = 0;
						}
					}
					for (FilterAccessDescriptor fad : filters)
						if (fad.matchDispatcher(DispatchFilterType.REQUEST) && fad.matchServlet(sad.name) >= 0)
							sfc.add(fad);
					// sfc.add(fad.filterInstance);
					// System.err.println("used:"+ sad.servPath+", wanted:"+((WebAppServlet) sad.getServletContext()).contextPath);
					sfc.setFilter(new WebAppContextFilter(sad.mapping[patIndex].servPath));
					// add servlet in chain
					sfc.setServlet(sad);
					sfc.reset();
					sfc.doFilter(req, res);
					return;
				}
			}
		} else {
			((HttpServletResponse) res).sendRedirect(hreq.getRequestURI() + "/");
			return;
		}

		// no matching, process as file
		sfc.setFilter(new WebAppContextFilter());
		sfc.setServlet(new HttpServlet() {
			public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
				String path = ((HttpServletRequest) req).getPathTranslated();
				returnFileContent(path, (HttpServletRequest) req, (HttpServletResponse) res);
			}
		});
		sfc.reset();
		sfc.doFilter(req, res);
	}

	protected void fillSecureAttrs(ServletRequest req) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -