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

📄 encodes.java

📁 ZK 基础介绍 功能操作 模块 结合数据库操作
💻 JAVA
字号:
/* Encodes.java{{IS_NOTE	Purpose:			Description:			History:		Fri Jun 21 14:13:50  2002, Created by tomyeh}}IS_NOTECopyright (C) 2002 Potix Corporation. All Rights Reserved.{{IS_RIGHT	This program is distributed under GPL Version 2.0 in the hope that	it will be useful, but WITHOUT ANY WARRANTY.}}IS_RIGHT*/package org.zkoss.web.servlet.http;import java.util.Arrays;import java.util.Map;import java.util.Set;import java.util.HashSet;import java.util.Locale;import java.util.Iterator;import java.io.UnsupportedEncodingException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.ServletContext;import org.zkoss.lang.D;import org.zkoss.lang.Objects;import org.zkoss.util.logging.Log;import org.zkoss.web.Attributes;import org.zkoss.web.servlet.Servlets;import org.zkoss.web.servlet.Charsets;import org.zkoss.web.util.resource.ExtendletContext;/** * Encoding utilities for servlets. * * @author tomyeh * @see Https */public class Encodes {	private static final Log log = Log.lookup(Encodes.class);	/** Encodes a string to HTTP URI compliant by use of	 * {@link Charsets#getURICharset}.	 *	 * <p>Besides two-byte characters, it also encodes any character found	 * in unsafes.	 *	 * @param unsafes the set of characters that must be encoded; never null.	 * It must be sorted.	 */	private static final String encodeURI0(String s, char[] unsafes)	throws UnsupportedEncodingException {		if (s == null)			return null;		final String charset = Charsets.getURICharset();		final byte[] in = s.getBytes(charset);		final byte[] out = new byte[in.length * 3];//at most: %xx		int j = 0, k = 0;		for (; j < in.length; ++j) {			//Though it is ok to use '+' for ' ', Jetty has problem to			//handle space between chinese characters.			final char cc = (char)(((int)in[j]) & 0xff);			if (cc >= 0x80 || cc <= ' '			|| Arrays.binarySearch(unsafes, cc) >= 0) {				out[k++] = (byte)'%';				String cvt = Integer.toHexString(cc);				if (cvt.length() == 1) {					out[k++] = (byte)'0';					out[k++] = (byte)cvt.charAt(0);				} else {					out[k++] = (byte)cvt.charAt(0);					out[k++] = (byte)cvt.charAt(1);				}			} else {				out[k++] = in[j];			}		}		return j == k ? s: new String(out, 0, k, charset);	}	/** unsafe character when that are used in url's localtion. */	private static final char[] URI_UNSAFE;	/** unsafe character when that are used in url's query. */	private static final char[] URI_COMP_UNSAFE;	static {		URI_UNSAFE = "`%^{}[]\\\"<>|".toCharArray();		Arrays.sort(URI_UNSAFE);		URI_COMP_UNSAFE = "`%^{}[]\\\"<>|$&,/:;=?".toCharArray();		Arrays.sort(URI_COMP_UNSAFE);	}	/** Does the HTTP encoding for the URI location.	 * For example, '%' is translated to '%25'.	 *	 * <p>Since {@link #encodeURL(ServletContext, ServletRequest, ServletResponse, String)}	 * will invoke this method automatically, you rarely need this method.	 *	 * @param s the string to encode; null is OK	 * @return the encoded string or null if s is null	 * @see #encodeURIComponent	 */	public static final String encodeURI(String s)	throws UnsupportedEncodingException {		return encodeURI0(s, URI_UNSAFE);	}	/** Does the HTTP encoding for a URI query parameter.	 * For example, '/' is translated to '%2F'.	 * Both name and value must be encoded seperately. Example,	 * <code>encodeURIComponent(name) + '=' + encodeURIComponent(value)</code>.	 *	 * <p>Since {@link #encodeURL(ServletContext, ServletRequest, ServletResponse, String)}	 * will <i>not</i> invoke this method automatically, you'd better	 * to encode each query parameter by this method or	 * {@link #addToQueryString(StringBuffer,Map)}.	 *	 * @param s the string to encode; null is OK	 * @return the encoded string or null if s is null	 * @see #addToQueryString(StringBuffer,String,Object)	 * @see #encodeURI	 */	public static final String encodeURIComponent(String s)	throws UnsupportedEncodingException {		return encodeURI0(s, URI_COMP_UNSAFE);	}	/**	/** Appends a map of parameters (name=value) to a query string.	 * It returns the query string preceding with '?' if any parameter exists,	 * or an empty string if no parameter at all. Thus, you could do	 *	 * <p><code>request.getRequestDispatcher(<br>	 * addToQueryStirng(new StringBuffer(uri), params).toString());</code>	 *	 * <p>Since RequestDispatcher.include and forward do not allow wrapping	 * the request and response -- see spec and the implementation of both	 * Jetty and Catalina, we have to use this method to pass the parameters.	 *	 * @param params a map of parameters; format: (String, Object) or	 * (String, Object[]); null is OK	 */	public static final StringBuffer	addToQueryString(StringBuffer sb, Map params)	throws UnsupportedEncodingException {		if (params != null) {			for (Iterator it = params.entrySet().iterator(); it.hasNext();) {				final Map.Entry me = (Map.Entry)it.next();				addToQueryString(sb, (String)me.getKey(), me.getValue());			}		}		return sb;	}	/** Appends a parameter (name=value) to a query string.	 * This method automatically detects whether other query is already	 * appended. If so, &amp; is used instead of ?.	 *	 * <p>The query string might contain servlet path and other parts.	 * This method starts the searching from the first '?'.	 * If the query string doesn't contain '?', it is assumed to be a string	 * without query's name/value pairs.	 *	 * @param value the value. If it is null, only name is appened.	 * If it is an array of objects, multipe pairs of name=value[j] will	 * be appended.	 */	public static final StringBuffer	addToQueryString(StringBuffer sb, String name, Object value)	throws UnsupportedEncodingException {		if (value instanceof Object[]) {			final Object[] vals = (Object[])value;			if (vals.length == 0) {				value = null; //only append name			} else {				for (int j = 0; j < vals.length; ++j)					addToQueryString(sb, name, vals[j]);				return sb; //done			}		}		sb.append(next(sb, '?', 0) >= sb.length() ? '?': '&');		sb.append(encodeURIComponent(name)).append('=');			//NOTE: jetty with jboss3.0.6 ignore parameters without '=',			//so we always append '=' even value is null		if (value != null)			sb.append(encodeURIComponent(Objects.toString(value)));		return sb;	}	/** Returns the first occurrence starting from j, or sb.length().	 */	private static final int next(StringBuffer sb, char cc, int j) {		for (final int len = sb.length(); j < len; ++j)			if (sb.charAt(j) == cc)				break;		return j;	}	/**	 * Sets the parameter (name=value) to a query string.	 * If the name already exists in the query string, it will be removed first.	 * If your name has appeared in the string, it will replace	 * your new value to the query string.	 * Otherwise, it will append the name/value to the new string. 	 *	 * <p>The query string might contain servlet path and other parts.	 * This method starts the searching from the first '?'.	 * If the query string doesn't contain '?', it is assumed to be a string	 * without query's name/value pairs.	 *	 * @param str The query string like xxx?xxx=xxx&xxx=xxx or null.	 * @param name The get parameter name.	 * @param value The value associated with the get parameter name. 	 * @return The new or result query string with your name/value.	 * @see #addToQueryString	 */	public static final	String setToQueryString(String str, String name, Object value)	throws UnsupportedEncodingException {		final StringBuffer sb = new StringBuffer();		if (str != null)			sb.append(str);		return setToQueryString(sb, name, value).toString();	}	/**	 * Sets the parameter (name=value) to a query string.	 * If the name already exists in the query string, it will be	 * removed first.	 * @see #addToQueryString	 */	public static final StringBuffer	setToQueryString(StringBuffer sb, String name, Object value)	throws UnsupportedEncodingException {		removeFromQueryString(sb, name);		return addToQueryString(sb, name, value);	}	/**	 * Sets a map of parameters (name=value) to a query string.	 * If the name already exists in the query string, it will be removed first.	 * @see #addToQueryString	 */	public static final String setToQueryString(String str, Map params)	throws UnsupportedEncodingException {		return setToQueryString(new StringBuffer(str), params).toString();	}	/**	 * Sets a map of parameters (name=value) to a query string.	 * If the name already exists in the query string, it will be removed first.	 * @see #addToQueryString	 */	public static final StringBuffer 	setToQueryString(StringBuffer sb, Map params)	throws UnsupportedEncodingException {		if (params != null) {			for (Iterator it = params.entrySet().iterator(); it.hasNext();) {				final Map.Entry me = (Map.Entry)it.next();				setToQueryString(sb, (String)me.getKey(), me.getValue());			}		}		return sb;	}	/** Tests whether a parameter exists in the query string.	 */	public static final boolean containsQuery(String str, String name) {		int j = str.indexOf(name);		if (j <= 0)			return false;		char cc = str.charAt(j - 1);		if (cc != '?' && cc != '&')			return false;		j += name.length();		if (j >= str.length())			return true;		cc = str.charAt(j);		return cc == '=' || cc == '&';	}	/** Remove all name/value pairs of the specified name from a string.	 *	 * <p>The query string might contain servlet path and other parts.	 * This method starts the searching from the last '?'.	 * If the query string doesn't contain '?', it is assumed to be a string	 * without query's name/value pairs.	 * @see #addToQueryString	 */	public static final	String removeFromQueryString(String str, String name)	throws UnsupportedEncodingException {		if (str == null)			return null;		int j = str.indexOf('?');		if (j < 0)			return str;		final StringBuffer sb = new StringBuffer(str);		removeFromQueryString(sb, name);		return sb.length() == str.length() ? str: sb.toString();	}	/** Remove all name/value pairs of the specified name from a string.	 * @see #addToQueryString	 */	public static final StringBuffer	removeFromQueryString(StringBuffer sb, String name)	throws UnsupportedEncodingException {		name = encodeURIComponent(name);		int j = sb.indexOf("?");		if (j < 0)			return sb; //no '?'		j = sb.indexOf(name, j + 1);		if (j < 0)			return sb; //no name		final int len = name.length();		do {			//1. make sure left is & or ?			int k = j + len;			char cc = sb.charAt(j - 1);			if (cc != '&' && cc != '?') {				j = k;				continue;			}			//2. make sure right is = or & or end-of-string			if (k < sb.length()) {				cc = sb.charAt(k);				if (cc != '=' && cc != '&') {					j = k;					continue;				}			}			//3. remove it until next & or end-of-string			k = next(sb, '&', k);			if (k < sb.length())				sb.delete(j, k + 1); //also remove '&'			else				sb.delete(j - 1, k); //also preceding '?' or '&'		} while ((j = sb.indexOf(name, j)) > 0);		return sb;	}	/** Encodes a URL.	 * It resolves "*" contained in URI, if any, to the proper Locale,	 * and the browser code.	 * Refer to {@link Servlets#locate(ServletContext, ServletRequest, String, Locator)}	 * for details. 	 *	 * <p>In additions, if uri starts with "/", the context path, e.g.,	 * /zkdemo, is prefixed.	 * In other words, "/ab/cd" means it is relevant to the servlet	 * context path (say, "/zkdemo").	 *	 * <p>If uri starts with "~abc/", it means it is relevant to a foreign	 * Web context called /abc. And, it will be converted to "/abc/" first	 * (without prefix request.getContextPath()).	 *	 * <p>Finally, the uri is encoded by HttpServletResponse.encodeURL.	 *	 * <p>This method invokes {@link #encodeURI} for any characters	 * before '?'. However, it does NOT encode any character after '?'. Thus,	 * you might hvae to invoke	 * {@link #encodeURIComponent} or {@link #addToQueryString(StringBuffer,Map)}	 * to encode the query parameters.	 *	 * @param request the request; never null	 * @param response the response; never null	 * @param uri it must be empty or starts with "/". It might contain	 * "*" for current browser code and Locale.	 * @param ctx the servlet context; used only if "*" is contained in uri	 * @exception IndexOutOfBoundException if uri is empty	 * @see org.zkoss.web.servlet.Servlets#locate	 * @see org.zkoss.web.servlet.Servlets#generateURI	 */	public static final String encodeURL(ServletContext ctx,	ServletRequest request, ServletResponse response, String uri)	throws ServletException {		try {			return encodeURL0(ctx, request, response, uri);		} catch (Exception ex) {			log.realCause(ex);			throw new ServletException("Unable to encode "+uri, ex);		}	}	private static final String encodeURL0(ServletContext ctx,	ServletRequest request, ServletResponse response, String uri)	throws Exception {		if (uri == null || uri.length() == 0)			return uri; //keep as it is		boolean ctxpathSpecified = false;		if (uri.charAt(0) != '/') { //NOT relative to context path			if (Servlets.isUniversalURL(uri)) return uri; //nothing to do			if (uri.charAt(0) == '~') { //foreign context				final String ctxroot;				if (uri.length() == 1) {					ctxroot = uri = "/";				} else if (uri.charAt(1) == '/') {					ctxroot = "/";					uri = uri.substring(1);				} else {					uri = '/' + uri.substring(1);					final int j = uri.indexOf('/', 1);					ctxroot = j >= 0 ? uri.substring(0, j): uri;				}				final ExtendletContext extctx =					Servlets.getExtendletContext(ctx, ctxroot.substring(1));				if (extctx != null) {					final int j = uri.indexOf('/', 1);					return extctx.encodeURL(request, response,						j >= 0 ? uri.substring(j): "/");				}				final ServletContext newctx = ctx.getContext(ctxroot);				if (newctx != null) {					ctx = newctx;				} else if (D.ON && log.debugable()) {					log.debug("Context not found: "+ctxroot);				}				ctxpathSpecified = true;			} else if (Https.isIncluded(request) || Https.isForwarded(request)) {				//if reletive URI and being included/forwarded,				//converts to absolute				String pgpath = Https.getThisServletPath(request);				if (pgpath != null) {					int j = pgpath.lastIndexOf('/');					if (j >= 0) {						uri = pgpath.substring(0, j + 1) + uri;					} else {						log.warning("The current page doesn't contain '/':" + pgpath);					}				}			}		}		//locate by locale and browser if necessary		uri = Servlets.locate(ctx, request, uri, null);		//prefix context path		if (!ctxpathSpecified && uri.charAt(0) == '/'		&& (request instanceof HttpServletRequest)) {			//Work around with a bug when we wrap Pluto's RenderRequest (1.0.1)			String ctxpath = ((HttpServletRequest)request).getContextPath();			if (ctxpath.length() > 0 && ctxpath.charAt(0) != '/')				ctxpath = '/' + ctxpath;			uri = ctxpath + uri;		}		int j = uri.indexOf('?');		if (j < 0) {			uri = encodeURI(uri);		} else {			uri = encodeURI(uri.substring(0, j)) + uri.substring(j);		}		//encode		if (response instanceof HttpServletResponse)			uri = ((HttpServletResponse)response).encodeURL(uri);		return uri;	}}

⌨️ 快捷键说明

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