From 5c65c2f5b51a064802cce719d0aa7a2f72ceece1 Mon Sep 17 00:00:00 2001 From: rudolf Date: Mon, 17 Jan 2005 11:21:52 +0000 Subject: Servlet Filter to keep the parameters in right order. git-svn-id: https://joinup.ec.europa.eu/svn/moa-idspss/trunk@215 d688527b-c9ab-4aba-bd8d-4036d912da1d --- .../moa/id/util/InOrderServletRequestWrapper.java | 345 +++++++++++++++++++++ .../moa/id/util/ParameterInOrderFilter.java | 62 ++++ 2 files changed, 407 insertions(+) create mode 100644 id.server/src/at/gv/egovernment/moa/id/util/InOrderServletRequestWrapper.java create mode 100644 id.server/src/at/gv/egovernment/moa/id/util/ParameterInOrderFilter.java (limited to 'id.server/src/at/gv/egovernment') diff --git a/id.server/src/at/gv/egovernment/moa/id/util/InOrderServletRequestWrapper.java b/id.server/src/at/gv/egovernment/moa/id/util/InOrderServletRequestWrapper.java new file mode 100644 index 000000000..78d0a0db0 --- /dev/null +++ b/id.server/src/at/gv/egovernment/moa/id/util/InOrderServletRequestWrapper.java @@ -0,0 +1,345 @@ +/* + * Created on 01.10.2004 + * + * @author rschamberger + * $ID$ + */ +package at.gv.egovernment.moa.id.util; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequestWrapper; + +import at.gv.egovernment.moa.util.URLDecoder; + +/** + * Special ServletRequestWrapper class which provides a more precise implementation of the getParameter* + * family. This implementation cares about the order of the parameters from Query String and HTTP POST + * Body. Use this as Filter class for Servlets which such needs. + * + * @author Rudolf Schamberger + * @version $Id$ + */ +public class InOrderServletRequestWrapper extends HttpServletRequestWrapper { + + /** + * standard encoding used to decode the URL string. + */ + // + public static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1"; + /** + * Vector that stores the order of the query paramters + */ + private Vector queryParamOrder; + + /** + * Hashtable that stores the content of the query paramters + */ + private Hashtable queryParameters; + + /** + * Vector that stores the order of the HTTP body paramters + */ + private Vector bodyParamOrder; + + /** + * Hashtable that stores the content of the HTTP body paramters + */ + private Hashtable bodyParameters; + + /** + * ServletContext + */ + private ServletContext context; + + /** + * Identifier used to identify query parameters + */ + public static final int QUERY_PARAM = 1; + + /** + * Identifier used to identify HTTP body parameters + */ + public static final int BODY_PARAM = 2; + + /** + * @see HttpServletRequestWrapper + */ + public InOrderServletRequestWrapper(final HttpServletRequest request, final ServletContext sContext) { + super(request); + this.context = sContext; + } + + /** + * parses the Query and if availlable also HTTP POST parameters + * + * @param req a HttpServletRequest which should be parsed + */ + protected final void parseParameters(final HttpServletRequest req) + { + queryParamOrder = new Vector(); + queryParameters = new Hashtable(); + bodyParamOrder = new Vector(); + bodyParameters = new Hashtable(); + + //Insert code for Query string parsing + String rawQuery = req.getQueryString(); + queryParameters = tokenize(queryParameters, queryParamOrder, rawQuery, DEFAULT_CHARACTER_ENCODING); + + //analyze HTTP Post body parameters + if (req.getMethod().equalsIgnoreCase("POST")) + { + //get body encoding + String enc = req.getCharacterEncoding(); + if (enc == null) enc = DEFAULT_CHARACTER_ENCODING; + + if (req.getContentType().equals("application/x-www-form-urlencoded")) + { + try + { + bodyParameters = parsePostData(bodyParameters, req.getContentLength(), req.getInputStream(), enc); + } + catch (IOException e) + { + context.log("could not open input stream of reqest \n" + e.toString()); + } + } + else + { + //TODO add multipart code + context.log( + "ERROR other Content-Types than 'application/x-www-form-urlencoded' not supported!"); + } + + }// end POST + } + + /** + * parses the HTTP POST parameters + * + * @param ht parameter Hashtable to put parameters in. + * @param length of content + * @param instream the ServletInputStream of the request + * @param encoding encoding of the instream + * + * @return the Hashtable with the parsed data + */ + private Hashtable parsePostData(Hashtable ht, final int length, final ServletInputStream instream, + final String encoding) + { + int inputLen, offset; + byte[] postedBytes = null; + boolean dataRemaining = true; + String postedBody; + + StringBuffer sb = new StringBuffer(); + + if (length <= 0) + { + return null; + } + + postedBytes = new byte[length]; + try + { + offset = 0; + while (dataRemaining) + { + inputLen = instream.read(postedBytes, offset, length - offset); + if (inputLen <= 0) + { + throw new IOException("read error during reading the HTTP POST body"); + } + offset += inputLen; + if ((length - offset) == 0) + { + dataRemaining = false; + } + } + } + catch (IOException e) + { + System.out.println("Exception =" + e); + return null; + } + + postedBody = new String(postedBytes); + Hashtable ht2 = tokenize(ht, bodyParamOrder, postedBody, encoding); + return ht2; + } + + + /** + * tokenizes parameter strings + * + * @param ht parameter Hashtable to put parameters in. + * @param order Vector in which the order of the tokenized parameters will be stored. + * @param parameterString String to tokenize. + * @param encoding which will be used to decode the parameterString. + * + * @return the Hashtable with the parsed data + */ + private Hashtable tokenize(Hashtable ht, Vector order, final String parameterString, final String encoding) + { + String[] valArray = null; + + if (null == parameterString) return ht; + + StringTokenizer st = new StringTokenizer(parameterString, "&"); + + String key = null; + String val = null; + + while (st.hasMoreTokens()) + { + String pair = (String) st.nextToken(); + int pos = pair.indexOf('='); + if (pos == -1) + { + throw new IllegalArgumentException(); + } + try + { + key = URLDecoder.decode(pair.substring(0, pos), encoding); + val = URLDecoder.decode(pair.substring(pos + 1, pair.length()), encoding); + } + catch (Exception e) + { + throw new IllegalArgumentException(); + } + if (ht.containsKey(key)) + { + String oldVals[] = (String[]) ht.get(key); + valArray = new String[oldVals.length + 1]; + for (int i = 0; i < oldVals.length; i++) + { + valArray[i] = oldVals[i]; + } + valArray[oldVals.length] = val; + } + else + { + valArray = new String[1]; + valArray[0] = val; + } + ht.put(key, valArray); + order.addElement(key); + } + return ht; + + } + + /** + * Returns the value of a request parameter as a String, or null if the + * parameter does not exist. Request parameters are extra information sent with the request. For HTTP + * servlets, parameters are contained in the query string or posted form data. + * + *

+ * You should only use this method when you are sure the parameter has only one value. If the parameter + * might have more than one value, use {@link #getParameterValues}. + * + *

+ * If you use this method with a multivalued parameter, the value returned is equal to the first value in + * the array returned by getParameterValues. + * + *

+ * If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then + * reading the body directly via {@link#getInputStream} or {@link #getReader}can interfere with the + * execution of this method. + * + * @param name a String containing the name of the parameter whose value is requested + * + * @return a String representing the single value of the parameter + * + * @see #getParameterValues + * + */ + public final String getParameter(final String name) { + String val = getParameter(name, QUERY_PARAM); + return (null != val) ? val : getParameter(name, BODY_PARAM); + } + + /** + * Returns the value of a request parameter as a String, or null if the + * parameter does not exist. + * + * @param name a String containing the name of the parameter whose value is requested + * @param parameterType type of parameter + * @see at.gv.egovernment.moa.id.util.ParametersInOrderServlet#QUERY_PARAM + * and @see at.gv.egovernment.moa.id.util.ParametersInOrderServlet#BODY_PARAM + * @see getParameterValues(String name); + * @return value of the (single) parameter or null if not availlable + **/ + public final String getParameter(final String name, final int parameterType) + { + + Hashtable parameters = (parameterType == QUERY_PARAM) ? queryParameters : bodyParameters; + String[] vals = (String[]) parameters.get(name); + if (vals == null) + { + return null; + } + return vals[0]; + } + + + /** + * Returns an array of String objects containing all of the values the given request + * parameter has, or null if the parameter does not exist. + * + *

+ * If the parameter has a single value, the array has a length of 1. + * + * @param name a String containing the name of the parameter whose value is requested + * @param parameterType type of parameter + * @see at.gv.egovernment.moa.id.util.ParametersInOrderServlet#QUERY_PARAM + * and @see at.gv.egovernment.moa.id.util.ParametersInOrderServlet#BODY_PARAM + * @return an array of String objects containing the parameter's values or null + * + * @see #getParameter + */ + public final String getParameterValues(final String name, final int parameterType) + { + Hashtable parameters = (parameterType == QUERY_PARAM) ? queryParameters : bodyParameters; + String[] vals = (String[]) parameters.get(name); + if (vals == null) + { + return null; + } + String vallist = vals[0]; + for (int i = 1; i < vals.length; i++) + { + vallist = vallist + "," + vals[i]; + } + return vallist; + } + + /** + * + * Returns an Enumeration of String objects containing the names of the + * parameters contained in this request. If the request has no parameters, the method returns an empty + * Enumeration. + * @param parameterType type of parameter + * @see at.gv.egovernment.moa.id.util.ParametersInOrderServlet#QUERY_PARAM + * and @see at.gv.egovernment.moa.id.util.ParametersInOrderServlet#BODY_PARAM + * + * @return an Enumeration of String objects, each String + * containing the name of a request parameter; or an empty Enumeration if the + * request has no parameters + * + */ + public final Enumeration getParameterNames(final int parameterType) + { + if (QUERY_PARAM == parameterType) + return queryParamOrder.elements(); + else + return bodyParamOrder.elements(); + } +} //End InOrderServletRequestWrapper \ No newline at end of file diff --git a/id.server/src/at/gv/egovernment/moa/id/util/ParameterInOrderFilter.java b/id.server/src/at/gv/egovernment/moa/id/util/ParameterInOrderFilter.java new file mode 100644 index 000000000..3f5fddba2 --- /dev/null +++ b/id.server/src/at/gv/egovernment/moa/id/util/ParameterInOrderFilter.java @@ -0,0 +1,62 @@ +package at.gv.egovernment.moa.id.util; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +/** + * @author rschamberger + * + */ +/** + * A Filter class wich uses the InOrderServletRequestWrapper to provide servlets a more precise + * implementation of the getParameter* family. This implementation cares about the order of the parameters + * from Query String and HTTP POST Body. Use this as Filter class for Servlets which such needs. + * + * @author Rudolf Schamberger + * @version $Id$ + */ +public class ParameterInOrderFilter implements Filter +{ + + /** + * filterConfig + */ + private FilterConfig filterConfig; + + /** + * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) + */ + public final void init(final FilterConfig config) + { + this.filterConfig = config; + } + + /** + * @see javax.servlet.Filter#destroy() + */ + public final void destroy() + { + }; + + /** + * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, + * javax.servlet.FilterChain) + */ + public final void doFilter(final ServletRequest request, final ServletResponse response, + final FilterChain chain) throws IOException, ServletException + { + InOrderServletRequestWrapper sRequ = new InOrderServletRequestWrapper((HttpServletRequest) request, + filterConfig.getServletContext()); + //parse the Query (and Body) parameters + sRequ.parseParameters((HttpServletRequest) request); + //process the rest of filter chain + chain.doFilter(sRequ, response); + } +} \ No newline at end of file -- cgit v1.2.3