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

📄 servlets.java

📁 ZK 基础介绍 功能操作 模块 结合数据库操作
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
				//Bug or limitation of Catalina: not accepting HttpServletRequest				//othere than the original one or wrapper of original one				//				//Real Cause: org.apache.catalina.core.ApplicationDispatcher				//call unwrapRequest() twice, and then causes ClassCastException				//				//Resolution: since it is the almost last statement, it is safe				//to ignore this exception				if (!(request instanceof org.zkoss.web.portlet.RenderHttpServletRequest))					throw ex; //not the case described above			} finally {				restorePassThruAttr(request, old);			}		} else {			disp.forward(request, response);		}	}	/** A shortcut of forward(request, response, uri, null, 0).	 */	public static final 	void forward(ServletContext ctx, ServletRequest request,	ServletResponse response, String uri) throws IOException, ServletException {		forward(ctx, request, response, uri, null, 0);	}	/**	 * Includes the resource at the specified URI.	 * It enhances RequestDispatcher to allow the inclusion with	 * a parameter map -- acutually converting parameters to a query string	 * and appending it to uri.	 *	 * <p>NOTE: don't include query parameters in uri.	 *	 * @param ctx the servlet context. If null, uri cannot be foreign URI.	 * It is ignored if URI is relevant (neither starts with '/' nor '~').	 * @param uri the URI to include. It is OK to relevant (without leading	 * '/'). If starts with "/", the context path of request is assumed.	 * To reference to foreign context, use "~ctx/" where ctx is the	 * context path of the foreign context (without leading '/').	 * @param params the parameter map; null to ignore	 * @param mode one of {@link #OVERWRITE_URI}, {@link #IGNORE_PARAM},	 * and {@link #APPEND_PARAM}. It defines how to handle if both uri	 * and params contains the same parameter.	 */	public static final	void include(ServletContext ctx, ServletRequest request,	ServletResponse response, String uri, Map params, int mode)	throws IOException, ServletException {//		if (D.ON && log.debugable()) log.debug("Including "+uri+" at "+ctx);		//20050606: Tom Yeh		//We have to set this special attribute for jetty		//Otherwise, if including a page crossing context might not return		//the same session		request.setAttribute("org.mortbay.jetty.servlet.Dispatcher.shared_session", Boolean.TRUE);		final RequestDispatcher disp =			getRequestDispatcher(ctx, request, uri, params, mode);		if (disp == null)			throw new ServletException("No dispatcher available to include "+uri);		if (mode == PASS_THRU_ATTR && params != null && !params.isEmpty()) {			final Map old = setPassThruAttr(request, params);			try {				disp.include(request, response);			} finally {				restorePassThruAttr(request, old);			}		} else {			disp.include(request, response);		}	}	/** A shortcut of include(request, response, uri, null, 0).	 */	public static final 	void include(ServletContext ctx, ServletRequest request,	ServletResponse response, String uri) throws IOException, ServletException {		include(ctx, request, response, uri, null, 0);	}	/** Sets the arg attribute to pass parameters thru request's attribute.	 */	private static final	Map setPassThruAttr(ServletRequest request, Map params) {		final Map old = (Map)request.getAttribute(Attributes.ARG);		request.setAttribute(Attributes.ARG, params);		return old;	}	/** Restores what has been done by {@link #setPassThruAttr}.	 */	private static final	void restorePassThruAttr(ServletRequest request, Map old) {		if (old != null)			request.setAttribute(Attributes.ARG, old);		else			request.removeAttribute(Attributes.ARG);	}	/** Returns the request dispatch of the specified URI.	 *	 * @param ctx the servlet context. If null, uri cannot be foreign URI.	 * It is ignored if uri is relevant (neither starts with '/' nor '~').	 * @param request the request. If null, uri cannot be relevant.	 * It is used only if uri is relevant.	 * @param uri the URI to include. It is OK to relevant (without leading	 * '/'). If starts with "/", the context path of request is assumed.	 * To reference to foreign context, use "~ctx/" where ctx is the	 * context path of the foreign context (without leading '/').	 * @param params the parameter map; null to ignore	 * @param mode one of {@link #OVERWRITE_URI}, {@link #IGNORE_PARAM},	 * and {@link #APPEND_PARAM}. It defines how to handle if both uri	 * and params contains the same parameter.	 */	public static final RequestDispatcher	getRequestDispatcher(ServletContext ctx, ServletRequest request,	String uri, Map params, int mode)	throws ServletException {		final char cc = uri.length() > 0 ? uri.charAt(0): (char)0;		if (ctx == null || (cc != '/' && cc != '~')) {//... or relevant			if (request == null)				throw new IllegalArgumentException(					ctx == null ?						"Servlet context and request cannot be both null":						"Request is required to use revalant URI: "+uri);			if (cc == '~')				throw new IllegalArgumentException("Servlet context is required to use foreign URI: "+uri);			uri = generateURI(uri, params, mode);			return request.getRequestDispatcher(uri);		}		//NO NEED to encodeURL since it is forward/include		return new ParsedURI(ctx, uri).getRequestDispatcher(params, mode);	}	/** Returns the resource of the specified uri.	 * Unlike ServletContext.getResource, it handles "~" like	 * {@link #getRequestDispatcher} did.	 */	public static final URL getResource(ServletContext ctx, String uri)	throws MalformedURLException {		return new ParsedURI(ctx, uri).getResource();	}	/** Returns the resource stream of the specified uri.	 * Unlike ServletContext.getResource, it handles "~" like	 * {@link #getRequestDispatcher} did.	 */	public static final InputStream getResourceAsStream(	ServletContext ctx, String uri) {		return new ParsedURI(ctx, uri).getResourceAsStream();	}	/** Used to resolve "~" in URI. */	private static class ParsedURI {		private ServletContext _svlctx;		private ExtendletContext _extctx;		private String _uri;		private ParsedURI(final ServletContext ctx, final String uri) {			if (uri != null && uri.startsWith("~")) { //refer to foreign context				final int j = uri.indexOf('/', 1);				final String ctxroot;				if (j >= 0) {					ctxroot = "/" + uri.substring(1, j);					_uri = uri.substring(j);				} else {					ctxroot = "/" + uri.substring(1);					_uri = "/";				}				_extctx = getExtendletContext(ctx, ctxroot.substring(1));				if (_extctx == null) {					_svlctx = ctx.getContext(ctxroot);					if (_svlctx == null) 						throw new SystemException("Context not found or not visible to "+ctx+": "+ctxroot);				}			} else {				_svlctx = ctx;				_uri = uri;			}		}		private RequestDispatcher getRequestDispatcher(Map params, int mode) {			if (_extctx == null && _svlctx == null) //not found				return null;			final String uri = generateURI(_uri, params, mode);			return _svlctx != null ? _svlctx.getRequestDispatcher(uri):				_extctx.getRequestDispatcher(uri);		}		private URL getResource() throws MalformedURLException {			return _svlctx != null ? _svlctx.getResource(_uri):				_extctx != null ? _extctx.getResource(_uri): null;		}		private InputStream getResourceAsStream() {			return _svlctx != null ? _svlctx.getResourceAsStream(_uri):				_extctx != null ? _extctx.getResourceAsStream(_uri): null;		}	}	/** Whether to overwrite uri if both uri and params contain the same	 * parameter.	 * Used by {@link #generateURI}	 */	public static final int OVERWRITE_URI = 0;	/** Whether to ignore params if both uri and params contain the same	 * parameter.	 * Used by {@link #generateURI}	 */	public static final int IGNORE_PARAM = 1;	/** Whether to append params if both uri and params contain the same	 * parameter. In other words, they both appear as the final query string.	 * Used by {@link #generateURI}	 */	public static final int APPEND_PARAM = 2;	/** Whether the specified parameters shall be passed thru the request	 * attribute called arg.	 */	public static final int PASS_THRU_ATTR = 3;	/** Generates URI by appending the parameters.	 * Note: it doesn't support the ~xxx/ format.	 *	 * @param params the parameters to apend to the query string	 * @param mode one of {@link #OVERWRITE_URI}, {@link #IGNORE_PARAM},	 * {@link #APPEND_PARAM} and {@link #PASS_THRU_ATTR}.	 * It defines how to handle if both uri and params contains the same	 * parameter.	 * mode is used only if both uri contains query string and params is	 * not empty.	 * @see Encodes#encodeURL(ServletContext, ServletRequest, ServletResponse, String)	 */	public static final String generateURI(String uri, Map params, int mode) {		if (uri.startsWith("~"))			throw new IllegalArgumentException("~ctx not supported here: "+uri);		final int j = uri.indexOf('?');		String qstr = null;		if (j >= 0) {			qstr = uri.substring(j);			uri = uri.substring(0, j);		}		//if (D.ON && uri.indexOf('%') >= 0)		//	log.warning(new IllegalStateException("You might encode URL twice: "+uri));		//might too annoying		try {			uri = Encodes.encodeURI(uri);			final boolean noQstr = qstr == null;			final boolean noParams =				mode == PASS_THRU_ATTR || params == null || params.isEmpty();			if (noQstr && noParams)				return uri;			if (noQstr != noParams)				mode = APPEND_PARAM;			final StringBuffer sb = new StringBuffer(80).append(uri);			if (qstr != null) sb.append(qstr);			switch (mode) {			case IGNORE_PARAM:				//removing params that is conflict				for (final Iterator it = params.entrySet().iterator();				it.hasNext();) {					final Map.Entry me = (Map.Entry)it.next();					final String nm = (String)me.getKey();					if (Encodes.containsQuery(qstr, nm))						it.remove();				}				//flow thru			case OVERWRITE_URI:				return Encodes.setToQueryString(sb, params).toString();			case APPEND_PARAM:				return Encodes.addToQueryString(sb, params).toString();			default:				throw new IllegalArgumentException("Unknown mode: "+mode);			}		} catch (UnsupportedEncodingException ex) {			throw new SystemException(ex);		}	}	/** A list of context root paths (e.g., "/abc"). */	private static List _ctxroots;	/** Returns a list of context paths (e.g., "/abc") that this application	 * has. This implementation parse application.xml. For war that doesn't	 * contain application.xml might have to override this method and	 * parse another file to know what context being loaded.	 */	public static final List getContextPaths() {		if (_ctxroots != null)			return _ctxroots;		try {			synchronized (Servlets.class) {				return _ctxroots = myGetContextPaths();			}		} catch (Exception ex) {			throw SystemException.Aide.wrap(ex);		}	}	private static final List myGetContextPaths() throws Exception {		final String APP_XML = "/META-INF/application.xml";		final List ctxroots = new LinkedList();		final URL xmlURL = Locators.getDefault().getResource(APP_XML);		if (xmlURL == null)			throw new SystemException("File not found: "+APP_XML);//		if (log.debugable()) log.debug("Parsing "+APP_XML);		final Element root =			new SAXBuilder(false,false,true).build(xmlURL).getRootElement();		for (Iterator it = root.getElements("module").iterator();		it.hasNext();) {			final Element e = (Element)it.next();			final String ctxroot = (String)e.getContent("web/context-root");			if (ctxroot == null) {//				if (D.ON && log.finerable()) log.finer("Skip non-web: "+e.getContent("java"));				continue;			}			ctxroots.add(ctxroot.startsWith("/") ? ctxroot: "/" + ctxroot);		}//		log.info("Context found: "+ctxroots);		return new ArrayList(ctxroots);	}	/** Returns a token to represent a limit-time offer.	 * It is mainly used as an parameter value (mostlycalled zk_lto), and then	 * you could verify whether it is expired by {@link #isOfferExpired}.	 */	public static final String getLimitTimeOffer() {		final String lto = Long.toHexString(System.currentTimeMillis());		return lto + Checksums.getChecksum(lto, "");	}	/** Returns whether a token returned by getLimitTimeOffer expired.	 * @param timeout how long the office shall expire, unit: seconds.	 */	public static final boolean isOfferExpired(String lto, int timeout) {		final int len = lto != null ? lto.length(): 0;		if (len <= 1)			return true;		final char cksm = lto.charAt(len - 1);		lto = lto.substring(0, len - 1);		if (cksm != Checksums.getChecksum(lto, ""))			return true;		try {			return Long.parseLong(lto, 16) + timeout*1000L				< System.currentTimeMillis();		} catch (NumberFormatException ex) {			return true;		}	}	/** Adds an extended context.	 * @return the previous extended context, if any, associated with	 * the specified name.	 */	public static final	ExtendletContext addExtendletContext(ServletContext ctx,	String name, ExtendletContext extctx) {		if (name == null || extctx == null)			throw new IllegalArgumentException("null");		return (ExtendletContext)getExtWebCtxs(ctx).put(name, extctx);	}	/** Removes an extended context of the specified name.	 */	public static final	ExtendletContext removeExtendletContext(ServletContext ctx, String name) {		return (ExtendletContext)getExtWebCtxs(ctx).remove(name);	}	/** Returns the extended context of the specified name.	 */	public static final	ExtendletContext getExtendletContext(ServletContext ctx, String name) {		return (ExtendletContext)getExtWebCtxs(ctx).get(name);	}	private static final Map getExtWebCtxs(ServletContext ctx) {		synchronized (Servlets.class) { //don't use ctx because it might be a proxy (in portlet)			final String attr = "javax.zkoss.web.servlets.ExtendletContexts";				//such that it could be shared among portlets			Map ctxs = (Map)ctx.getAttribute(attr);			if (ctxs == null)				ctx.setAttribute(attr,					ctxs = Collections.synchronizedMap(new HashMap(5)));			return ctxs;		}	}	/** Returns the file extension of the specified path, or null	 * if no extension at all.	 *	 * <p>Note: the extension is converted to the lower case.	 *	 * <p>Note: it assumes the session ID, if any, starts with semicolon.	 * For example, the path could be "/a/b.zul;jsession=xxx".	 *	 * @param path the path. If path is null, null is returned.	 * @since 2.4.1	 */	public static final String getExtension(String path) {		if (path != null) {			int j = path.lastIndexOf('.');			if (j >= 0 && path.indexOf('/', j + 1) < 0) {				final String ext = path.substring(j + 1);				j = ext.indexOf(';');				return j >= 0 ? ext.substring(0, j).toLowerCase(): ext.toLowerCase();			}		}		return null;	}}

⌨️ 快捷键说明

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