Hi, Sling currently does not allow to read request parameters in their original order. I need this for a migrated servlet code that used to run on other servlet containers and was able to preserve the order (see below), thus has URL schemes where paramter order is crucial.
Actually it is the java servlet spec that messed up things here: the HTML forms definition [1] clearly says that the order in the form encoding should be preserved (both for GET and POST), but the servlet API uses the "Map" interface and doesn't specify that this has to be an ordered map. Hence most/all the servlet containers implement this using a HashMap (Jetty [2], Adobe's CQSE; only Tomcat seems to be an exception [3]), and you can't rely on it. Note that while Sling does try to _ensure_ the order of parameters as noted on [4], this only means it keeps the container order, and only for the special case of "multipart/form-data" POSTs, where Sling actually does the decoding itself and does not use the servlet containers implicit decoding. However, the majority of POSTs and the ones I care about are not in multipart. Now, there can be a workaround: simply parse it yourself: - GET: use request.getQueryString() - POST: use request.getReader() This is what the servlet code base I mention is doing. However, the POST case relies on the fact that getReader() hasn't been called yet. But this is easily the case with form POSTs, since the first request.getParameter() will trigger decoding of the request body. And in Sling there will usually be at least one authentication handler that needs to do a request.getParameter(), and authentication handlers come before any servlet filter, so no luck to work around that. The proper way IMO would be to have sling take care of the correctly-ordered-re-decoding. This would need to be a change mostly in ParameterSupport [5] of the sling engine. It should probably be disabled by default (otherwise all parameters would always get decoded twice, once in the container and once in Sling) and could be opt-in on a per servlet basis - via means of some "sling.servlet.orderedparameters" option. Since the servlet is not resolved at the time of the auth handlers, this might in fact be tricky to do. WDYT? [1] http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1 [2] http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/util/MultiMap.html#33 [3] http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/Parameters.java?revision=1525696&view=markup [4] http://sling.apache.org/documentation/the-sling-engine/request-parameters.html [5] http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/parameters/ParameterSupport.java?view=markup Cheers, Alex
