Repository: incubator-juneau
Updated Branches:
  refs/heads/master fa4736b6d -> 321f6bdee


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
index c35e0bd..dfced43 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -31,12 +31,10 @@ import javax.servlet.http.*;
 import org.apache.juneau.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.encoders.*;
-import org.apache.juneau.encoders.Encoder;
 import org.apache.juneau.http.*;
 import org.apache.juneau.ini.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
-import org.apache.juneau.parser.ParseException;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.svl.*;
 import org.apache.juneau.uon.*;
@@ -70,26 +68,22 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
 
        private final String method;
        private String pathRemainder;
-       private byte[] body;
+       private RequestBody body;
        private Method javaMethod;
        private ObjectMap properties;
        private SerializerGroup serializerGroup;
        private ParserGroup parserGroup;
-       private EncoderGroup encoders;
-       private Encoder encoder;
-       private int contentLength;
        private final boolean debug;
        private UrlEncodingParser urlEncodingParser;   // The parser used to 
parse URL attributes and parameters (beanContext also used to parse headers)
        private BeanSession beanSession;
        private VarResolverSession varSession;
-       private final Map<String,String[]> queryParams;
-       private Map<String,String> formData;
-       private final Map<String,String> defaultServletHeaders;
-       private Map<String,String> defaultMethodHeaders, overriddenHeaders, 
overriddenQueryParams, overriddenFormDataParams, pathParameters;
+       private final RequestQuery queryParams;
+       private RequestFormData formData;
+       private RequestPathParams pathParams;
        private boolean isPost;
        private String servletURI, relativeServletURI;
        private String charset, defaultCharset;
-       private ObjectMap headers;
+       private RequestHeaders headers;
        private ConfigFile cf;
        private Swagger swagger, fileSwagger;
        private String pageTitle, pageText, pageLinks;
@@ -106,33 +100,45 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
 
                        // If this is a POST, we want to parse the query 
parameters ourselves to prevent
                        // the servlet code from processing the HTTP body as 
URL-Encoded parameters.
+                       queryParams = new RequestQuery();
                        if (isPost)
-                               queryParams = 
context.getUrlEncodingParser().parseIntoSimpleMap(getQueryString());
-                       else {
-                               queryParams = req.getParameterMap();
-                       }
+                               
context.getUrlEncodingParser().parseIntoSimpleMap(getQueryString(), 
queryParams);
+                       else
+                               queryParams.putAll(req.getParameterMap());
+
 
                        // Get the HTTP method.
                        // Can be overridden through a "method" GET attribute.
                        String _method = super.getMethod();
 
-                       String m = getQueryParameter("method");
+                       String m = getQuery("method");
                        if (context.allowMethodParam(m))
                                _method = m;
 
                        method = _method;
 
+                       headers = new RequestHeaders();
+                       for (Enumeration<String> e = getHeaderNames(); 
e.hasMoreElements();) {
+                               String name = e.nextElement();
+                               headers.put(name, super.getHeaders(name));
+                       }
+
+                       body = new RequestBody(this);
+
                        if (context.isAllowBodyParam()) {
-                               String b = getQueryParameter("body");
+                               String b = getQuery("body");
                                if (b != null) {
-                                       setHeader("Content-Type", 
UonSerializer.DEFAULT.getResponseContentType());
-                                       this.body = b.getBytes(IOUtils.UTF8);
+                                       headers.put("Content-Type", 
UonSerializer.DEFAULT.getResponseContentType());
+                                       body.load(b.getBytes(IOUtils.UTF8));
                                }
                        }
 
-                       defaultServletHeaders = 
context.getDefaultRequestHeaders();
+                       if (context.isAllowHeaderParams())
+                               headers.setQueryParams(queryParams);
 
-                       debug = "true".equals(getQueryParameter("debug", 
"false")) || "true".equals(getHeader("Debug", "false"));
+                       debug = "true".equals(getQuery("debug", "false")) || 
"true".equals(getHeader("Debug", "false"));
+
+                       this.pathParams = new RequestPathParams();
 
                } catch (RestException e) {
                        throw e;
@@ -149,13 +155,28 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                this.javaMethod = javaMethod;
                this.pathRemainder = pathRemainder;
                this.properties = properties;
-               this.defaultMethodHeaders = mDefaultRequestHeaders;
-               this.serializerGroup = mSerializers;
-               this.parserGroup = mParsers;
                this.urlEncodingParser = mUrlEncodingParser;
                this.beanSession = 
urlEncodingParser.getBeanContext().createSession();
+               this.pathParams
+                       .setParser(urlEncodingParser)
+                       .setBeanSession(beanSession);
+               this.queryParams
+                       .setParser(urlEncodingParser)
+                       .setBeanSession(beanSession);
+               this.headers
+                       .addDefault(mDefaultRequestHeaders)
+                       .addDefault(context.getDefaultRequestHeaders())
+                       .setParser(urlEncodingParser)
+                       .setBeanSession(beanSession);
+               this.body
+                       .setEncoders(encoders)
+                       .setParsers(mParsers)
+                       .setHeaders(headers)
+                       .setBeanSession(beanSession)
+                       .setUrlEncodingParser(mUrlEncodingParser);
+               this.serializerGroup = mSerializers;
+               this.parserGroup = mParsers;
                this.defaultCharset = defaultCharset;
-               this.encoders = encoders;
                this.pageTitle = pageTitle;
                this.pageText = pageText;
                this.pageLinks = pageLinks;
@@ -209,188 +230,49 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
        
//--------------------------------------------------------------------------------
 
        /**
-        * Sets a request header value.
+        * Returns the headers on this request.
+        *
+        * @return The headers on this request.  Never <jk>null</jk>.
+        */
+       public RequestHeaders getHeaders() {
+               return headers;
+       }
+
+       /**
+        * Convenience method for calling <code>getHeaders().put(name, 
value);</code>
         *
         * @param name The header name.
         * @param value The header value.
         */
        public void setHeader(String name, Object value) {
-               if (overriddenHeaders == null)
-                       overriddenHeaders = new 
TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER);
-               overriddenHeaders.put(name, StringUtils.toString(value));
+               getHeaders().put(name, value);
        }
 
-
        /**
-        * Returns the specified header value, or <jk>null</jk> if the header 
doesn't exist.
-        * <p>
-        * If {@code allowHeaderParams} init parameter is <jk>true</jk>, then 
first looks for {@code &HeaderName=x} in the URL query string.
+        * Convenience method for calling 
<code>getHeaders().getFirst(name);</code>
         */
        @Override /* ServletRequest */
        public String getHeader(String name) {
-               return getHeader(name, (String)null);
+               return getHeaders().getFirst(name);
        }
 
        /**
-        * Returns the specified header value, or a default value if the header 
doesn't exist.
-        * <p>
-        * If {@code allowHeaderParams} init parameter is <jk>true</jk>, then 
first looks for {@code &HeaderName=x} in the URL query string.
+        * Convenience method for calling <code>getHeaders().getFirst(name, 
def);</code>
         *
         * @param name The HTTP header name.
         * @param def The default value to return if the header value isn't 
found.
         * @return The header value, or the default value if the header isn't 
present.
         */
        public String getHeader(String name, String def) {
-               String h = getOverriddenHeader(name);
-               if (h != null)
-                       return h;
-               h = super.getHeader(name);
-               if (h != null && ! h.isEmpty())
-                       return h;
-               if (defaultMethodHeaders != null) {
-                       h = defaultMethodHeaders.get(name);
-                       if (h != null)
-                               return h;
-               }
-               h = defaultServletHeaders.get(name);
-               if (h != null)
-                       return h;
-               return def;
-       }
-
-       /**
-        * Returns the specified header value converted to a POJO.
-        * <p>
-        * The type can be any POJO type convertable from a <code>String</code>
-        * (See <a class="doclink" 
href="package-summary.html#PojosConvertableFromString">POJOs Convertable From 
Strings</a>).
-        * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into an integer.</jc>
-        *      <jk>int</jk> myheader = req.getHeader(<js>"My-Header"</js>, 
<jk>int</jk>.<jk>class</jk>);
-        *
-        *      <jc>// Parse a UUID.</jc>
-        *      UUID myheader = req.getHeader(<js>"My-Header"</js>, 
UUID.<jk>class</jk>);
-        * </p>
-        *
-        * @param name The HTTP header name.
-        * @param type The class type to convert the header value to.
-        * @param <T> The class type to convert the header value to.
-        * @return The parameter value converted to the specified class type.
-        */
-       public <T> T getHeader(String name, Class<T> type) {
-               String h = getHeader(name);
-               return beanSession.convertToType(h, type);
-       }
-
-       /**
-        * Same as {@link #getHeader(String, Class)} but returns a default 
value if not found.
-        *
-        * @param name The HTTP header name.
-        * @param def The default value if the header was not specified or is 
<jk>null</jk>.
-        * @param type The class type to convert the header value to.
-        * @param <T> The class type to convert the header value to.
-        * @return The parameter value converted to the specified class type.
-        */
-       public <T> T getHeader(String name, T def, Class<T> type) {
-               String h = getHeader(name);
-               if (h == null)
-                       return def;
-               return beanSession.convertToType(h, type);
-       }
-
-       /**
-        * Returns the specified header value converted to a POJO.
-        * <p>
-        * The type can be any POJO type convertable from a <code>String</code>
-        * (See <a class="doclink" 
href="package-summary.html#PojosConvertableFromString">POJOs Convertable From 
Strings</a>).
-        * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into a linked-list of strings.</jc>
-        *      List&lt;String&gt; myheader = 
req.getHeader(<js>"My-Header"</js>, LinkedList.<jk>class</jk>, 
String.<jk>class</jk>);
-        * </p>
-        *
-        * @param name The HTTP header name.
-        * @param type The type of object to create.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        * @param args The type arguments of the class if it's a collection or 
map.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        *      <br>Ignored if the main type is not a map or collection.
-        * @param <T> The class type to convert the header value to.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException If the header could not be converted to the 
specified type.
-        */
-       public <T> T getHeader(String name, Type type, Type...args) throws 
ParseException {
-               String h = getHeader(name);
-               return urlEncodingParser.parsePart(h, type, args);
-       }
-
-       /**
-        * Returns all the request headers as an {@link ObjectMap}.
-        * <p>
-        * Altering entries in this map does not alter headers in the 
underlying request.
-        *
-        * @return The request headers.  Never <jk>null</jk>.
-        */
-       public ObjectMap getHeaders() {
-               if (headers == null) {
-                       headers = new ObjectMap();
-                       for (Enumeration<String> e = getHeaderNames(); 
e.hasMoreElements();) {
-                               String key = e.nextElement();
-                               headers.put(key, getHeader(key));
-                       }
-               }
-               return headers;
+               return getHeaders().getFirst(name, def);
        }
 
        @Override /* ServletRequest */
        public Enumeration<String> getHeaders(String name) {
-               String h = getOverriddenHeader(name);
-               if (h != null)
-                       return enumeration(singleton(h));
-               return super.getHeaders(name);
-       }
-
-       /**
-        * Returns the <code>Accept</code> header on the request.
-        *
-        * @return The parsed <code>Accept</code> header on the request, or 
<jk>null</jk> if not found.
-        */
-       public Accept getAcceptHeader() {
-               return getHeader("Accept", Accept.class);
-       }
-
-       /**
-        * Returns the <code>Content-Type</code> header on the request.
-        *
-        * @return The parsed <code>Content-Type</code> header on the request, 
or <jk>null</jk> if not found.
-        */
-       public ContentType getContentTypeHeader() {
-               return getHeader("Content-Type", ContentType.class);
-       }
-
-       /**
-        * Returns the <code>Accept-Encoding</code> header on the request.
-        *
-        * @return The parsed <code>Accept-Encoding</code> header on the 
request, or <jk>null</jk> if not found.
-        */
-       public AcceptEncoding getAcceptEncodingHeader() {
-               return getHeader("Accept-Encoding", AcceptEncoding.class);
-       }
-
-       /**
-        * Returns the <code>Time-Zone</code> header value on the request if 
there is one.
-        * <p>
-        * Example: <js>"GMT"</js>.
-        *
-        * @return The <code>Time-Zone</code> header value on the request, or 
<jk>null</jk> if not present.
-        */
-       public TimeZone getTimeZone() {
-               String tz = getHeader("Time-Zone");
-               if (tz != null)
-                       return TimeZone.getTimeZone(tz);
-               return null;
+               String[] v = headers.get(name);
+               if (v == null || v.length == 0)
+                       return Collections.enumeration(Collections.EMPTY_LIST);
+               return Collections.enumeration(Arrays.asList(v));
        }
 
        /**
@@ -435,7 +317,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
 
        @Override /* ServletRequest */
        public Locale getLocale() {
-               String h = getOverriddenHeader("Accept-Language");
+               String h = headers.getFirst("Accept-Language");
                if (h != null) {
                        MediaTypeRange[] mr = MediaTypeRange.parse(h);
                        if (mr.length > 0)
@@ -446,7 +328,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
 
        @Override /* ServletRequest */
        public Enumeration<Locale> getLocales() {
-               String h = getOverriddenHeader("Accept-Language");
+               String h = headers.getFirst("Accept-Language");
                if (h != null) {
                        MediaTypeRange[] mr = MediaTypeRange.parse(h);
                        if (mr.length > 0) {
@@ -465,672 +347,142 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
        
//--------------------------------------------------------------------------------
 
        /**
-        * Sets a request query parameter value.
-        *
-        * @param name The parameter name.
-        * @param value The parameter value.
-        */
-       public void setQueryParameter(String name, Object value) {
-               if (overriddenQueryParams == null)
-                       overriddenQueryParams = new 
TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER);
-               overriddenQueryParams.put(name, value == null ? null : 
value.toString());
-       }
-
-       /**
-        * Returns a query parameter value.
-        * <p>
-        * Same as {@link #getParameter(String)} except only looks in the URL 
string, not parameters from URL-Encoded FORM posts.
-        * <p>
-        * This method can be used to retrieve a parameter without triggering 
the underlying servlet API to load and parse the request body.
-        *
-        * @param name The URL parameter name.
-        * @return The parameter value, or <jk>null</jk> if parameter not 
specified or has no value (e.g. <js>"&amp;foo"</js>.
-        */
-       public String getQueryParameter(String name) {
-               String s = null;
-               if (overriddenQueryParams != null)
-                       s = overriddenQueryParams.get(name);
-               if (s != null)
-                       return s;
-               String[] v = queryParams.get(name);
-               if (v == null || v.length == 0)
-                       return null;
-               if (v.length == 1 && v[0] != null && v[0].isEmpty()) {
-                       // Fix for behavior difference between Tomcat and WAS.
-                       // getParameter("foo") on "&foo" in Tomcat returns "".
-                       // getParameter("foo") on "&foo" in WAS returns null.
-                       if (queryParams.containsKey(name))
-                               return null;
-               }
-               return v[0];
-       }
-
-       /**
-        * Same as {@link #getQueryParameter(String)} but returns the specified 
default value if the query parameter was not specified.
-        *
-        * @param name The URL parameter name.
-        * @param def The default value.
-        * @return The parameter value, or the default value if parameter not 
specified or has no value (e.g. <js>"&amp;foo"</js>.
-        */
-       public String getQueryParameter(String name, String def) {
-               String s = getQueryParameter(name);
-               return s == null ? def : s;
-       }
-
-       /**
-        * Returns the specified query parameter value converted to a POJO.
-        * <p>
-        * This method can be used to retrieve a parameter without triggering 
the underlying servlet API to load and parse the request body.
-        * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into an integer.</jc>
-        *      <jk>int</jk> myparam = 
req.getQueryParameter(<js>"myparam"</js>, <jk>int</jk>.<jk>class</jk>);
-        *
-        *      <jc>// Parse into an int array.</jc>
-        *      <jk>int</jk>[] myparam = 
req.getQueryParameter(<js>"myparam"</js>, <jk>int</jk>[].<jk>class</jk>);
-
-        *      <jc>// Parse into a bean.</jc>
-        *      MyBean myparam = req.getQueryParameter(<js>"myparam"</js>, 
MyBean.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a linked-list of objects.</jc>
-        *      List myparam = req.getQueryParameter(<js>"myparam"</js>, 
LinkedList.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map of object keys/values.</jc>
-        *      Map myparam = req.getQueryParameter(<js>"myparam"</js>, 
TreeMap.<jk>class</jk>);
-        * </p>
-        *
-        * @param name The parameter name.
-        * @param type The class type to convert the parameter value to.
-        * @param <T> The class type to convert the parameter value to.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException
-        */
-       public <T> T getQueryParameter(String name, Class<T> type) throws 
ParseException {
-               return getQueryParameter(name, beanSession.getClassMeta(type));
-       }
-
-       /**
-        * Same as {@link #getQueryParameter(String, Class)} except returns a 
default value if not found.
-        *
-        * @param name The parameter name.
-        * @param def The default value if the parameter was not specified or 
is <jk>null</jk>.
-        * @param type The class type to convert the parameter value to.
-        * @param <T> The class type to convert the parameter value to.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException
-        */
-       public <T> T getQueryParameter(String name, T def, Class<T> type) 
throws ParseException {
-               return getQueryParameter(name, def, 
beanSession.getClassMeta(type));
-       }
-
-       /**
-        * Returns the specified query parameter value converted to a POJO.
-        * <p>
-        * This method can be used to retrieve a parameter without triggering 
the underlying servlet API to load and parse the request body.
+        * Equivalent to {@link #getParameterMap()}, but only looks for query 
parameters in the URL, not form posts.
         * <p>
-        * Use this method if you want to parse into a parameterized 
<code>Map</code>/<code>Collection</code> object.
+        * This method can be used to retrieve query parameters without 
triggering the underlying servlet API to load and parse the request body.
         * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into a linked-list of strings.</jc>
-        *      Listt&lt;String&gt; myparam = 
req.getQueryParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, 
String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a linked-list of linked-lists of strings.</jc>
-        *      Listt&lt;List&lt;String&gt;&gt; myparam = 
req.getQueryParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, 
LinkedList.<jk>class</jk>, String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map of string keys/values.</jc>
-        *      Map&lt;String,String&gt; myparam = 
req.getQueryParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, 
String.<jk>class</jk>, String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map containing string keys and values of 
lists containing beans.</jc>
-        *      Map&lt;String,List&lt;MyBean&gt;&gt; myparam = 
req.getQueryParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, 
String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
-        * </p>
+        * This object is modifiable.
         *
-        * @param name The parameter name.
-        * @param type The type of object to create.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        * @param args The type arguments of the class if it's a collection or 
map.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        *      <br>Ignored if the main type is not a map or collection.
-        * @param <T> The class type to convert the parameter value to.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException
+        * @return The query parameters as a modifiable map.
         */
-       public <T> T getQueryParameter(String name, Type type, Type...args) 
throws ParseException {
-               return (T)getQueryParameter(name, 
beanSession.getClassMeta(type, args));
+       public RequestQuery getQuery() {
+               return queryParams;
        }
 
        /**
-        * Same as {@link #getQueryParameter(String, Class)} except returns a 
default value if not found.
+        * Convenience method for calling <code>getQueryParams().put(name, 
value);</code>.
         *
         * @param name The parameter name.
-        * @param type The type of object to create.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        * @param args The type arguments of the class if it's a collection or 
map.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        *      <br>Ignored if the main type is not a map or collection.
-        * @param def The default value if the parameter was not specified or 
is <jk>null</jk>.
-        * @param <T> The class type to convert the parameter value to.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException
-        */
-       public <T> T getQueryParameter(String name, Object def, Type type, 
Type...args) throws ParseException {
-               return (T)getQueryParameter(name, def, 
getBeanSession().getClassMeta(type, args));
-       }
-
-       /**
-        * Same as {@link #getQueryParameter(String, Class)} except for use on 
multi-part parameters
-        * (e.g. <js>"&amp;key=1&amp;key=2&amp;key=3"</js> instead of 
<js>"&amp;key=(1,2,3)"</js>).
-        * <p>
-        * This method must only be called when parsing into classes of type 
Collection or array.
-        *
-        * @param name The query parameter name.
-        * @param c The class type to convert the parameter value to.
-        * @param <T> The class type to convert the parameter value to.
-        * @return The query parameter value converted to the specified class 
type.
-        * @throws ParseException
-        */
-       public <T> T getQueryParameters(String name, Class<T> c) throws 
ParseException {
-               return getQueryParameters(name, beanSession.getClassMeta(c));
-       }
-
-       /**
-        * Same as {@link #getQueryParameter(String, Type, Type...)} except for 
use on multi-part parameters
-        * (e.g. <js>"&amp;key=1&amp;key=2&amp;key=3"</js> instead of 
<js>"&amp;key=(1,2,3)"</js>).
-        * <p>
-        * This method must only be called when parsing into classes of type 
Collection or array.
-        *
-        * @param name The query parameter name.
-        * @param type The type of object to create.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        * @param args The type arguments of the class if it's a collection or 
map.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        *      <br>Ignored if the main type is not a map or collection.
-        * @param <T> The class type to convert the parameter value to.
-        * @return The query parameter value converted to the specified class 
type.
-        * @throws ParseException
+        * @param value The parameter value.
         */
-       public <T> T getQueryParameters(String name, Type type, Type...args) 
throws ParseException {
-               return (T)getQueryParameters(name, 
getBeanSession().getClassMeta(type, args));
+       public void setQuery(String name, Object value) {
+               queryParams.put(name, value);
        }
 
        /**
-        * Returns the list of all query parameters with the specified name.
-        * <p>
-        * Same as {@link #getParameterValues(String)} except only looks in the 
URL string, not parameters from URL-Encoded FORM posts.
-        * <p>
-        * This method can be used to retrieve parameters without triggering 
the underlying servlet API to load and parse the request body.
+        * Convenience method for calling 
<code>getQueryParams().getFirst(name);</code>
         *
-        * @param name
-        * @return the list of query parameters, or <jk>null</jk> if the 
parameter does not exist.
+        * @param name The URL parameter name.
+        * @return The parameter value, or <jk>null</jk> if parameter not 
specified or has no value (e.g. <js>"&amp;foo"</js>.
         */
-       public String[] getQueryParameters(String name) {
-               return queryParams.get(name);
+       public String getQuery(String name) {
+               return getQuery().getFirst(name);
        }
 
        /**
-        * Returns <jk>true</jk> if the query parameters on this request 
contains the specified entry.
-        * <p>
-        * Note that this returns <jk>true</jk> even if the value is set to 
null (e.g. <js>"?key"</js>).
-        * <p>
-        * This method can be used to check the existence of a parameter 
without triggering the underlying
-        *      servlet API to load and parse the request body.
+        * Convenience method for calling <code>getQueryParams().getFirst(name, 
def);</code>
         *
         * @param name The URL parameter name.
-        * @return <jk>true</jk> if the URL parameters on this request contains 
the specified entry.
+        * @param def The default value.
+        * @return The parameter value, or the default value if parameter not 
specified or has no value (e.g. <js>"&amp;foo"</js>.
         */
-       public boolean hasQueryParameter(String name) {
-               return queryParams.containsKey(name);
+       public String getQuery(String name, String def) {
+               return getQuery().getFirst(name, def);
        }
 
-       /**
-        * Returns <jk>true</jk> if the request contains any of the specified 
query parameters.
-        *
-        * @param params The list of parameters to check for.
-        * @return <jk>true</jk> if the request contains any of the specified 
query parameters.
-        */
-       public boolean hasAnyQueryParameters(String...params) {
-               for (String p : params)
-                       if (hasQueryParameter(p))
-                               return true;
-               return false;
-       }
 
-       /**
-        * Equivalent to {@link #getParameterMap()}, but only looks for query 
parameters in the URL, not form posts.
-        * <p>
-        * This method can be used to retrieve query parameters without 
triggering the underlying servlet API to load and parse the request body.
-        * <p>
-        * This object is modifiable.
-        *
-        * @return The query parameters as a modifiable map.
-        */
-       public Map<String,String[]> getQueryParameterMap() {
-               return queryParams;
-       }
+       
//--------------------------------------------------------------------------------
+       // Form data parameters
+       
//--------------------------------------------------------------------------------
 
        /**
-        * Equivalent to {@link #getParameterNames()}, but only looks for query 
parameters in the URL, not form posts.
-        * <p>
-        * This method can be used to retrieve query parameters without 
triggering the underlying servlet API to load and parse the request body.
-        * <p>
-        * This object is modifiable.
+        * Retrieves the URL-encoded form data from the request if the body has 
already been cached locally.
         *
-        * @return An iterator of query parameter names.
+        * @return The URL-encoded form data from the request.
         */
-       public Iterator<String> getQueryParameterNames() {
-               return queryParams.keySet().iterator();
-       }
-
-       /* Workhorse method */
-       <T> T getQueryParameter(String name, T def, ClassMeta<T> cm) throws 
ParseException {
-               String val = getQueryParameter(name);
-               if (val == null)
-                       return def;
-               return parseParameter(val, cm);
-       }
-
-       /* Workhorse method */
-       <T> T getQueryParameter(String name, ClassMeta<T> cm) throws 
ParseException {
-               String val = getQueryParameter(name);
-               if (cm.isPrimitive() && (val == null || val.isEmpty()))
-                       return cm.getPrimitiveDefault();
-               return parseParameter(val, cm);
-       }
-
-       /* Workhorse method */
-       @SuppressWarnings("rawtypes")
-       <T> T getQueryParameters(String name, ClassMeta<T> cm) throws 
ParseException {
-               String[] p = getQueryParameters(name);
-               if (p == null)
-                       return null;
-               if (cm.isArray()) {
-                       List c = new ArrayList();
-                       for (int i = 0; i < p.length; i++)
-                               c.add(parseParameter(p[i], 
cm.getElementType()));
-                       return (T)ArrayUtils.toArray(c, 
cm.getElementType().getInnerClass());
-               } else if (cm.isCollection()) {
-                       try {
-                               Collection c = 
(Collection)(cm.canCreateNewInstance() ? cm.newInstance() : new ObjectList());
-                               for (int i = 0; i < p.length; i++)
-                                       c.add(parseParameter(p[i], 
cm.getElementType()));
-                               return (T)c;
-                       } catch (ParseException e) {
-                               throw e;
-                       } catch (Exception e) {
-                               // Typically an instantiation exception.
-                               throw new ParseException(e);
+       public RequestFormData getFormData() {
+               try {
+                       if (formData == null) {
+                               formData = new RequestFormData();
+                               
formData.setParser(urlEncodingParser).setBeanSession(beanSession);
+                               if (! body.isLoaded()) {
+                                       formData.putAll(getParameterMap());
+                               } else {
+                                       Map<String,String> m = 
urlEncodingParser.parse(body.getReader(), Map.class, String.class, 
String.class);
+                                       for (Map.Entry<String,String> e : 
m.entrySet()) {
+                                               formData.put(e.getKey(), 
e.getValue());
+                                       }
+                               }
                        }
+                       return formData;
+               } catch (Exception e) {
+                       throw new RestException(SC_INTERNAL_SERVER_ERROR, e);
                }
-               throw new ParseException("Invalid call to 
getQueryParameters(String, ClassMeta).  Class type must be a Collection or 
array.");
        }
 
-
-       
//--------------------------------------------------------------------------------
-       // Form data parameters
-       
//--------------------------------------------------------------------------------
-
        /**
-        * Sets a request form data parameter value.
+        * Convenience method for calling <code>getFormData().put(name, 
value);</code>.
         *
         * @param name The parameter name.
         * @param value The parameter value.
         */
-       public void setFormDataParameter(String name, Object value) {
-               if (overriddenFormDataParams == null)
-                       overriddenFormDataParams = new 
TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER);
-               overriddenFormDataParams.put(name, value == null ? null : 
value.toString());
+       public void setFormData(String name, Object value) {
+               getFormData().put(name, value);
        }
 
        /**
-        * Returns a form data parameter value.
-        * <p>
-        * Parameter lookup is case-insensitive (consistent with WAS, but 
differs from Tomcat).
-        * <p>
-        * <h5 class='section'>Notes:</h5>
-        * <ul>
-        *      <li>Calling this method on URL-Encoded FORM posts causes the 
body content to be loaded and parsed by the underlying servlet API.
-        *      <li>This method returns the raw unparsed value, and differs 
from calling <code>getFormDataParameter(name, String.<jk>class</js>)</code>
-        *              which will convert the value from UON notation:
-        *              <ul>
-        *                      <li><js>"null"</js> =&gt; <jk>null</jk>
-        *                      <li><js>"'null'"</js> =&gt; <js>"null"</js>
-        *                      <li><js>"'foo bar'"</js> =&gt; <js>"foo 
bar"</js>
-        *                      <li><js>"foo~~bar"</js> =&gt; <js>"foo~bar"</js>
-        *              </ul>
-        * </ul>
+        * Convenience method for calling 
<code>getFormData().getFirst(name);</code>.
         *
         * @param name The form data parameter name.
         * @return The parameter value, or <jk>null</jk> if parameter does not 
exist.
         */
-       public String getFormDataParameter(String name) {
-               String s = null;
-               if (overriddenFormDataParams != null)
-                       s = overriddenFormDataParams.get(name);
-               if (s != null)
-                       return s;
-
-               return getFormParameterInner(name);
+       public String getFormData(String name) {
+               return getFormData().getFirst(name);
        }
 
        /**
-        * Same as {@link #getFormDataParameter(String)} except returns a 
default value if <jk>null</jk> or empty.
+        * Convenience method for calling <code>getFormData().getFirst(name, 
def);</code>.
         *
         * @param name The form data parameter name.
         * @param def The default value.
         * @return The parameter value, or the default value if <jk>null</jk> 
or empty.
         */
-       public String getFormDataParameter(String name, String def) {
-               String val = getFormParameterInner(name);
-               if (val == null || val.isEmpty())
-                       return def;
-               return val;
-       }
-
-       /**
-        * Returns the specified form data parameter value converted to a POJO 
using the
-        *      {@link UrlEncodingParser} registered with this servlet.
-        * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into an integer.</jc>
-        *      <jk>int</jk> myparam = 
req.getFormDataParameter(<js>"myparam"</js>, <jk>int</jk>.<jk>class</jk>);
-        *
-        *      <jc>// Parse into an int array.</jc>
-        *      <jk>int</jk>[] myparam = 
req.getFormDataParameter(<js>"myparam"</js>, <jk>int</jk>[].<jk>class</jk>);
-
-        *      <jc>// Parse into a bean.</jc>
-        *      MyBean myparam = req.getFormDataParameter(<js>"myparam"</js>, 
MyBean.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a linked-list of objects.</jc>
-        *      List myparam = req.getFormDataParameter(<js>"myparam"</js>, 
LinkedList.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map of object keys/values.</jc>
-        *      Map myparam = req.getFormDataParameter(<js>"myparam"</js>, 
TreeMap.<jk>class</jk>);
-        * </p>
-        * <p>
-        * <h5 class='section'>Notes:</h5>
-        * <ul>
-        *      <li>Calling this method on URL-Encoded FORM posts causes the 
body content to be loaded and parsed by the underlying servlet API.
-        * </ul>
-        *
-        * @param name The parameter name.
-        * @param type The class type to convert the parameter value to.
-        * @param <T> The class type to convert the parameter value to.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException
-        */
-       public <T> T getFormDataParameter(String name, Class<T> type) throws 
ParseException {
-               return getFormDataParameter(name, 
beanSession.getClassMeta(type));
+       public String getFormData(String name, String def) {
+               return getFormData().getFirst(name, def);
        }
 
-       /**
-        * Same as {@link #getFormDataParameter(String, Class)} except returns 
a default value if not specified.
-        *
-        * @param name The parameter name.
-        * @param def The default value if the parameter was not specified or 
is <jk>null</jk>.
-        * @param type The class type to convert the parameter value to.
-        * @param <T> The class type to convert the parameter value to.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException
-        */
-       public <T> T getFormDataParameter(String name, T def, Class<T> type) 
throws ParseException {
-               return getFormDataParameter(name, def, 
beanSession.getClassMeta(type));
-       }
 
-       /**
-        * Same as {@link #getFormDataParameter(String, Class)} except for use 
on multi-part parameters
-        *      (e.g. <js>"key=1&amp;key=2&amp;key=3"</js> instead of 
<js>"key=(1,2,3)"</js>)
-        * <p>
-        * This method must only be called when parsing into classes of type 
Collection or array.
-        *
-        * @param name The parameter name.
-        * @param type The class type to convert the parameter value to.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException
-        */
-       public <T> T getFormDataParameters(String name, Class<T> type) throws 
ParseException {
-               return getFormDataParameters(name, 
beanSession.getClassMeta(type));
-       }
+       
//--------------------------------------------------------------------------------
+       // Path parameters
+       
//--------------------------------------------------------------------------------
 
        /**
-        * Returns the specified form data parameter value converted to a POJO 
using the
-        *      {@link UrlEncodingParser} registered with this servlet.
-        * <p>
-        * <h5 class='section'>Notes:</h5>
-        * <ul>
-        *      <li>Calling this method on URL-Encoded FORM posts causes the 
body content to be loaded and parsed by the underlying servlet API.
-        *      <li>Use this method if you want to parse into a parameterized 
<code>Map</code>/<code>Collection</code> object.
-        * </ul>
-        * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into a linked-list of strings.</jc>
-        *      List&lt;String&gt; myparam = 
req.getFormDataParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, 
String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a linked-list of linked-lists of strings.</jc>
-        *      List&lt;List&lt;String&gt;&gt; myparam = 
req.getFormDataParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, 
LinkedList.<jk>class</jk>, String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map of string keys/values.</jc>
-        *      Map&lt;String,String&gt; myparam = 
req.getFormDataParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, 
String.<jk>class</jk>, String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map containing string keys and values of 
lists containing beans.</jc>
-        *      Map&lt;String,List&lt;MyBean&gt;&gt; myparam = 
req.getFormDataParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, 
String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
-        * </p>
+        * Retrieves the URL-encoded form data from the request if the body has 
already been cached locally.
         *
-        * @param name The parameter name.
-        * @param type The type of object to create.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        * @param args The type arguments of the class if it's a collection or 
map.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        *      <br>Ignored if the main type is not a map or collection.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException
+        * @return The URL-encoded form data from the request.
         */
-       public <T> T getFormDataParameter(String name, Type type, Type...args) 
throws ParseException {
-               return (T)getFormDataParameter(name, 
beanSession.getClassMeta(type, args));
+       public RequestPathParams getPathParams() {
+               return pathParams;
        }
 
        /**
-        * Same as {@link #getFormDataParameter(String, Type, Type...)} except 
for use on multi-part parameters
-        *      (e.g. <js>"key=1&amp;key=2&amp;key=3"</js> instead of 
<js>"key=(1,2,3)"</js>)
-        * <p>
-        * This method must only be called when parsing into classes of type 
Collection or array.
-        *
-        * @param name The parameter name.
-        * @param type The type of object to create.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        * @param args The type arguments of the class if it's a collection or 
map.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        *      <br>Ignored if the main type is not a map or collection.
-        * @return The parameter value converted to the specified class type.
-        * @throws ParseException
-        */
-       public <T> T getFormDataParameters(String name, Type type, Type...args) 
throws ParseException {
-               return (T)getFormDataParameters(name, 
beanSession.getClassMeta(type, args));
-       }
-
-       /**
-        * Returns <jk>true</jk> if the form data parameters on this request 
contains the specified entry.
-        * <p>
-        * Note that this returns <jk>true</jk> even if the value is set to 
null (e.g. <js>"?key"</js>).
-        *
-        * @param name The URL parameter name.
-        * @return <jk>true</jk> if the URL parameters on this request contains 
the specified entry.
-        */
-       public boolean hasFormDataParameter(String name) {
-               return getParameterMap().containsKey(name);
-       }
-
-       /**
-        * Retrieves the URL-encoded from data from the request if the body has 
already been cached locally.
-        */
-       private Map<String,String> getFormData() {
-               try {
-                       if (formData == null)
-                               formData = urlEncodingParser.parse(body, 
Map.class, String.class, String.class);
-                       return formData;
-               } catch (ParseException e) {
-                       throw new RestException(SC_INTERNAL_SERVER_ERROR, e);
-               }
-       }
-
-       /* Workhorse method */
-       <T> T getFormDataParameter(String name, T def, ClassMeta<T> cm) throws 
ParseException {
-               String val = getFormParameterInner(name);
-               if (val == null)
-                       return def;
-               return parseParameter(val, cm);
-       }
-
-       /* Workhorse method */
-       <T> T getFormDataParameter(String name, ClassMeta<T> cm) throws 
ParseException {
-               String val = getFormParameterInner(name);
-               if (cm.isPrimitive() && (val == null || val.isEmpty()))
-                       return cm.getPrimitiveDefault();
-               return parseParameter(val, cm);
-       }
-
-       private String getFormParameterInner(String name) {
-               return (body == null ? super.getParameter(name) : 
getFormData().get(name));
-       }
-
-       /* Workhorse method */
-       @SuppressWarnings("rawtypes")
-       <T> T getFormDataParameters(String name, ClassMeta<T> cm) throws 
ParseException {
-               String[] p = getParameterValues(name);
-               if (p == null)
-                       return null;
-               if (cm.isArray()) {
-                       List c = new ArrayList();
-                       for (int i = 0; i < p.length; i++)
-                               c.add(parseParameter(p[i], 
cm.getElementType()));
-                       return (T)ArrayUtils.toArray(c, 
cm.getElementType().getInnerClass());
-               } else if (cm.isCollection()) {
-                       try {
-                               Collection c = 
(Collection)(cm.canCreateNewInstance() ? cm.newInstance() : new ObjectList());
-                               for (int i = 0; i < p.length; i++)
-                                       c.add(parseParameter(p[i], 
cm.getElementType()));
-                               return (T)c;
-                       } catch (ParseException e) {
-                               throw e;
-                       } catch (Exception e) {
-                               // Typically an instantiation exception.
-                               throw new ParseException(e);
-                       }
-               }
-               throw new ParseException("Invalid call to getParameters(String, 
ClassMeta).  Class type must be a Collection or array.");
-       }
-
-
-       
//--------------------------------------------------------------------------------
-       // Path parameters
-       
//--------------------------------------------------------------------------------
-
-       /**
-        * Sets a path parameter value.
-        * <p>
-        * A path parameter is a variable in the path pattern such as 
<js>"/{foo}"</js>
+        * Convenience method for calling <code>getPathParams().put(name, 
value);</code>.
         *
         * @param name The parameter name.
         * @param value The parameter value.
         */
        public void setPathParameter(String name, String value) {
-               if (pathParameters == null)
-                       pathParameters = new 
TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER);
-               pathParameters.put(name, value == null ? null : 
value.toString());
+               pathParams.put(name, StringUtils.toString(value));
        }
 
        /**
-        * Returns a path parameter value.
-        * <p>
-        * A path parameter is a variable in the path pattern such as 
<js>"/{foo}"</js>
+        * Convenience method for calling 
<code>getPathParams().get(name);</code>.
         *
         * @param name The parameter name.
-        * @return The paramter value, or <jk>null</jk> if path parameter not 
specified.
+        * @return The parameter value, or <jk>null</jk> if path parameter not 
specified.
         */
        public String getPathParameter(String name) {
-               return (pathParameters == null ? null : 
pathParameters.get(name));
-       }
-
-       /**
-        * Returns the specified path parameter converted to a POJO.
-        * <p>
-        * The type can be any POJO type convertable from a <code>String</code> 
(See <a class="doclink" 
href="package-summary.html#PojosConvertableFromString">POJOs Convertable From 
Strings</a>).
-        * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into an integer.</jc>
-        *      <jk>int</jk> myparam = req.getPathParameter(<js>"myparam"</js>, 
<jk>int</jk>.<jk>class</jk>);
-        *
-        *      <jc>// Parse into an int array.</jc>
-        *      <jk>int</jk>[] myparam = 
req.getPathParameter(<js>"myparam"</js>, <jk>int</jk>[].<jk>class</jk>);
-
-        *      <jc>// Parse into a bean.</jc>
-        *      MyBean myparam = req.getPathParameter(<js>"myparam"</js>, 
MyBean.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a linked-list of objects.</jc>
-        *      List myparam = req.getPathParameter(<js>"myparam"</js>, 
LinkedList.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map of object keys/values.</jc>
-        *      Map myparam = req.getPathParameter(<js>"myparam"</js>, 
TreeMap.<jk>class</jk>);
-        * </p>
-        *
-        * @param name The attribute name.
-        * @param type The class type to convert the attribute value to.
-        * @param <T> The class type to convert the attribute value to.
-        * @return The attribute value converted to the specified class type.
-        * @throws ParseException
-        */
-       public <T> T getPathParameter(String name, Class<T> type) throws 
ParseException {
-               return getPathParameter(name, beanSession.getClassMeta(type));
-       }
-
-       /**
-        * Returns the specified path parameter converted to a POJO.
-        * <p>
-        * The type can be any POJO type convertable from a <code>String</code> 
(See <a class="doclink" 
href="package-summary.html#PojosConvertableFromString">POJOs Convertable From 
Strings</a>).
-        * <p>
-        * Use this method if you want to parse into a parameterized 
<code>Map</code>/<code>Collection</code> object.
-        * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into a linked-list of strings.</jc>
-        *      List&lt;String&gt; myparam = 
req.getPathParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, 
String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a linked-list of linked-lists of strings.</jc>
-        *      List&lt;List&lt;String&gt;&gt; myparam = 
req.getPathParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, 
LinkedList.<jk>class</jk>, String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map of string keys/values.</jc>
-        *      Map&lt;String,String&gt; myparam = 
req.getPathParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, 
String.<jk>class</jk>, String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map containing string keys and values of 
lists containing beans.</jc>
-        *      Map&lt;String,List&lt;MyBean&gt;&gt; myparam = 
req.getPathParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, 
String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
-        * </p>
-        *
-        * @param name The attribute name.
-        * @param type The type of object to create.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        * @param args The type arguments of the class if it's a collection or 
map.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        *      <br>Ignored if the main type is not a map or collection.
-        * @param <T> The class type to convert the attribute value to.
-        * @return The attribute value converted to the specified class type.
-        * @throws ParseException
-        */
-       public <T> T getPathParameter(String name, Type type, Type...args) 
throws ParseException {
-               return (T)getPathParameter(name, beanSession.getClassMeta(type, 
args));
-       }
-
-       /* Workhorse method */
-       <T> T getPathParameter(String name, ClassMeta<T> cm) throws 
ParseException {
-               Object attr = getPathParameter(name);
-               T t = null;
-               if (attr != null)
-                       t = urlEncodingParser.parsePart(attr.toString(), cm);
-               if (t == null && cm.isPrimitive())
-                       return cm.getPrimitiveDefault();
-               return t;
+               return pathParams.get(name);
        }
 
 
@@ -1139,123 +491,12 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
        
//--------------------------------------------------------------------------------
 
        /**
-        * Reads the input from the HTTP request as JSON, XML, or HTML and 
converts the input to a POJO.
-        * <p>
-        * If {@code allowHeaderParams} init parameter is <jk>true</jk>, then 
first looks for {@code &body=xxx} in the URL query string.
-        * <p>
-        * If type is <jk>null</jk> or <code>Object.<jk>class</jk></code>, then 
the actual type will be determined automatically based on the following input:
-        * <table class='styled'>
-        *      <tr><th>Type</th><th>JSON input</th><th>XML 
input</th><th>Return type</th></tr>
-        *      <tr>
-        *              <td>object</td>
-        *              <td><js>"{...}"</js></td>
-        *              
<td><code><xt>&lt;object&gt;</xt>...<xt>&lt;/object&gt;</xt></code><br><code><xt>&lt;x</xt>
 <xa>type</xa>=<xs>'object'</xs><xt>&gt;</xt>...<xt>&lt;/x&gt;</xt></code></td>
-        *              <td>{@link ObjectMap}</td>
-        *      </tr>
-        *      <tr>
-        *              <td>array</td>
-        *              <td><js>"[...]"</js></td>
-        *              
<td><code><xt>&lt;array&gt;</xt>...<xt>&lt;/array&gt;</xt></code><br><code><xt>&lt;x</xt>
 <xa>type</xa>=<xs>'array'</xs><xt>&gt;</xt>...<xt>&lt;/x&gt;</xt></code></td>
-        *              <td>{@link ObjectList}</td>
-        *      </tr>
-        *      <tr>
-        *              <td>string</td>
-        *              <td><js>"'...'"</js></td>
-        *              
<td><code><xt>&lt;string&gt;</xt>...<xt>&lt;/string&gt;</xt></code><br><code><xt>&lt;x</xt>
 <xa>type</xa>=<xs>'string'</xs><xt>&gt;</xt>...<xt>&lt;/x&gt;</xt></code></td>
-        *              <td>{@link String}</td>
-        *      </tr>
-        *      <tr>
-        *              <td>number</td>
-        *              <td><code>123</code></td>
-        *              
<td><code><xt>&lt;number&gt;</xt>123<xt>&lt;/number&gt;</xt></code><br><code><xt>&lt;x</xt>
 <xa>type</xa>=<xs>'number'</xs><xt>&gt;</xt>...<xt>&lt;/x&gt;</xt></code></td>
-        *              <td>{@link Number}</td>
-        *      </tr>
-        *      <tr>
-        *              <td>boolean</td>
-        *              <td><jk>true</jk></td>
-        *              
<td><code><xt>&lt;boolean&gt;</xt>true<xt>&lt;/boolean&gt;</xt></code><br><code><xt>&lt;x</xt>
 <xa>type</xa>=<xs>'boolean'</xs><xt>&gt;</xt>...<xt>&lt;/x&gt;</xt></code></td>
-        *              <td>{@link Boolean}</td>
-        *      </tr>
-        *      <tr>
-        *              <td>null</td>
-        *              <td><jk>null</jk> or blank</td>
-        *              <td><code><xt>&lt;null/&gt;</xt></code> or 
blank<br><code><xt>&lt;x</xt> 
<xa>type</xa>=<xs>'null'</xs><xt>/&gt;</xt></code></td>
-        *              <td><jk>null</jk></td>
-        *      </tr>
-        * </table>
-        * <p>
-        * Refer to <a class="doclink" 
href="../../../../overview-summary.html#Core.PojoCategories">POJO 
Categories</a> for a complete definition of supported POJOs.
-        * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into an integer.</jc>
-        *      <jk>int</jk> body = req.getBody(<jk>int</jk>.<jk>class</jk>);
-        *
-        *      <jc>// Parse into an int array.</jc>
-        *      <jk>int</jk>[] body = 
req.getBody(<jk>int</jk>[].<jk>class</jk>);
-
-        *      <jc>// Parse into a bean.</jc>
-        *      MyBean body = req.getBody(MyBean.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a linked-list of objects.</jc>
-        *      List body = req.getBody(LinkedList.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map of object keys/values.</jc>
-        *      Map body = req.getBody(TreeMap.<jk>class</jk>);
-        * </p>
-        *
-        * @param type The class type to instantiate.
-        * @param <T> The class type to instantiate.
-        * @return The input parsed to a POJO.
-        * @throws IOException If a problem occurred trying to read from the 
reader.
-        * @throws ParseException If the input contains a syntax error or is 
malformed for the requested {@code Accept} header or is not valid for the 
specified type.
-        */
-       public <T> T getBody(Class<T> type) throws IOException, ParseException {
-               return getBody(beanSession.getClassMeta(type));
-       }
-
-       /**
-        * Reads the input from the HTTP request as JSON, XML, or HTML and 
converts the input to a POJO.
-        * <p>
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode'>
-        *      <jc>// Parse into a linked-list of strings.</jc>
-        *      List&lt;String&gt; body = 
req.getBody(LinkedList.<jk>class</jk>, String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a linked-list of linked-lists of strings.</jc>
-        *      List&lt;List&lt;String&gt;&gt; body = 
req.getBody(LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, 
String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map of string keys/values.</jc>
-        *      Map&lt;String,String&gt; body = 
req.getBody(TreeMap.<jk>class</jk>, String.<jk>class</jk>, 
String.<jk>class</jk>);
-        *
-        *      <jc>// Parse into a map containing string keys and values of 
lists containing beans.</jc>
-        *      Map&lt;String,List&lt;MyBean&gt;&gt; body = 
req.getBody(TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, 
MyBean.<jk>class</jk>);
-        * </p>
-        *
-        * @param type The type of object to create.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        * @param args The type arguments of the class if it's a collection or 
map.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        *      <br>Ignored if the main type is not a map or collection.
-        * @param <T> The class type to instantiate.
-        * @return The input parsed to a POJO.
-        */
-       public <T> T getBody(Type type, Type...args) {
-               return (T)getBody(beanSession.getClassMeta(type, args));
-       }
-
-       /**
-        * Returns the HTTP body content as a plain string.
-        * <p>
-        * If {@code allowHeaderParams} init parameter is true, then first 
looks for {@code &body=xxx} in the URL query string.
+        * Returns the body of this HTTP request.
         *
-        * @return The incoming input from the connection as a plain string.
-        * @throws IOException If a problem occurred trying to read from the 
reader.
+        * @return The body of this HTTP request.
         */
-       public String getBodyAsString() throws IOException {
-               if (body == null)
-                       body = IOUtils.readBytes(getInputStream(), 1024);
-               return new String(body, IOUtils.UTF8);
+       public RequestBody getBody() {
+               return body;
        }
 
        /**
@@ -1267,24 +508,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         */
        @Override /* ServletRequest */
        public BufferedReader getReader() throws IOException {
-               Reader r = getUnbufferedReader();
-               if (r instanceof BufferedReader)
-                       return (BufferedReader)r;
-               int len = getContentLength();
-               int buffSize = len <= 0 ? 8192 : Math.max(len, 8192);
-               return new BufferedReader(r, buffSize);
-       }
-
-       /**
-        * Same as {@link #getReader()}, but doesn't encapsulate the result in 
a {@link BufferedReader};
-        *
-        * @return An unbuffered reader.
-        * @throws IOException
-        */
-       protected Reader getUnbufferedReader() throws IOException {
-               if (body != null)
-                       return new CharSequenceReader(new String(body, 
IOUtils.UTF8));
-               return new InputStreamReader(getInputStream(), 
getCharacterEncoding());
+               return getBody().getReader();
        }
 
        /**
@@ -1298,66 +522,11 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         */
        @Override /* ServletRequest */
        public ServletInputStream getInputStream() throws IOException {
-
-               if (body != null)
-                       return new ServletInputStream2(body);
-
-               Encoder enc = getEncoder();
-
-               ServletInputStream is = super.getInputStream();
-               if (enc != null) {
-                       final InputStream is2 = enc.getInputStream(is);
-                       return new ServletInputStream2(is2);
-               }
-               return is;
+               return getBody().getInputStream();
        }
 
-       /* Workhorse method */
-       <T> T getBody(ClassMeta<T> cm) throws RestException {
-
-               try {
-                       if (cm.isReader())
-                               return (T)getReader();
-
-                       if (cm.isInputStream())
-                               return (T)getInputStream();
-
-                       TimeZone timeZone = getTimeZone();
-                       Locale locale = getLocale();
-                       ParserMatch pm = getParserMatch();
-
-                       if (pm != null) {
-                               Parser p = pm.getParser();
-                               MediaType mediaType = pm.getMediaType();
-                               try {
-                                       properties.append("mediaType", 
mediaType).append("characterEncoding", getCharacterEncoding());
-                                       if (! p.isReaderParser()) {
-                                               InputStreamParser p2 = 
(InputStreamParser)p;
-                                               ParserSession session = 
p2.createSession(getInputStream(), properties, getJavaMethod(), 
context.getResource(), locale, timeZone, mediaType);
-                                               return p2.parseSession(session, 
cm);
-                                       }
-                                       ReaderParser p2 = (ReaderParser)p;
-                                       ParserSession session = 
p2.createSession(getUnbufferedReader(), properties, getJavaMethod(), 
context.getResource(), locale, timeZone, mediaType);
-                                       return p2.parseSession(session, cm);
-                               } catch (ParseException e) {
-                                       throw new RestException(SC_BAD_REQUEST,
-                                               "Could not convert request body 
content to class type ''{0}'' using parser ''{1}''.",
-                                               cm, p.getClass().getName()
-                                       ).initCause(e);
-                               }
-                       }
-
-                       throw new RestException(SC_UNSUPPORTED_MEDIA_TYPE,
-                               "Unsupported media-type in request header 
''Content-Type'': ''{0}''\n\tSupported media-types: {1}",
-                               getHeader("Content-Type"), 
parserGroup.getSupportedMediaTypes()
-                       );
-
-               } catch (IOException e) {
-                       throw new RestException(SC_INTERNAL_SERVER_ERROR,
-                               "I/O exception occurred while attempting to 
handle request ''{0}''.",
-                               getDescription()
-                       ).initCause(e);
-               }
+       ServletInputStream getRawInputStream() throws IOException {
+               return super.getInputStream();
        }
 
 
@@ -1724,53 +893,6 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                return parserGroup;
        }
 
-       /**
-        * Returns the parser and media type matching the request 
<code>Content-Type</code> header.
-        *
-        * @return The parser matching the request <code>Content-Type</code> 
header, or <jk>null</jk>
-        *      if no matching parser was found.
-        * Includes the matching media type.
-        */
-       public ParserMatch getParserMatch() {
-               MediaType mediaType = getContentTypeHeader();
-               if (mediaType == null) {
-                       if (body != null)
-                               mediaType = MediaType.UON;
-                       else
-                               mediaType = MediaType.JSON;
-               }
-               ParserMatch pm = parserGroup.getParserMatch(mediaType);
-
-               // If no patching parser for URL-encoding, use the one defined 
on the servlet.
-               if (pm == null && mediaType.equals(MediaType.URLENCODING))
-                       pm = new ParserMatch(MediaType.URLENCODING, 
urlEncodingParser);
-
-               return pm;
-       }
-
-       /**
-        * Returns the parser matching the request <code>Content-Type</code> 
header.
-        *
-        * @return The parser matching the request <code>Content-Type</code> 
header, or <jk>null</jk>
-        *      if no matching parser was found.
-        */
-       public Parser getParser() {
-               ParserMatch pm = getParserMatch();
-               return (pm == null ? null : pm.getParser());
-       }
-
-       /**
-        * Returns the reader parser matching the request 
<code>Content-Type</code> header.
-        *
-        * @return The reader parser matching the request 
<code>Content-Type</code> header, or <jk>null</jk>
-        *      if no matching reader parser was found, or the matching parser 
was an input stream parser.
-        */
-       public ReaderParser getReaderParser() {
-               Parser p = getParser();
-               if (p != null && p.isReaderParser())
-                       return (ReaderParser)p;
-               return null;
-       }
 
        /**
         * Returns the method of this request.
@@ -1782,10 +904,24 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                return method;
        }
 
+       /**
+        * Returns the HTTP 1.1 method name of the request as an enum.
+        * <p>
+        * Note that non-RFC2616 method names resolve as {@link 
HttpMethod#OTHER}.
+        *
+        * @return The HTTP method.
+        */
+       public HttpMethod getHttpMethod() {
+               return HttpMethod.forString(method);
+       }
 
        @Override /* ServletRequest */
        public int getContentLength() {
-               return contentLength == 0 ? super.getContentLength() : 
contentLength;
+               return getBody().getContentLength();
+       }
+
+       int getRawContentLength() {
+               return super.getContentLength();
        }
 
        /**
@@ -1799,7 +935,7 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
         * @return <jk>true</jk> if {@code &amp;plainText=true} was specified 
as a URL parameter
         */
        public boolean isPlainText() {
-               return "true".equals(getQueryParameter("plainText", "false"));
+               return "true".equals(getQuery("plainText", "false"));
        }
 
        /**
@@ -1976,18 +1112,17 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                        sb.append("\t").append(h).append(": 
").append(getHeader(h)).append("\n");
                }
                sb.append("---Default Servlet Headers---\n");
-               for (Map.Entry<String,String> e : 
defaultServletHeaders.entrySet()) {
+               for (Map.Entry<String,String> e : 
context.getDefaultRequestHeaders().entrySet()) {
                        sb.append("\t").append(e.getKey()).append(": 
").append(e.getValue()).append("\n");
                }
                if (javaMethod == null) {
                        sb.append("***init() not called yet!***\n");
                } else if (method.equals("PUT") || method.equals("POST")) {
                        try {
-                               body = IOUtils.readBytes(getInputStream(), 
1024);
                                sb.append("---Body UTF-8---\n");
-                               sb.append(new String(body, 
"UTF-8")).append("\n");
+                               sb.append(body.asString()).append("\n");
                                sb.append("---Body Hex---\n");
-                               sb.append(StringUtils.toHex(body)).append("\n");
+                               sb.append(body.asHex()).append("\n");
                        } catch (Exception e1) {
                                sb.append(e1.getLocalizedMessage());
                                context.getLogger().log(WARNING, e1, "Error 
occurred while trying to read debug input.");
@@ -2001,10 +1136,6 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
        // Utility methods
        
//--------------------------------------------------------------------------------
 
-       private <T> T parseParameter(String val, ClassMeta<T> c) throws 
ParseException {
-               return urlEncodingParser.parsePart(val, c);
-       }
-
        /*
         * Converts an Accept-Language value entry to a Locale.
         */
@@ -2018,74 +1149,8 @@ public final class RestRequest extends 
HttpServletRequestWrapper {
                return new Locale(lang, country);
        }
 
-       private Encoder getEncoder() {
-               if (encoder == null) {
-                       String ce = getHeader("content-encoding");
-                       if (! (ce == null || ce.isEmpty())) {
-                               ce = ce.trim();
-                               encoder = encoders.getEncoder(ce);
-                               if (encoder == null)
-                                       throw new 
RestException(SC_UNSUPPORTED_MEDIA_TYPE,
-                                               "Unsupported encoding in 
request header ''Content-Encoding'': ''{0}''\n\tSupported codings: {1}",
-                                               getHeader("content-encoding"), 
encoders.getSupportedEncodings()
-                                       );
-                       }
-
-                       if (encoder != null)
-                               contentLength = -1;
-               }
-               // Note that if this is the identity encoder, we want to return 
null
-               // so that we don't needlessly wrap the input stream.
-               if (encoder == IdentityEncoder.INSTANCE)
-                       return null;
-               return encoder;
-       }
-
-       /*
-        * Returns header value from URL-parameters or set via setHeader() meant
-        * to override actual header values on the request.
-        */
-       private String getOverriddenHeader(String name) {
-               String h = null;
-               if (context.isAllowHeaderParams())
-                       h = getQueryParameter(name);
-               if (h != null)
-                       return h;
-               if (overriddenHeaders != null) {
-                       h = overriddenHeaders.get(name);
-                       if (h != null)
-                               return h;
-               }
-               return h;
-       }
 
        void setJavaMethod(Method method) {
                this.javaMethod = method;
        }
-
-       /**
-        * ServletInputStream wrapper around a normal input stream.
-        */
-       private static class ServletInputStream2 extends ServletInputStream {
-
-               private final InputStream is;
-
-               private ServletInputStream2(InputStream is) {
-                       this.is = is;
-               }
-
-               private ServletInputStream2(byte[] b) {
-                       this(new ByteArrayInputStream(b));
-               }
-
-               @Override /* InputStream */
-               public final int read() throws IOException {
-                       return is.read();
-               }
-
-               @Override /* InputStream */
-               public final void close() throws IOException {
-                       is.close();
-               }
-       }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/FormData.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/FormData.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/FormData.java
index 9a16812..bf40391 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/FormData.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/FormData.java
@@ -46,7 +46,7 @@ import org.apache.juneau.rest.*;
  *
  * <h6 class='topic'>Important note concerning FORM posts</h6>
  * <p>
- * This annotation should not be combined with the {@link Body @Body} 
annotation or {@link RestRequest#getBody(Class)} method
+ * This annotation should not be combined with the {@link Body @Body} 
annotation or {@link RestRequest#getBody()} method
  *     for <code>application/x-www-form-urlencoded POST</code> posts, since it 
will trigger the underlying servlet
  *     API to parse the body content as key-value pairs resulting in empty 
content.
  * <p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasFormData.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasFormData.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasFormData.java
index 79d9ba0..085d7e9 100644
--- 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasFormData.java
+++ 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasFormData.java
@@ -74,7 +74,7 @@ import org.apache.juneau.rest.*;
  *
  * <h6 class='topic'>Important note concerning FORM posts</h6>
  * <p>
- * This annotation should not be combined with the {@link Body @Body} 
annotation or {@link RestRequest#getBody(Class)} method
+ * This annotation should not be combined with the {@link Body @Body} 
annotation or {@link RestRequest#getBody()} method
  *     for <code>application/x-www-form-urlencoded POST</code> posts, since it 
will trigger the underlying servlet API to parse the body
  *     content as key-value pairs, resulting in empty content.
  * <p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasQuery.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasQuery.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasQuery.java
index 880b1b7..19f4469 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasQuery.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HasQuery.java
@@ -26,7 +26,7 @@ import org.apache.juneau.rest.*;
  * Unlike {@link HasFormData @HasFormData}, using this annotation does not 
result in the servlet reading the contents
  *     of URL-encoded form posts.
  * Therefore, this annotation can be used in conjunction with the {@link Body 
@Body} annotation
- *     or {@link RestRequest#getBody(Class)} method for 
<code>application/x-www-form-urlencoded POST</code> calls.
+ *     or {@link RestRequest#getBody()} method for 
<code>application/x-www-form-urlencoded POST</code> calls.
  *
  * <h5 class='section'>Example:</h5>
  * <p class='bcode'>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Query.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Query.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Query.java
index 8e411d3..1f00fdc 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Query.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Query.java
@@ -26,7 +26,7 @@ import org.apache.juneau.rest.*;
  * Unlike {@link FormData @FormData}, using this annotation does not result in 
the servlet reading the contents
  *     of URL-encoded form posts.
  * Therefore, this annotation can be used in conjunction with the {@link Body 
@Body} annotation
- *     or {@link RestRequest#getBody(Class)} method for 
<code>application/x-www-form-urlencoded POST</code> calls.
+ *     or {@link RestRequest#getBody()} method for 
<code>application/x-www-form-urlencoded POST</code> calls.
  *
  * <h5 class='section'>Example:</h5>
  * <p class='bcode'>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
 
b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
index b4bb393..cf5f16d 100644
--- 
a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
+++ 
b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java
@@ -40,8 +40,8 @@ public final class Introspectable implements RestConverter {
        @Override /* RestConverter */
        @SuppressWarnings({"unchecked", "rawtypes"})
        public Object convert(RestRequest req, Object o, ClassMeta cm) throws 
RestException {
-               String method = req.getQueryParameter("invokeMethod");
-               String args = req.getQueryParameter("invokeArgs");
+               String method = req.getQuery("invokeMethod");
+               String args = req.getQuery("invokeArgs");
                if (method == null)
                        return o;
                try {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Queryable.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Queryable.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Queryable.java
index fee4939..a563863 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Queryable.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Queryable.java
@@ -58,10 +58,11 @@ public final class Queryable implements RestConverter {
                        return null;
 
                try {
+                       RequestQuery q = req.getQuery();
 
                        // If no actual filtering parameters have been passed 
in, and there is no map augmenter specified,
                        // then just pass the original object back.
-                       if 
(req.hasAnyQueryParameters("q","v","s","g","i","p","l")) {
+                       if (q.containsAnyKeys("q","v","s","g","i","p","l")) {
                                BeanSession session = req.getBeanSession();
 
                                if (cm.getPojoSwap() != null)
@@ -70,16 +71,16 @@ public final class Queryable implements RestConverter {
                                PojoQuery f = new PojoQuery(o, session);
 
                                if (o instanceof Collection || 
o.getClass().isArray()) {
-                                       ObjectMap query = 
req.getQueryParameter("q", ObjectMap.class);
-                                       List<String> view = 
req.getQueryParameter("v", List.class, String.class);
-                                       List sort = req.getQueryParameter("s", 
List.class, String.class);
-                                       boolean ignoreCase = 
req.getQueryParameter("i", false, Boolean.class);
-                                       int pos = req.getQueryParameter("p", 0, 
Integer.class);
-                                       int limit = req.getQueryParameter("l", 
0, Integer.class);
+                                       ObjectMap query = q.get("q", 
ObjectMap.class);
+                                       List<String> view = q.get("v", 
List.class, String.class);
+                                       List sort = q.get("s", List.class, 
String.class);
+                                       boolean ignoreCase = q.get("i", false, 
Boolean.class);
+                                       int pos = q.get("p", 0, Integer.class);
+                                       int limit = q.get("l", 0, 
Integer.class);
                                        o = f.filterCollection(query, view, 
sort, pos, limit, ignoreCase);
 
                                } else {
-                                       List<String> view = 
req.getQueryParameter("v", List.class, String.class);
+                                       List<String> view = q.get("v", 
List.class, String.class);
                                        o = f.filterMap(view);
                                }
                        }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java
index f56bf15..4816453 100644
--- 
a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java
+++ 
b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java
@@ -53,7 +53,7 @@ public final class Traversable implements RestConverter {
                        try {
                                if (cm.getPojoSwap() != null)
                                        o = 
cm.getPojoSwap().swap(req.getBeanSession(), o);
-                               PojoRest p = new PojoRest(o, 
req.getReaderParser());
+                               PojoRest p = new PojoRest(o, 
req.getBody().getReaderParser());
                                o = p.get(req.getPathRemainder());
                        } catch (SerializeException e) {
                                throw new 
RestException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
 
b/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
index 795f521..2d173f5 100644
--- 
a/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
+++ 
b/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
@@ -99,9 +99,9 @@ public abstract class RemoteableServlet extends 
RestServletDefault {
        public Object invoke(RestRequest req, @Path String javaInterface, @Path 
String javaMethod) throws Exception {
 
                // Find the parser.
-               ReaderParser p = req.getReaderParser();
+               ReaderParser p = req.getBody().getReaderParser();
                if (p == null)
-                       throw new RestException(SC_UNSUPPORTED_MEDIA_TYPE, 
"Could not find parser for media type ''{0}''", req.getContentTypeHeader()); 
//$NON-NLS-1$
+                       throw new RestException(SC_UNSUPPORTED_MEDIA_TYPE, 
"Could not find parser for media type ''{0}''", 
req.getHeaders().getContentType()); //$NON-NLS-1$
                Class<?> c = getInterfaceClass(javaInterface);
 
                // Find the service.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
index 190ea44..b06479b 100644
--- 
a/juneau-rest/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
+++ 
b/juneau-rest/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
@@ -60,13 +60,13 @@ public class DefaultHandler implements ResponseHandler {
                                if (! s.isWriterSerializer()) {
                                        OutputStreamSerializer s2 = 
(OutputStreamSerializer)s;
                                        OutputStream os = 
res.getNegotiatedOutputStream();
-                                       SerializerSession session = 
s.createSession(os, p, req.getJavaMethod(), req.getLocale(), req.getTimeZone(), 
mediaType);
+                                       SerializerSession session = 
s.createSession(os, p, req.getJavaMethod(), req.getLocale(), 
req.getHeaders().getTimeZone(), mediaType);
                                        s2.serialize(session, output);
                                        os.close();
                                } else {
                                        WriterSerializer s2 = 
(WriterSerializer)s;
                                        Writer w = res.getNegotiatedWriter();
-                                       SerializerSession session = 
s.createSession(w, p, req.getJavaMethod(), req.getLocale(), req.getTimeZone(), 
mediaType);
+                                       SerializerSession session = 
s.createSession(w, p, req.getJavaMethod(), req.getLocale(), 
req.getHeaders().getTimeZone(), mediaType);
                                        s2.serialize(session, output);
                                        w.close();
                                }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/321f6bde/juneau-rest/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/vars/RequestVar.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
index 455a375..f02c2ab 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
@@ -72,9 +72,9 @@ public class RequestVar extends SimpleVar {
                                        if ("path".equals(prefix))
                                                return 
req.getPathParameter(remainder);
                                        if ("query".equals(prefix))
-                                               return 
req.getQueryParameter(remainder);
+                                               return req.getQuery(remainder);
                                        if ("formData".equals(prefix))
-                                               return 
req.getFormDataParameter(remainder);
+                                               return 
req.getFormData(remainder);
                                        if ("header".equals(prefix))
                                                return req.getHeader(remainder);
                                        if ("attribute".equals(prefix))

Reply via email to