You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/05/08 14:51:05 UTC

[1/2] incubator-juneau git commit: Add support for custom REST method parameter resolvers.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master d6fe4ff9d -> c9797b775


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
index 8451144..9e2e52d 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
@@ -579,13 +579,78 @@
 		<ul class='spaced-list'>
 			<li>Parameters of the following class types:
 				<ul>
-					<li>{@link org.apache.juneau.rest.RestRequest} - The request object.
-					<li>{@link javax.servlet.http.HttpServletRequest} - The superclass of <code>RestRequest</code>.
-					<li>{@link org.apache.juneau.rest.RestResponse} - The response object.
-					<li>{@link javax.servlet.http.HttpServletResponse} - The superclass of <code>RestResponse</code>.
-					<li>{@link org.apache.juneau.http.Accept} - The parsed <code>Accept</code> header.
-					<li>{@link org.apache.juneau.http.AcceptEncoding} - The parsed <code>Accept-Encoding</code> header.
-					<li>{@link org.apache.juneau.http.ContentType} - The parsed <code>Content-Type</code> header.
+					<li>Request/response objects:
+						<ul>
+							<li>{@link org.apache.juneau.rest.RestRequest} - The request object.
+							<li>{@link javax.servlet.http.HttpServletRequest} - The superclass of <code>RestRequest</code>.
+							<li>{@link org.apache.juneau.rest.RestResponse} - The response object.
+							<li>{@link javax.servlet.http.HttpServletResponse} - The superclass of <code>RestResponse</code>.
+						</ul>
+					<li>Parsed request header values:
+						<ul>
+							<li>{@link org.apache.juneau.http.Accept}
+							<li>{@link org.apache.juneau.http.AcceptCharset}
+							<li>{@link org.apache.juneau.http.AcceptEncoding}
+							<li>{@link org.apache.juneau.http.AcceptLanguage}
+							<li>{@link org.apache.juneau.http.Authorization}
+							<li>{@link org.apache.juneau.http.CacheControl}
+							<li>{@link org.apache.juneau.http.Connection}
+							<li>{@link org.apache.juneau.http.ContentLength}
+							<li>{@link org.apache.juneau.http.ContentType}
+							<li>{@link org.apache.juneau.http.Date}
+							<li>{@link org.apache.juneau.http.Expect}
+							<li>{@link org.apache.juneau.http.From}
+							<li>{@link org.apache.juneau.http.Host}
+							<li>{@link org.apache.juneau.http.IfMatch}
+							<li>{@link org.apache.juneau.http.IfModifiedSince}
+							<li>{@link org.apache.juneau.http.IfNoneMatch}
+							<li>{@link org.apache.juneau.http.IfRange}
+							<li>{@link org.apache.juneau.http.IfUnmodifiedSince}
+							<li>{@link org.apache.juneau.http.MaxForwards}
+							<li>{@link org.apache.juneau.http.Pragma}
+							<li>{@link org.apache.juneau.http.ProxyAuthorization}
+							<li>{@link org.apache.juneau.http.Range}
+							<li>{@link org.apache.juneau.http.Referer}
+							<li>{@link org.apache.juneau.http.TE}
+							<li>{@link org.apache.juneau.http.UserAgent}
+							<li>{@link org.apache.juneau.http.Upgrade}
+							<li>{@link org.apache.juneau.http.Via}
+							<li>{@link org.apache.juneau.http.Warning}
+							<li>{@link java.util.TimeZone}
+						</ul>
+					<li>Direct streams on request/response:
+						<ul>
+							<li>{@link java.io.InputStream}
+							<li>{@link javax.servlet.ServletInputStream}
+							<li>{@link java.io.Reader}
+							<li>{@link java.io.OutputStream}
+							<li>{@link javax.servlet.ServletOutputStream}
+							<li>{@link java.io.Writer}
+						</ul>
+					<li>Localization:
+						<ul>
+							<li>{@link java.util.ResourceBundle} - Client-localized resource bundle.
+							<li>{@link org.apache.juneau.utils.MessageBundle} - A resource bundle with additional features.
+							<li>{@link java.util.Locale} - Client locale.
+						</ul>
+					<li>Request APIs:
+						<ul>
+							<li>{@link org.apache.juneau.rest.RequestHeaders} - API for accessing request headers.
+							<li>{@link org.apache.juneau.rest.RequestQuery} - API for accessing request query parameters.
+							<li>{@link org.apache.juneau.rest.RequestFormData} - API for accessing request form data.
+							<li>{@link org.apache.juneau.rest.RequestPathParams} - API for accessing path variables.
+							<li>{@link org.apache.juneau.rest.RequestBody} - API for accessing request body.
+						</ul>
+					<li>Other:
+						<ul>
+							<li>{@link org.apache.juneau.http.HttpMethod} - The method name matched (when using <code><ja>@RestMethod</ja>(name=<js>"*"</js>)</code>)
+							<li>{@link java.util.logging.Logger} - The logger to use for logging.
+							<li>{@link org.apache.juneau.internal.JuneauLogger} - Logger with additional features.
+							<li>{@link org.apache.juneau.rest.RestContext} - The resource read-only context.
+							<li>{@link org.apache.juneau.parser.Parser} - The parser matching the request content type.
+							<li>{@link org.apache.juneau.dto.swagger.Swagger} - The auto-generated Swagger doc.
+							<li>{@link org.apache.juneau.ini.ConfigFile} - The external config file for the resource.
+						</ul>
 				</ul>
 			<li>Annotated parameters:
 				<ul>
@@ -641,21 +706,8 @@
 	}
 		</p>
 		<p>
-			All annotations have programmatic equivalents on the {@link org.apache.juneau.rest.RestRequest} class:
+			All annotations have programmatic equivalents on the {@link org.apache.juneau.rest.RestRequest} class.
 		</p>
-		<ul class='javahierarchy'>
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Class)}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Class)}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#hasFormDataParameter(String)}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Class)}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#hasQueryParameter(String)}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#getBody(Class)}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Class)}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#getMethod()}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#getPathRemainder()}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#getMessage(String,Object[])}
-			<li class='m'>{@link org.apache.juneau.rest.RestRequest#getProperties()}
-		</ul>
 		
 		<!-- ======================================================================================================== -->
 		<a id="RestResources.MethodSignature.Path"></a>
@@ -820,7 +872,7 @@
 		</p>
 		<p>
 			The HTTP body of a request can be retrieved as a parsed POJO using either the 
-				{@link org.apache.juneau.rest.RestRequest#getBody(Class)} method, or a parameter 
+				{@link org.apache.juneau.rest.RestRequest#getBody()} method, or a parameter 
 				annotated with {@link org.apache.juneau.rest.annotation.Body @Body}.
 		</p>
 		<p class='bcode'>
@@ -833,7 +885,7 @@
 	<jc>// Equivalent method 2</jc>
 	<ja>@RestMethod</ja>(name=<js>"POST"</js>, path=<js>"/example2"</js>)
 	<jk>public void</jk> doPost2(RestRequest req) {
-		Person p = req.getBody(Person.<jk>class</jk>);
+		Person p = req.getBody).asType(Person.<jk>class</jk>);
 		<jc>// Do something with p.</jc>
 	}
 		</p>
@@ -896,7 +948,7 @@
 					cause the underlying JEE servlet to parse the HTTP body as a form post.
 				Your input bean will end up being null since there won't be any content left
 					after the servlet has parsed the body of the request.
-				This applies to WHENEVER you use <l>@Body</l> or {@link org.apache.juneau.rest.RestRequest#getBody(Class)}.
+				This applies to WHENEVER you use <l>@Body</l> or {@link org.apache.juneau.rest.RestRequest#getBody()}.
 		</p>	
 		</div>
 
@@ -2036,14 +2088,14 @@
 					<ul>
 						<li><ck>$R{attribute.X}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getAttribute(String)} converted to a string.
 						<li><ck>$R{contextPath}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getContextPath()}.
-						<li><ck>$R{formData.X}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String)}.
+						<li><ck>$R{formData.X}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getFormData(String)}.
 						<li><ck>$R{header.X}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getHeader(String)}.
 						<li><ck>$R{method}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getMethod()}.
 						<li><ck>$R{methodSummary}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getMethodSummary()}.
 						<li><ck>$R{methodDescription}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getMethodDescription()}.
 						<li><ck>$R{path.X}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getPathParameter(String)}.
 						<li><ck>$R{pathInfo}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getPathInfo()}.
-						<li><ck>$R{query.X}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getQueryParameter(String)}.
+						<li><ck>$R{query.X}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getQuery(String)}.
 						<li><ck>$R{requestParentURI}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getRequestParentURI()}.
 						<li><ck>$R{requestURI}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getRequestURI()}.
 						<li><ck>$R{servletDescription}</ck> - Value returned by {@link org.apache.juneau.rest.RestRequest#getServletDescription()}.
@@ -3114,7 +3166,7 @@
 <div class='topic'>
 		<p>
 		Certain methods in the REST server API allow you to specify class types that can be convertable
-			from <l>Strings</l> (e.g. {@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Class)}).
+			from <l>Strings</l> (e.g. {@link org.apache.juneau.rest.RestRequest#getPathParameter(String)}).
 		</p>
 		<p>
 		POJOs convertable from <l>Strings</l> have one of the following:


[2/2] incubator-juneau git commit: Add support for custom REST method parameter resolvers.

Posted by ja...@apache.org.
Add support for custom REST method parameter resolvers.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/c9797b77
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/c9797b77
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/c9797b77

Branch: refs/heads/master
Commit: c9797b7756a14929d4095c028d7174a8d0f694e6
Parents: d6fe4ff
Author: JamesBognar <ja...@apache.org>
Authored: Mon May 8 10:50:58 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Mon May 8 10:50:58 2017 -0400

----------------------------------------------------------------------
 juneau-core/src/main/javadoc/overview.html      | 156 ++-
 .../org/apache/juneau/microservice/package.html |   4 +-
 .../java/org/apache/juneau/rest/CallMethod.java | 124 +--
 .../java/org/apache/juneau/rest/RestConfig.java |  17 +-
 .../org/apache/juneau/rest/RestContext.java     |  92 ++
 .../java/org/apache/juneau/rest/RestParam.java  | 914 +-----------------
 .../apache/juneau/rest/RestParamDefaults.java   | 944 +++++++++++++++++++
 .../juneau/rest/annotation/RestResource.java    |  32 +
 .../java/org/apache/juneau/rest/package.html    | 106 ++-
 9 files changed, 1286 insertions(+), 1103 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html
index 44ef436..ae07cf3 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -3101,9 +3101,10 @@
 			<li class='m'><l>doGetExample2()</l>
 				<br>Identical to <l>doGetExample1()</l> but shows how to use the {@link org.apache.juneau.rest.RestRequest} and {@link org.apache.juneau.rest.RestResponse} objects:
 				<ul>
-					<li class='m'>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Class)}
-					<li class='m'>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Class)}
-					<li class='m'>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Class)}
+					<li class='m'>{@link org.apache.juneau.rest.RestRequest#getPathParams()}
+					<li class='m'>{@link org.apache.juneau.rest.RestRequest#getQuery()}
+					<li class='m'>{@link org.apache.juneau.rest.RestRequest#getFormData()}
+					<li class='m'>{@link org.apache.juneau.rest.RestRequest#getHeaders()}
 					<li class='m'>{@link org.apache.juneau.rest.RestRequest#getMethod()}
 					<li class='m'>{@link org.apache.juneau.rest.RestRequest#getPathRemainder()}
 				</ul>
@@ -5934,6 +5935,69 @@
 					<li>{@link org.apache.juneau.rest.RequestFormData}
 					<li>{@link org.apache.juneau.rest.RequestPathParams}
 				</ul>						
+			<li>The unannotated parameter types that can be passed in through REST Java methods has been significantly expanded.
+				<br>For reference, the previous supported types were:
+				<ul>
+					<li>{@link org.apache.juneau.rest.RestRequest} - The request object.
+					<li>{@link javax.servlet.http.HttpServletRequest} - The superclass of <code>RestRequest</code>.
+					<li>{@link org.apache.juneau.rest.RestResponse} - The response object.
+					<li>{@link javax.servlet.http.HttpServletResponse} - The superclass of <code>RestResponse</code>.
+				</ul>
+				The new supported types are:
+				<ul>
+					<li>{@link org.apache.juneau.http.Accept}
+					<li>{@link org.apache.juneau.http.AcceptCharset}
+					<li>{@link org.apache.juneau.http.AcceptEncoding}
+					<li>{@link org.apache.juneau.http.AcceptLanguage}
+					<li>{@link org.apache.juneau.http.Authorization}
+					<li>{@link org.apache.juneau.http.CacheControl}
+					<li>{@link org.apache.juneau.http.Connection}
+					<li>{@link org.apache.juneau.http.ContentLength}
+					<li>{@link org.apache.juneau.http.ContentType}
+					<li>{@link org.apache.juneau.http.Date}
+					<li>{@link org.apache.juneau.http.Expect}
+					<li>{@link org.apache.juneau.http.From}
+					<li>{@link org.apache.juneau.http.Host}
+					<li>{@link org.apache.juneau.http.IfMatch}
+					<li>{@link org.apache.juneau.http.IfModifiedSince}
+					<li>{@link org.apache.juneau.http.IfNoneMatch}
+					<li>{@link org.apache.juneau.http.IfRange}
+					<li>{@link org.apache.juneau.http.IfUnmodifiedSince}
+					<li>{@link org.apache.juneau.http.MaxForwards}
+					<li>{@link org.apache.juneau.http.Pragma}
+					<li>{@link org.apache.juneau.http.ProxyAuthorization}
+					<li>{@link org.apache.juneau.http.Range}
+					<li>{@link org.apache.juneau.http.Referer}
+					<li>{@link org.apache.juneau.http.TE}
+					<li>{@link org.apache.juneau.http.UserAgent}
+					<li>{@link org.apache.juneau.http.Upgrade}
+					<li>{@link org.apache.juneau.http.Via}
+					<li>{@link org.apache.juneau.http.Warning}
+					<li>{@link java.util.TimeZone}
+					<li>{@link java.io.InputStream}
+					<li>{@link javax.servlet.ServletInputStream}
+					<li>{@link java.io.Reader}
+					<li>{@link java.io.OutputStream}
+					<li>{@link javax.servlet.ServletOutputStream}
+					<li>{@link java.io.Writer}
+					<li>{@link java.util.ResourceBundle} - Client-localized resource bundle.
+					<li>{@link org.apache.juneau.utils.MessageBundle} - A resource bundle with additional features.
+					<li>{@link java.util.Locale} - Client locale.
+					<li>{@link org.apache.juneau.rest.RequestHeaders} - API for accessing request headers.
+					<li>{@link org.apache.juneau.rest.RequestQuery} - API for accessing request query parameters.
+					<li>{@link org.apache.juneau.rest.RequestFormData} - API for accessing request form data.
+					<li>{@link org.apache.juneau.rest.RequestPathParams} - API for accessing path variables.
+					<li>{@link org.apache.juneau.rest.RequestBody} - API for accessing request body.
+					<li>{@link org.apache.juneau.http.HttpMethod} - The method name matched (when using <code><ja>@RestMethod</ja>(name=<js>"*"</js>)</code>)
+					<li>{@link java.util.logging.Logger} - The logger to use for logging.
+					<li>{@link org.apache.juneau.internal.JuneauLogger} - Logger with additional features.
+					<li>{@link org.apache.juneau.rest.RestContext} - The resource read-only context.
+					<li>{@link org.apache.juneau.parser.Parser} - The parser matching the request content type.
+					<li>{@link org.apache.juneau.dto.swagger.Swagger} - The auto-generated Swagger doc.
+					<li>{@link org.apache.juneau.ini.ConfigFile} - The external config file for the resource.
+				</ul>
+			<li>A new annotation {@link org.apache.juneau.rest.annotation.RestResource#paramResolvers() @RestResource.paramResolvers()}
+				that allows you to define your own custom Java method parameter resolvers.
 		</ul>
 
 		<h6 class='topic'>org.apache.juneau.rest.client</h6>
@@ -6448,28 +6512,28 @@
 		<h6 class='topic'>org.apache.juneau.rest</h6>
 		<ul class='spaced-list'>
 			<li>{@link org.apache.juneau.rest.RestRequest} now passes locale and timezone to serializers/parsers/transforms.
-			<li>New {@link org.apache.juneau.rest.RestRequest#getTimeZone()} method.
+			<li><code><del>RestRequest.getTimeZone()</del></code> method.
 			<li>Standardized the following methods in {@link org.apache.juneau.rest.RestRequest} to remove dependency on <code>ClassMeta</code>
 				objects and eliminate the need for casts:
 				<ul>
-					<li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Class) getHeader(String,Class)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Object,Class) getHeader(String)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Type,Type...)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Class)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Object,Class)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Type,Type...)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Object,Type,Type...)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Class)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Type,Type...)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Class)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Object,Class)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameters(String,Class)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Type,Type...)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameters(String,Type,Type...)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Class)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Type,Type...)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getBody(Class)}
-					<li>{@link org.apache.juneau.rest.RestRequest#getBody(Type,Type...)}
+					<li><code><del>RestRequest.getHeader(String,Class)</del></code>
+					<li><code><del>RestRequest.getHeader(String,Object,Class)</del></code>
+					<li><code><del>RestRequest.getHeader(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getQueryParameter(String,Class)</del></code>
+					<li><code><del>RestRequest.getQueryParameter(String,Object,Class)</del></code>
+					<li><code><del>RestRequest.getQueryParameter(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getQueryParameter(String,Object,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getQueryParameters(String,Class)</del></code>
+					<li><code><del>RestRequest.getQueryParameters(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getFormDataParameter(String,Class)</del></code>
+					<li><code><del>RestRequest.getFormDataParameter(String,Object,Class)</del></code>
+					<li><code><del>RestRequest.getFormDataParameters(String,Class)</del></code>
+					<li><code><del>RestRequest.getFormDataParameter(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getFormDataParameters(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getPathParameter(String,Class)</del></code>
+					<li><code><del>RestRequest.getPathParameter(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getBody(Class)</del></code>
+					<li><code><del>RestRequest.getBody(Type,Type...)</del></code>
 				</ul>
 			<li>New methods on {@link org.apache.juneau.rest.client.NameValuePairs}
 			<li>Fixed issue where whitespace was not added to UON/URL-Encoding output when <code>&amp;plainText=true</code> specified.
@@ -7365,8 +7429,8 @@
 				<ul>
 					<li>Added new methods:
 						<ul>
-							<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameterMap()}
-							<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameterNames()}
+							<li><code><del>RestRequest.getQueryParameterMap()</del></code>
+							<li><code><del>RestRequest.getQueryParameterNames()</del></code>
 							<li>{@link org.apache.juneau.rest.RestRequest#getPathInfoUndecoded()}
 							<li>{@link org.apache.juneau.rest.RestRequest#getPathRemainderUndecoded()}
 							<li>{@link org.apache.juneau.rest.RestRequest#getTrimmedRequestURI()}
@@ -7515,24 +7579,24 @@
 		<ul class='spaced-list'>
 			<li>New methods in {@link org.apache.juneau.rest.client.RestCall}:
 				<ol>
-<li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Object,Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getHeader(String,Type,Type...)}
-<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Object,Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Type,Type...)}
-<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameter(String,Object,Type,Type...)}
-<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Type,Type...)}
-<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Object,Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameters(String,Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String,Type,Type...)}
-<li>{@link org.apache.juneau.rest.RestRequest#getFormDataParameters(String,Type,Type...)}
-<li>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getPathParameter(String,Type,Type...)}
-<li>{@link org.apache.juneau.rest.RestRequest#getBody(Class)}
-<li>{@link org.apache.juneau.rest.RestRequest#getBody(Type,Type...)}
+					<li><code><del>RestRequest.getHeader(String,Class)</del></code>
+					<li><code><del>RestRequest.getHeader(String,Object,Class)</del></code>
+					<li><code><del>RestRequest.getHeader(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getQueryParameter(String,Class)</del></code>
+					<li><code><del>RestRequest.getQueryParameter(String,Object,Class)</del></code>
+					<li><code><del>RestRequest.getQueryParameter(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getQueryParameter(String,Object,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getQueryParameters(String,Class)</del></code>
+					<li><code><del>RestRequest.getQueryParameters(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getFormDataParameter(String,Class)</del></code>
+					<li><code><del>RestRequest.getFormDataParameter(String,Object,Class)</del></code>
+					<li><code><del>RestRequest.getFormDataParameters(String,Class)</del></code>
+					<li><code><del>RestRequest.getFormDataParameter(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getFormDataParameters(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getPathParameter(String,Class)</del></code>
+					<li><code><del>RestRequest.getPathParameter(String,Type,Type...)</del></code>
+					<li><code><del>RestRequest.getBody(Class)</del></code>
+					<li><code><del>RestRequest.getBody(Type,Type...)</del></code>
 				</ol>
 			</li>
 		</ul>
@@ -7572,8 +7636,8 @@
 				explicitely specify which HTTP methods can be used in the <code>&amp;method</code> parameter.
 			<li>New methods added to {@link org.apache.juneau.rest.RestRequest}:
 			<ul>
-				<li>{@link org.apache.juneau.rest.RestRequest#getParser()}
-				<li>{@link org.apache.juneau.rest.RestRequest#getReaderParser()}
+				<li><code><del>RestRequest.getParser()</del></code>
+				<li><code><del>RestRequest.getReaderParser()</del></code>
 			</ul>
 		</ul>
 	</div>
@@ -7697,7 +7761,7 @@
 			<li>New methods on {@link org.apache.juneau.rest.RestRequest} for handling multi-part parameters:
 				<ul>
 					<li><del><code>RestRequest.getParameters(String,Class)</code></del>
-					<li>{@link org.apache.juneau.rest.RestRequest#getQueryParameters(String,Class)}
+					<li><code><del>RestRequest#getQueryParameters(String,Class)</del></code>
 				</ul>
 			</li>
 			<li>Fixed Jetty issue in {@link org.apache.juneau.rest.RestResponse#setHeader(String,String)} where setting 
@@ -7757,7 +7821,7 @@
 			<li>Fixed major issue that prevented parsing URL-Encoded form posts into POJOs.
 				Calling <del><code>HttpServlet.getParameter(String)</code></del> was forcing the underlying servlet code to process the HTTP body itself, preventing the <code>UrlEncodingSerializer</code>
 				class from being able to parse the content.  Updated code no longer inadvertantly calls this method.
-			<li>New {@link org.apache.juneau.rest.RestRequest#getQueryParameter(String)}, {@link org.apache.juneau.rest.RestRequest#hasQueryParameter(String)}, and {@link org.apache.juneau.rest.RestRequest#hasAnyQueryParameters(String[])}
+			<li>New <code><del>RestRequest.getQueryParameter(String)</del></code>, <code><del>RestRequest.hasQueryParameter(String)</del></code>, and <code><del>RestRequest.hasAnyQueryParameters(String[])</del></code>
 				methods that only look for parameters in the URL query string to prevent loading and parsing of URL-Encoded form posts.
 			<li>New <del><code>@QParam</code></del> and <del><code>@HasQParam</code></del> annotations for accessing query parameters from the URL query string.
 			<li><code>&amp;plainText</code> parameter can now specify a false value.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html b/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
index 614e64a..2595771 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
@@ -652,14 +652,14 @@
 					<ul>
 			 			<li><l>$R{attribute.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getAttribute(String)} converted to a string.
 			 			<li><l>$R{contextPath}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getContextPath()}.
-			 			<li><l>$R{formData.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getFormDataParameter(String)}.
+			 			<li><l>$R{formData.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getFormData(String)}.
 			 			<li><l>$R{header.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getHeader(String)}.
 			 			<li><l>$R{method}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getMethod()}.
 			 			<li><l>$R{methodSummary}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getMethodSummary()}.
 			 			<li><l>$R{methodDescription}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getMethodDescription()}.
 			 			<li><l>$R{path.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getPathParameter(String)}.
 			 			<li><l>$R{pathInfo}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getPathInfo()}.
-			 			<li><l>$R{query.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getQueryParameter(String)}.
+			 			<li><l>$R{query.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getQuery(String)}.
 			 			<li><l>$R{requestParentURI}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getRequestParentURI()}.
 			 			<li><l>$R{requestURI}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getRequestURI()}.
 			 			<li><l>$R{servletDescription}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getServletDescription()}.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
index afc7a1e..4fe77de 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
@@ -18,12 +18,10 @@ import static org.apache.juneau.rest.RestContext.*;
 import static org.apache.juneau.rest.annotation.Inherit.*;
 import static org.apache.juneau.serializer.SerializerContext.*;
 
-import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.lang.reflect.Method;
 import java.util.*;
 
-import javax.servlet.*;
 import javax.servlet.http.*;
 
 import org.apache.juneau.*;
@@ -34,7 +32,6 @@ import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.annotation.Properties;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.svl.*;
 import org.apache.juneau.urlencoding.*;
@@ -47,7 +44,7 @@ class CallMethod implements Comparable<CallMethod>  {
 	private final java.lang.reflect.Method method;
 	private final String httpMethod;
 	private final UrlPathPattern pathPattern;
-	private final CallMethod.MethodParam[] params;
+	private final RestParam[] params;
 	private final RestGuard[] guards;
 	private final RestMatcher[] optionalMatchers;
 	private final RestMatcher[] requiredMatchers;
@@ -103,7 +100,7 @@ class CallMethod implements Comparable<CallMethod>  {
 	private static class Builder  {
 		private String httpMethod, defaultCharset, description, tags, summary, externalDocs, pageTitle, pageText, pageLinks;
 		private UrlPathPattern pathPattern;
-		private CallMethod.MethodParam[] params;
+		private RestParam[] params;
 		private RestGuard[] guards;
 		private RestMatcher[] optionalMatchers, requiredMatchers;
 		private RestConverter[] converters;
@@ -276,14 +273,7 @@ class CallMethod implements Comparable<CallMethod>  {
 
 				pathPattern = new UrlPathPattern(p);
 
-				int attrIdx = 0;
-				Type[] pt = method.getGenericParameterTypes();
-				Annotation[][] pa = method.getParameterAnnotations();
-				params = new CallMethod.MethodParam[pt.length];
-				for (int i = 0; i < params.length; i++) {
-					params[i] = new CallMethod.MethodParam(pt[i], method, pa[i], plainParams, pathPattern, attrIdx);
-					attrIdx = params[i].attrIdx;
-				}
+				params = context.findParams(method, plainParams, pathPattern);
 
 				if (sgb != null)
 					serializers = sgb.build();
@@ -303,110 +293,6 @@ class CallMethod implements Comparable<CallMethod>  {
 	}
 
 	/**
-	 * Represents a single parameter in the Java method.
-	 */
-	private static class MethodParam {
-
-		private final int attrIdx;
-		private final RestParam param;
-
-		private MethodParam(Type type, Method method, Annotation[] annotations, boolean methodPlainParams, UrlPathPattern pathPattern, int attrIdx) throws ServletException {
-
-			RestParam _param = null;
-			String _name = "";
-
-			boolean isClass = type instanceof Class;
-			if (isClass)
-				_param = RestParam.STANDARD_RESOLVERS.get(type);
-
-			if (_param == null) {
-				for (Annotation a : annotations) {
-					if (a instanceof Path) {
-						Path a2 = (Path)a;
-						_name = a2.value();
-					} else if (a instanceof Header) {
-						_param = new RestParam.HeaderObject(((Header)a).value(), type);
-					} else if (a instanceof FormData) {
-						FormData p = (FormData)a;
-						if (p.multipart())
-							assertCollection(type, method);
-						boolean plainParams = p.format().equals("INHERIT") ? methodPlainParams : p.format().equals("PLAIN");
-						_param = new RestParam.FormDataObject(p.value(), type, p.multipart(), plainParams);
-					} else if (a instanceof Query) {
-						Query p = (Query)a;
-						if (p.multipart())
-							assertCollection(type, method);
-						boolean plainParams = p.format().equals("INHERIT") ? methodPlainParams : p.format().equals("PLAIN");
-						_param = new RestParam.QueryObject(p.value(), type, p.multipart(), plainParams);
-					} else if (a instanceof HasFormData) {
-						_param = new RestParam.HasFormDataObject(((HasFormData)a).value(), type);
-					} else if (a instanceof HasQuery) {
-						_param = new RestParam.HasQueryObject(((HasQuery)a).value(), type);
-					} else if (a instanceof Body) {
-						_param = new RestParam.BodyObject(type);
-					} else if (a instanceof org.apache.juneau.rest.annotation.Method) {
-						_param = new RestParam.MethodObject(type);
-					} else if (a instanceof PathRemainder) {
-						_param = new RestParam.PathRemainderObject(type);
-					} else if (a instanceof Properties) {
-						_param = new RestParam.PropsObject(type);
-					} else if (a instanceof Messages) {
-						_param = new RestParam.MessageBundleObject();
-					}
-				}
-			}
-
-			if (_param == null) {
-
-				if (_name.isEmpty()) {
-					int idx = attrIdx++;
-					String[] vars = pathPattern.getVars();
-					if (vars.length <= idx)
-						throw new RestServletException("Number of attribute parameters in method ''{0}'' exceeds the number of URL pattern variables.", method.getName());
-
-					// Check for {#} variables.
-					String idxs = String.valueOf(idx);
-					for (int i = 0; i < vars.length; i++)
-						if (StringUtils.isNumeric(vars[i]) && vars[i].equals(idxs))
-							_name = vars[i];
-
-					if (_name.isEmpty())
-						_name = pathPattern.getVars()[idx];
-				}
-				_param = new RestParam.PathParameterObject(_name, type);
-			}
-
-			this.param = _param;
-			this.attrIdx = attrIdx;
-		}
-
-		/**
-		 * Throws an exception if the specified type isn't an array or collection.
-		 */
-		private static void assertCollection(Type t, Method m) throws ServletException {
-			ClassMeta<?> cm = BeanContext.DEFAULT.getClassMeta(t);
-			if (! cm.isCollectionOrArray())
-				throw new ServletException("Use of multipart flag on parameter that's not an array or Collection on method" + m);
-		}
-
-		private Object getValue(RestRequest req, RestResponse res) throws Exception {
-			return param.resolve(req, res);
-		}
-
-		private RestParamType getParamType() {
-			return param.getParamType();
-		}
-
-		private String getName() {
-			return param.getName();
-		}
-
-		private Type getType() {
-			return param.getType();
-		}
-	}
-
-	/**
 	 * Returns <jk>true</jk> if this Java method has any guards or matchers.
 	 */
 	boolean hasGuardsOrMatchers() {
@@ -633,7 +519,7 @@ class CallMethod implements Comparable<CallMethod>  {
 		}
 
 		// Finally, look for parameters defined on method.
-		for (CallMethod.MethodParam mp : this.params) {
+		for (RestParam mp : this.params) {
 			RestParamType in = mp.getParamType();
 			if (in != RestParamType.OTHER) {
 				String k2 = in.toString() + '.' + (in == RestParamType.BODY ? null : mp.getName());
@@ -800,7 +686,7 @@ class CallMethod implements Comparable<CallMethod>  {
 		Object[] args = new Object[params.length];
 		for (int i = 0; i < params.length; i++) {
 			try {
-				args[i] = params[i].getValue(req, res);
+				args[i] = params[i].resolve(req, res);
 			} catch (RestException e) {
 				throw e;
 			} catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
index 2a33a34..a04c95e 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestConfig.java
@@ -85,7 +85,8 @@ public class RestConfig implements ServletConfig {
 
 	List<Class<?>>
 		beanFilters = new ArrayList<Class<?>>(),
-		pojoSwaps = new ArrayList<Class<?>>();
+		pojoSwaps = new ArrayList<Class<?>>(),
+		paramResolvers = new ArrayList<Class<?>>();
 	SerializerGroupBuilder serializers = new SerializerGroupBuilder();
 	ParserGroupBuilder parsers = new ParserGroupBuilder();
 	EncoderGroupBuilder encoders = new EncoderGroupBuilder().append(IdentityEncoder.INSTANCE);
@@ -184,6 +185,7 @@ public class RestConfig implements ServletConfig {
 				addChildResources(r.children());
 				addBeanFilters(r.beanFilters());
 				addPojoSwaps(r.pojoSwaps());
+				addParamResolvers(r.paramResolvers());
 				if (! r.stylesheet().isEmpty())
 					setStyleSheet(c, r.stylesheet());
 				if (! r.favicon().isEmpty())
@@ -362,6 +364,19 @@ public class RestConfig implements ServletConfig {
 	}
 
 	/**
+	 * Adds class-level parameter resolvers to this resource.
+	 * <p>
+	 * This is the programmatic equivalent to the {@link RestResource#paramResolvers() @RestResource.paramResolvers()} annotation.
+	 *
+	 * @param paramResolvers The parameter resolvers to add to this config.
+	 * @return This object (for method chaining).
+	 */
+	public RestConfig addParamResolvers(Class<? extends RestParam>...paramResolvers) {
+		this.paramResolvers.addAll(Arrays.asList(paramResolvers));
+		return this;
+	}
+
+	/**
 	 * Adds class-level serializers to this resource.
 	 * <p>
 	 * This is the programmatic equivalent to the {@link RestResource#serializers() @RestResource.serializers()} annotation.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
index 54a3fa0..258ff01 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -16,6 +16,7 @@ import static javax.servlet.http.HttpServletResponse.*;
 import static org.apache.juneau.internal.StringUtils.*;
 
 import java.io.*;
+import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.lang.reflect.Method;
 import java.util.*;
@@ -33,6 +34,7 @@ import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.annotation.Properties;
 import org.apache.juneau.rest.vars.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.svl.*;
@@ -300,6 +302,7 @@ public final class RestContext extends Context {
 	private final Class<?>[]
 		beanFilters,
 		pojoSwaps;
+	private final Map<Class<?>,RestParam> paramResolvers;
 	private final SerializerGroup serializers;
 	private final ParserGroup parsers;
 	private final UrlEncodingSerializer urlEncodingSerializer;
@@ -366,6 +369,7 @@ public final class RestContext extends Context {
 			this.properties = b.properties;
 			this.beanFilters = b.beanFilters;
 			this.pojoSwaps = b.pojoSwaps;
+			this.paramResolvers = Collections.unmodifiableMap(b.paramResolvers);
 			this.serializers = b.serializers;
 			this.parsers = b.parsers;
 			this.urlEncodingSerializer = b.urlEncodingSerializer;
@@ -557,6 +561,7 @@ public final class RestContext extends Context {
 		ObjectMap properties;
 		Class<?>[] beanFilters;
 		Class<?>[] pojoSwaps;
+		Map<Class<?>,RestParam> paramResolvers = new HashMap<Class<?>,RestParam>();
 		SerializerGroup serializers;
 		ParserGroup parsers;
 		UrlEncodingSerializer urlEncodingSerializer;
@@ -609,6 +614,12 @@ public final class RestContext extends Context {
 			Collections.reverse(sc.pojoSwaps);
 			beanFilters = ArrayUtils.toObjectArray(sc.beanFilters, Class.class);
 			pojoSwaps = ArrayUtils.toObjectArray(sc.pojoSwaps, Class.class);
+
+			for (Class<?> c : sc.paramResolvers) {
+				RestParam rp = (RestParam)c.newInstance();
+				paramResolvers.put(rp.forClass(), rp);
+			}
+
 			clientVersionHeader = sc.clientVersionHeader;
 
 			// Find resource resource bundle location.
@@ -1254,6 +1265,87 @@ public final class RestContext extends Context {
 	}
 
 	/**
+	 * Finds the {@link RestParam} instances to handle resolving objects on the calls to the specified Java method.
+	 *
+	 * @param method The Java method being called.
+	 * @param methodPlainParams Whether plain-params setting is specified.
+	 * @param pathPattern The parsed URL path pattern.
+	 * @return The array of resolvers.
+	 * @throws ServletException If an annotation usage error was detected.
+	 */
+	protected RestParam[] findParams(Method method, boolean methodPlainParams, UrlPathPattern pathPattern) throws ServletException {
+
+		Type[] pt = method.getGenericParameterTypes();
+		Annotation[][] pa = method.getParameterAnnotations();
+		RestParam[] rp = new RestParam[pt.length];
+		int attrIndex = 0;
+
+		for (int i = 0; i < pt.length; i++) {
+
+			Type t = pt[i];
+			if (t instanceof Class) {
+				Class<?> c = (Class<?>)t;
+				rp[i] = paramResolvers.get(c);
+				if (rp[i] == null)
+					rp[i] = RestParamDefaults.STANDARD_RESOLVERS.get(c);
+			}
+
+			if (rp[i] == null) {
+				for (Annotation a : pa[i]) {
+					if (a instanceof Header)
+						rp[i] = new RestParamDefaults.HeaderObject((Header)a, t);
+					else if (a instanceof FormData)
+						rp[i] = new RestParamDefaults.FormDataObject(method, (FormData)a, t, methodPlainParams);
+					else if (a instanceof Query)
+						rp[i] = new RestParamDefaults.QueryObject(method, (Query)a, t, methodPlainParams);
+					else if (a instanceof HasFormData)
+						rp[i] = new RestParamDefaults.HasFormDataObject(method, (HasFormData)a, t);
+					else if (a instanceof HasQuery)
+						rp[i] = new RestParamDefaults.HasQueryObject(method, (HasQuery)a, t);
+					else if (a instanceof Body)
+						rp[i] = new RestParamDefaults.BodyObject(t);
+					else if (a instanceof org.apache.juneau.rest.annotation.Method)
+						rp[i] = new RestParamDefaults.MethodObject(method, t);
+					else if (a instanceof PathRemainder)
+						rp[i] = new RestParamDefaults.PathRemainderObject(method, t);
+					else if (a instanceof Properties)
+						rp[i] = new RestParamDefaults.PropsObject(method, t);
+					else if (a instanceof Messages)
+						rp[i] = new RestParamDefaults.MessageBundleObject();
+				}
+			}
+
+			if (rp[i] == null) {
+				Path p = null;
+				for (Annotation a : pa[i])
+					if (a instanceof Path)
+						p = (Path)a;
+
+				String name = (p == null ? "" : p.value());
+
+				if (name.isEmpty()) {
+					int idx = attrIndex++;
+					String[] vars = pathPattern.getVars();
+					if (vars.length <= idx)
+						throw new RestServletException("Number of attribute parameters in method ''{0}'' exceeds the number of URL pattern variables.", method.getName());
+
+					// Check for {#} variables.
+					String idxs = String.valueOf(idx);
+					for (int j = 0; j < vars.length; j++)
+						if (StringUtils.isNumeric(vars[j]) && vars[j].equals(idxs))
+							name = vars[j];
+
+					if (name.isEmpty())
+						name = pathPattern.getVars()[idx];
+				}
+				rp[i] = new RestParamDefaults.PathParameterObject(name, t);
+			}
+		}
+
+		return rp;
+	}
+
+	/**
 	 * Returns the URL-encoding parser associated with this resource.
 	 * @return The URL-encoding parser associated with this resource.  Never <jk>null</jk>.
 	 */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java
index c6e176e..4e834b4 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParam.java
@@ -12,114 +12,20 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest;
 
-import static org.apache.juneau.rest.RestParamType.*;
-
-import java.io.*;
 import java.lang.reflect.*;
-import java.util.*;
-import java.util.logging.*;
-
-import javax.servlet.*;
-import javax.servlet.http.*;
 
-import org.apache.juneau.*;
-import org.apache.juneau.dto.swagger.*;
-import org.apache.juneau.http.*;
-import org.apache.juneau.http.Date;
-import org.apache.juneau.ini.*;
-import org.apache.juneau.internal.*;
-import org.apache.juneau.parser.*;
-import org.apache.juneau.utils.*;
+import org.apache.juneau.rest.annotation.*;
 
 /**
  * REST java method parameter resolver.
+ * <p>
+ * Used to resolve instances of classes being passed to Java REST methods.
+ * <p>
+ * This class is associated with REST classes via the {@link RestResource#paramResolvers()} annotation and
+ * {@link RestConfig#addParamResolvers(Class...)} method.
  */
 public abstract class RestParam {
 
-	/**
-	 * Standard set of method parameter resolvers.
-	 */
-	public static final Map<Class<?>,RestParam> STANDARD_RESOLVERS;
-
-	static {
-		Map<Class<?>,RestParam> m = new HashMap<Class<?>,RestParam>();
-
-		@SuppressWarnings("rawtypes")
-		Class[] r = new Class[] {
-
-			// Standard top-level objects
-			HttpServletRequestObject.class,
-			RestRequestObject.class,
-			HttpServletResponseObject.class,
-			RestResponseObject.class,
-
-			// Headers
-			AcceptHeader.class,
-			AcceptCharsetHeader.class,
-			AcceptEncodingHeader.class,
-			AcceptLanguageHeader.class,
-			AuthorizationHeader.class,
-			CacheControlHeader.class,
-			ConnectionHeader.class,
-			ContentLengthHeader.class,
-			ContentTypeHeader.class,
-			DateHeader.class,
-			ExpectHeader.class,
-			FromHeader.class,
-			HostHeader.class,
-			IfMatchHeader.class,
-			IfModifiedSinceHeader.class,
-			IfNoneMatchHeader.class,
-			IfRangeHeader.class,
-			IfUnmodifiedSinceHeader.class,
-			MaxForwardsHeader.class,
-			PragmaHeader.class,
-			ProxyAuthorizationHeader.class,
-			RangeHeader.class,
-			RefererHeader.class,
-			TEHeader.class,
-			UserAgentHeader.class,
-			UpgradeHeader.class,
-			ViaHeader.class,
-			WarningHeader.class,
-			TimeZoneHeader.class,
-
-			// Other objects
-			ResourceBundleObject.class,
-			MessageBundleObject.class,
-			InputStreamObject.class,
-			ServletInputStreamObject.class,
-			ReaderObject.class,
-			OutputStreamObject.class,
-			ServletOutputStreamObject.class,
-			WriterObject.class,
-			RequestHeadersObject.class,
-			RequestQueryParamsObject.class,
-			RequestFormDataObject.class,
-			HttpMethodObject.class,
-			LoggerObject.class,
-			JuneauLoggerObject.class,
-			RestContextObject.class,
-			ParserObject.class,
-			LocaleObject.class,
-			SwaggerObject.class,
-			RequestPathParamsObject.class,
-			RequestBodyObject.class,
-			ConfigFileObject.class,
-		};
-
-		for (Class<?> c : r) {
-			try {
-				RestParam mpr = (RestParam)c.newInstance();
-				m.put(mpr.forClass(), mpr);
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
-
-		STANDARD_RESOLVERS = Collections.unmodifiableMap(m);
-	}
-
 	final RestParamType paramType;
 	final String name;
 	final Type type;
@@ -181,812 +87,4 @@ public abstract class RestParam {
 	public Type getType() {
 		return type;
 	}
-
-	//-------------------------------------------------------------------------------------------------------------------
-	// Request / Response retrievers
-	//-------------------------------------------------------------------------------------------------------------------
-
-	static final class HttpServletRequestObject extends RestParam {
-
-		protected HttpServletRequestObject() {
-			super(OTHER, null, HttpServletRequest.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) {
-			return req;
-		}
-	}
-
-	static final class HttpServletResponseObject extends RestParam {
-
-		protected HttpServletResponseObject() {
-			super(OTHER, null, HttpServletResponse.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) {
-			return res;
-		}
-	}
-
-	static final class RestRequestObject extends RestParam {
-
-		protected RestRequestObject() {
-			super(OTHER, null, RestRequest.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) {
-			return req;
-		}
-	}
-
-	static final class RestResponseObject extends RestParam {
-
-		protected RestResponseObject() {
-			super(OTHER, null, RestResponse.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) {
-			return res;
-		}
-	}
-
-	//-------------------------------------------------------------------------------------------------------------------
-	// Header retrievers
-	//-------------------------------------------------------------------------------------------------------------------
-
-	static final class AcceptHeader extends RestParam {
-
-		protected AcceptHeader() {
-			super(HEADER, "Accept-Header", Accept.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getAccept();
-		}
-	}
-
-	static final class AcceptCharsetHeader extends RestParam {
-
-		protected AcceptCharsetHeader() {
-			super(HEADER, "Accept-Charset", AcceptCharset.class);
-		}
-
-		@Override /* RestParam */
-		public AcceptCharset resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getAcceptCharset();
-		}
-	}
-
-	static final class AcceptEncodingHeader extends RestParam {
-
-		protected AcceptEncodingHeader() {
-			super(HEADER, "Accept-Encoding", AcceptEncoding.class);
-		}
-
-		@Override
-		public AcceptEncoding resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getAcceptEncoding();
-		}
-	}
-
-	static final class AcceptLanguageHeader extends RestParam {
-
-		protected AcceptLanguageHeader() {
-			super(HEADER, "Accept-Language", AcceptLanguage.class);
-		}
-
-		@Override
-		public AcceptLanguage resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getAcceptLanguage();
-		}
-	}
-
-	static final class AuthorizationHeader extends RestParam {
-
-		protected AuthorizationHeader() {
-			super(HEADER, "Authorization", Authorization.class);
-		}
-
-		@Override
-		public Authorization resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getAuthorization();
-		}
-	}
-
-	static final class CacheControlHeader extends RestParam {
-
-		protected CacheControlHeader() {
-			super(HEADER, "Cache-Control", CacheControl.class);
-		}
-
-		@Override
-		public CacheControl resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getCacheControl();
-		}
-	}
-
-	static final class ConnectionHeader extends RestParam {
-
-		protected ConnectionHeader() {
-			super(HEADER, "Connection", Connection.class);
-		}
-
-		@Override
-		public Connection resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getConnection();
-		}
-	}
-
-	static final class ContentLengthHeader extends RestParam {
-
-		protected ContentLengthHeader() {
-			super(HEADER, "Content-Length", ContentLength.class);
-		}
-
-		@Override
-		public ContentLength resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getContentLength();
-		}
-	}
-
-	static final class ContentTypeHeader extends RestParam {
-
-		protected ContentTypeHeader() {
-			super(HEADER, "Content-Type", ContentType.class);
-		}
-
-		@Override
-		public ContentType resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getContentType();
-		}
-	}
-
-	static final class DateHeader extends RestParam {
-
-		protected DateHeader() {
-			super(HEADER, "Date", Date.class);
-		}
-
-		@Override
-		public Date resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getDate();
-		}
-	}
-
-	static final class ExpectHeader extends RestParam {
-
-		protected ExpectHeader() {
-			super(HEADER, "Expect", Expect.class);
-		}
-
-		@Override
-		public Expect resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getExpect();
-		}
-	}
-
-	static final class FromHeader extends RestParam {
-
-		protected FromHeader() {
-			super(HEADER, "From", From.class);
-		}
-
-		@Override
-		public From resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getFrom();
-		}
-	}
-
-	static final class HostHeader extends RestParam {
-
-		protected HostHeader() {
-			super(HEADER, "Host", Host.class);
-		}
-
-		@Override
-		public Host resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getHost();
-		}
-	}
-
-	static final class IfMatchHeader extends RestParam {
-
-		protected IfMatchHeader() {
-			super(HEADER, "If-Match", IfMatch.class);
-		}
-
-		@Override
-		public IfMatch resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getIfMatch();
-		}
-	}
-
-	static final class IfModifiedSinceHeader extends RestParam {
-
-		protected IfModifiedSinceHeader() {
-			super(HEADER, "If-Modified-Since", IfModifiedSince.class);
-		}
-
-		@Override
-		public IfModifiedSince resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getIfModifiedSince();
-		}
-	}
-
-	static final class IfNoneMatchHeader extends RestParam {
-
-		protected IfNoneMatchHeader() {
-			super(HEADER, "If-None-Match", IfNoneMatch.class);
-		}
-
-		@Override
-		public IfNoneMatch resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getIfNoneMatch();
-		}
-	}
-
-	static final class IfRangeHeader extends RestParam {
-
-		protected IfRangeHeader() {
-			super(HEADER, "If-Range", IfRange.class);
-		}
-
-		@Override
-		public IfRange resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getIfRange();
-		}
-	}
-
-	static final class IfUnmodifiedSinceHeader extends RestParam {
-
-		protected IfUnmodifiedSinceHeader() {
-			super(HEADER, "If-Unmodified-Since", IfUnmodifiedSince.class);
-		}
-
-		@Override
-		public IfUnmodifiedSince resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getIfUnmodifiedSince();
-		}
-	}
-
-	static final class MaxForwardsHeader extends RestParam {
-
-		protected MaxForwardsHeader() {
-			super(HEADER, "Max-Forwards", MaxForwards.class);
-		}
-
-		@Override
-		public MaxForwards resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getMaxForwards();
-		}
-	}
-
-	static final class PragmaHeader extends RestParam {
-
-		protected PragmaHeader() {
-			super(HEADER, "Pragma", Pragma.class);
-		}
-
-		@Override
-		public Pragma resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getPragma();
-		}
-	}
-
-	static final class ProxyAuthorizationHeader extends RestParam {
-
-		protected ProxyAuthorizationHeader() {
-			super(HEADER, "Proxy-Authorization", ProxyAuthorization.class);
-		}
-
-		@Override
-		public ProxyAuthorization resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getProxyAuthorization();
-		}
-	}
-
-	static final class RangeHeader extends RestParam {
-
-		protected RangeHeader() {
-			super(HEADER, "Range", Range.class);
-		}
-
-		@Override
-		public Range resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getRange();
-		}
-	}
-
-	static final class RefererHeader extends RestParam {
-
-		protected RefererHeader() {
-			super(HEADER, "Referer", Referer.class);
-		}
-
-		@Override
-		public Referer resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getReferer();
-		}
-	}
-
-	static final class TEHeader extends RestParam {
-
-		protected TEHeader() {
-			super(HEADER, "TE", TE.class);
-		}
-
-		@Override
-		public TE resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getTE();
-		}
-	}
-
-	static final class UserAgentHeader extends RestParam {
-
-		protected UserAgentHeader() {
-			super(HEADER, "User-Agent", UserAgent.class);
-		}
-
-		@Override
-		public UserAgent resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getUserAgent();
-		}
-	}
-
-	static final class UpgradeHeader extends RestParam {
-
-		protected UpgradeHeader() {
-			super(HEADER, "Upgrade", Upgrade.class);
-		}
-
-		@Override
-		public Upgrade resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getUpgrade();
-		}
-	}
-
-	static final class ViaHeader extends RestParam {
-
-		protected ViaHeader() {
-			super(HEADER, "Via", Via.class);
-		}
-
-		@Override
-		public Via resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getVia();
-		}
-	}
-
-	static final class WarningHeader extends RestParam {
-
-		protected WarningHeader() {
-			super(HEADER, "Warning", Warning.class);
-		}
-
-		@Override
-		public Warning resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getWarning();
-		}
-	}
-
-	static final class TimeZoneHeader extends RestParam {
-
-		protected TimeZoneHeader() {
-			super(HEADER, "Time-Zone", TimeZone.class);
-		}
-
-		@Override
-		public TimeZone resolve(RestRequest req, RestResponse res) {
-			return req.getHeaders().getTimeZone();
-		}
-	}
-
-	//-------------------------------------------------------------------------------------------------------------------
-	// Annotated retrievers
-	//-------------------------------------------------------------------------------------------------------------------
-
-	static final class PathParameterObject extends RestParam {
-
-		protected PathParameterObject(String name, Type type) {
-			super(PATH, name, type);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getPathParams().get(name, type);
-		}
-	}
-
-	static final class BodyObject extends RestParam {
-
-		protected BodyObject(Type type) {
-			super(BODY, null, type);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getBody().asType(type);
-		}
-	}
-
-	static final class HeaderObject extends RestParam {
-
-		protected HeaderObject(String name, Type type) {
-			super(HEADER, name, type);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getHeaders().get(name, type);
-		}
-	}
-
-	static final class MethodObject extends RestParam {
-
-		protected MethodObject(Type type) throws ServletException {
-			super(OTHER, null, null);
-			if (type != String.class)
-				throw new ServletException("@Method parameters must be of type String");
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getMethod();
-		}
-	}
-
-	static final class FormDataObject extends RestParam {
-		private final boolean multiPart, plainParams;
-
-		protected FormDataObject(String name, Type type, boolean multiPart, boolean plainParams) {
-			super(FORMDATA, name, type);
-			this.multiPart = multiPart;
-			this.plainParams = plainParams;
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			BeanSession bs = req.getBeanSession();
-			if (multiPart)
-				return req.getFormData().getAll(name, type);
-			if (plainParams)
-				return bs.convertToType(req.getFormData(name), bs.getClassMeta(type));
-			return req.getFormData().get(name, type);
-		}
-	}
-
-	static final class QueryObject extends RestParam {
-		private final boolean multiPart, plainParams;
-
-		protected QueryObject(String name, Type type, boolean multiPart, boolean plainParams) {
-			super(QUERY, name, type);
-			this.multiPart = multiPart;
-			this.plainParams = plainParams;
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			BeanSession bs = req.getBeanSession();
-			if (multiPart)
-				return req.getQuery().getAll(name, type);
-			if (plainParams)
-				return bs.convertToType(req.getQuery(name), bs.getClassMeta(type));
-			return req.getQuery().get(name, type);
-		}
-	}
-
-	static final class HasFormDataObject extends RestParam {
-
-		protected HasFormDataObject(String name, Type type) {
-			super(FORMDATA, name, type);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			BeanSession bs = req.getBeanSession();
-			return bs.convertToType(req.getFormData().containsKey(name), bs.getClassMeta(type));
-		}
-	}
-
-	static final class HasQueryObject extends RestParam {
-
-		protected HasQueryObject(String name, Type type) {
-			super(QUERY, name, type);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			BeanSession bs = req.getBeanSession();
-			return bs.convertToType(req.getQuery().containsKey(name), bs.getClassMeta(type));
-		}
-	}
-
-	static final class PathRemainderObject extends RestParam {
-
-		protected PathRemainderObject(Type type) throws ServletException {
-			super(OTHER, null, null);
-			if (type != String.class)
-				throw new ServletException("@PathRemainder parameters must be of type String");
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getPathRemainder();
-		}
-	}
-
-	static final class PropsObject extends RestParam {
-
-		protected PropsObject(Type type) throws ServletException {
-			super(OTHER, null, null);
-			if (! ClassUtils.isParentClass(LinkedHashMap.class, type))
-				throw new ServletException("@PathRemainder parameters must be of type String");
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getProperties();
-		}
-	}
-
-	//-------------------------------------------------------------------------------------------------------------------
-	// Other retrievers
-	//-------------------------------------------------------------------------------------------------------------------
-
-	static final class ResourceBundleObject extends RestParam {
-
-		protected ResourceBundleObject() {
-			super(OTHER, null, ResourceBundle.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getResourceBundle();
-		}
-	}
-
-	static final class MessageBundleObject extends RestParam {
-
-		protected MessageBundleObject() {
-			super(OTHER, null, MessageBundle.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getResourceBundle();
-		}
-	}
-
-	static final class InputStreamObject extends RestParam {
-
-		protected InputStreamObject() {
-			super(OTHER, null, InputStream.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getInputStream();
-		}
-	}
-
-	static final class ServletInputStreamObject extends RestParam {
-
-		protected ServletInputStreamObject() {
-			super(OTHER, null, ServletInputStream.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getInputStream();
-		}
-	}
-
-	static final class ReaderObject extends RestParam {
-
-		protected ReaderObject() {
-			super(OTHER, null, Reader.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getReader();
-		}
-	}
-
-	static final class OutputStreamObject extends RestParam {
-
-		protected OutputStreamObject() {
-			super(OTHER, null, OutputStream.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return res.getOutputStream();
-		}
-	}
-
-	static final class ServletOutputStreamObject extends RestParam {
-
-		protected ServletOutputStreamObject() {
-			super(OTHER, null, ServletOutputStream.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return res.getOutputStream();
-		}
-	}
-
-	static final class WriterObject extends RestParam {
-
-		protected WriterObject() {
-			super(OTHER, null, Writer.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return res.getWriter();
-		}
-	}
-
-	static final class RequestHeadersObject extends RestParam {
-
-		protected RequestHeadersObject() {
-			super(OTHER, null, RequestHeaders.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getHeaders();
-		}
-	}
-
-	static final class RequestQueryParamsObject extends RestParam {
-
-		protected RequestQueryParamsObject() {
-			super(OTHER, null, RequestQuery.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getQuery();
-		}
-	}
-
-	static final class RequestFormDataObject extends RestParam {
-
-		protected RequestFormDataObject() {
-			super(OTHER, null, RequestFormData.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getFormData();
-		}
-	}
-
-	static final class HttpMethodObject extends RestParam {
-
-		protected HttpMethodObject() {
-			super(OTHER, null, HttpMethod.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getHttpMethod();
-		}
-	}
-
-	static final class LoggerObject extends RestParam {
-
-		protected LoggerObject() {
-			super(OTHER, null, Logger.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getContext().getLogger().getLogger();
-		}
-	}
-
-	static final class JuneauLoggerObject extends RestParam {
-
-		protected JuneauLoggerObject() {
-			super(OTHER, null, JuneauLogger.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getContext().getLogger().getLogger();
-		}
-	}
-
-	static final class RestContextObject extends RestParam {
-
-		protected RestContextObject() {
-			super(OTHER, null, RestContext.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getContext();
-		}
-	}
-
-	static final class ParserObject extends RestParam {
-
-		protected ParserObject() {
-			super(OTHER, null, Parser.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getBody().getParser();
-		}
-	}
-
-	static final class LocaleObject extends RestParam {
-
-		protected LocaleObject() {
-			super(OTHER, null, Locale.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getLocale();
-		}
-	}
-
-	static final class SwaggerObject extends RestParam {
-
-		protected SwaggerObject() {
-			super(OTHER, null, Swagger.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getSwagger();
-		}
-	}
-
-	static final class RequestPathParamsObject extends RestParam {
-
-		protected RequestPathParamsObject() {
-			super(OTHER, null, RequestPathParams.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getPathParams();
-		}
-	}
-
-	static final class RequestBodyObject extends RestParam {
-
-		protected RequestBodyObject() {
-			super(BODY, null, RequestBody.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getBody();
-		}
-	}
-
-	static final class ConfigFileObject extends RestParam {
-
-		protected ConfigFileObject() {
-			super(OTHER, null, ConfigFile.class);
-		}
-
-		@Override /* RestParam */
-		public Object resolve(RestRequest req, RestResponse res) throws Exception {
-			return req.getConfigFile();
-		}
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
new file mode 100644
index 0000000..dc29cc6
--- /dev/null
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
@@ -0,0 +1,944 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.rest;
+
+import static org.apache.juneau.rest.RestParamType.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.logging.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.dto.swagger.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.http.Date;
+import org.apache.juneau.ini.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * Default REST method parameter resolvers.
+ */
+class RestParamDefaults {
+
+	/**
+	 * Standard set of method parameter resolvers.
+	 */
+	static final Map<Class<?>,RestParam> STANDARD_RESOLVERS;
+
+	static {
+		Map<Class<?>,RestParam> m = new HashMap<Class<?>,RestParam>();
+
+		@SuppressWarnings("rawtypes")
+		Class[] r = new Class[] {
+
+			// Standard top-level objects
+			HttpServletRequestObject.class,
+			RestRequestObject.class,
+			HttpServletResponseObject.class,
+			RestResponseObject.class,
+
+			// Headers
+			AcceptHeader.class,
+			AcceptCharsetHeader.class,
+			AcceptEncodingHeader.class,
+			AcceptLanguageHeader.class,
+			AuthorizationHeader.class,
+			CacheControlHeader.class,
+			ConnectionHeader.class,
+			ContentLengthHeader.class,
+			ContentTypeHeader.class,
+			DateHeader.class,
+			ExpectHeader.class,
+			FromHeader.class,
+			HostHeader.class,
+			IfMatchHeader.class,
+			IfModifiedSinceHeader.class,
+			IfNoneMatchHeader.class,
+			IfRangeHeader.class,
+			IfUnmodifiedSinceHeader.class,
+			MaxForwardsHeader.class,
+			PragmaHeader.class,
+			ProxyAuthorizationHeader.class,
+			RangeHeader.class,
+			RefererHeader.class,
+			TEHeader.class,
+			UserAgentHeader.class,
+			UpgradeHeader.class,
+			ViaHeader.class,
+			WarningHeader.class,
+			TimeZoneHeader.class,
+
+			// Other objects
+			ResourceBundleObject.class,
+			MessageBundleObject.class,
+			InputStreamObject.class,
+			ServletInputStreamObject.class,
+			ReaderObject.class,
+			OutputStreamObject.class,
+			ServletOutputStreamObject.class,
+			WriterObject.class,
+			RequestHeadersObject.class,
+			RequestQueryParamsObject.class,
+			RequestFormDataObject.class,
+			HttpMethodObject.class,
+			LoggerObject.class,
+			JuneauLoggerObject.class,
+			RestContextObject.class,
+			ParserObject.class,
+			LocaleObject.class,
+			SwaggerObject.class,
+			RequestPathParamsObject.class,
+			RequestBodyObject.class,
+			ConfigFileObject.class,
+		};
+
+		for (Class<?> c : r) {
+			try {
+				RestParam mpr = (RestParam)c.newInstance();
+				m.put(mpr.forClass(), mpr);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+
+		STANDARD_RESOLVERS = Collections.unmodifiableMap(m);
+	}
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Request / Response retrievers
+	//-------------------------------------------------------------------------------------------------------------------
+
+	static final class HttpServletRequestObject extends RestParam {
+
+		protected HttpServletRequestObject() {
+			super(OTHER, null, HttpServletRequest.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) {
+			return req;
+		}
+	}
+
+	static final class HttpServletResponseObject extends RestParam {
+
+		protected HttpServletResponseObject() {
+			super(OTHER, null, HttpServletResponse.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) {
+			return res;
+		}
+	}
+
+	static final class RestRequestObject extends RestParam {
+
+		protected RestRequestObject() {
+			super(OTHER, null, RestRequest.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) {
+			return req;
+		}
+	}
+
+	static final class RestResponseObject extends RestParam {
+
+		protected RestResponseObject() {
+			super(OTHER, null, RestResponse.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) {
+			return res;
+		}
+	}
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Header retrievers
+	//-------------------------------------------------------------------------------------------------------------------
+
+	static final class AcceptHeader extends RestParam {
+
+		protected AcceptHeader() {
+			super(HEADER, "Accept-Header", Accept.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getAccept();
+		}
+	}
+
+	static final class AcceptCharsetHeader extends RestParam {
+
+		protected AcceptCharsetHeader() {
+			super(HEADER, "Accept-Charset", AcceptCharset.class);
+		}
+
+		@Override /* RestParam */
+		public AcceptCharset resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getAcceptCharset();
+		}
+	}
+
+	static final class AcceptEncodingHeader extends RestParam {
+
+		protected AcceptEncodingHeader() {
+			super(HEADER, "Accept-Encoding", AcceptEncoding.class);
+		}
+
+		@Override
+		public AcceptEncoding resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getAcceptEncoding();
+		}
+	}
+
+	static final class AcceptLanguageHeader extends RestParam {
+
+		protected AcceptLanguageHeader() {
+			super(HEADER, "Accept-Language", AcceptLanguage.class);
+		}
+
+		@Override
+		public AcceptLanguage resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getAcceptLanguage();
+		}
+	}
+
+	static final class AuthorizationHeader extends RestParam {
+
+		protected AuthorizationHeader() {
+			super(HEADER, "Authorization", Authorization.class);
+		}
+
+		@Override
+		public Authorization resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getAuthorization();
+		}
+	}
+
+	static final class CacheControlHeader extends RestParam {
+
+		protected CacheControlHeader() {
+			super(HEADER, "Cache-Control", CacheControl.class);
+		}
+
+		@Override
+		public CacheControl resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getCacheControl();
+		}
+	}
+
+	static final class ConnectionHeader extends RestParam {
+
+		protected ConnectionHeader() {
+			super(HEADER, "Connection", Connection.class);
+		}
+
+		@Override
+		public Connection resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getConnection();
+		}
+	}
+
+	static final class ContentLengthHeader extends RestParam {
+
+		protected ContentLengthHeader() {
+			super(HEADER, "Content-Length", ContentLength.class);
+		}
+
+		@Override
+		public ContentLength resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getContentLength();
+		}
+	}
+
+	static final class ContentTypeHeader extends RestParam {
+
+		protected ContentTypeHeader() {
+			super(HEADER, "Content-Type", ContentType.class);
+		}
+
+		@Override
+		public ContentType resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getContentType();
+		}
+	}
+
+	static final class DateHeader extends RestParam {
+
+		protected DateHeader() {
+			super(HEADER, "Date", Date.class);
+		}
+
+		@Override
+		public Date resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getDate();
+		}
+	}
+
+	static final class ExpectHeader extends RestParam {
+
+		protected ExpectHeader() {
+			super(HEADER, "Expect", Expect.class);
+		}
+
+		@Override
+		public Expect resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getExpect();
+		}
+	}
+
+	static final class FromHeader extends RestParam {
+
+		protected FromHeader() {
+			super(HEADER, "From", From.class);
+		}
+
+		@Override
+		public From resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getFrom();
+		}
+	}
+
+	static final class HostHeader extends RestParam {
+
+		protected HostHeader() {
+			super(HEADER, "Host", Host.class);
+		}
+
+		@Override
+		public Host resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getHost();
+		}
+	}
+
+	static final class IfMatchHeader extends RestParam {
+
+		protected IfMatchHeader() {
+			super(HEADER, "If-Match", IfMatch.class);
+		}
+
+		@Override
+		public IfMatch resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getIfMatch();
+		}
+	}
+
+	static final class IfModifiedSinceHeader extends RestParam {
+
+		protected IfModifiedSinceHeader() {
+			super(HEADER, "If-Modified-Since", IfModifiedSince.class);
+		}
+
+		@Override
+		public IfModifiedSince resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getIfModifiedSince();
+		}
+	}
+
+	static final class IfNoneMatchHeader extends RestParam {
+
+		protected IfNoneMatchHeader() {
+			super(HEADER, "If-None-Match", IfNoneMatch.class);
+		}
+
+		@Override
+		public IfNoneMatch resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getIfNoneMatch();
+		}
+	}
+
+	static final class IfRangeHeader extends RestParam {
+
+		protected IfRangeHeader() {
+			super(HEADER, "If-Range", IfRange.class);
+		}
+
+		@Override
+		public IfRange resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getIfRange();
+		}
+	}
+
+	static final class IfUnmodifiedSinceHeader extends RestParam {
+
+		protected IfUnmodifiedSinceHeader() {
+			super(HEADER, "If-Unmodified-Since", IfUnmodifiedSince.class);
+		}
+
+		@Override
+		public IfUnmodifiedSince resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getIfUnmodifiedSince();
+		}
+	}
+
+	static final class MaxForwardsHeader extends RestParam {
+
+		protected MaxForwardsHeader() {
+			super(HEADER, "Max-Forwards", MaxForwards.class);
+		}
+
+		@Override
+		public MaxForwards resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getMaxForwards();
+		}
+	}
+
+	static final class PragmaHeader extends RestParam {
+
+		protected PragmaHeader() {
+			super(HEADER, "Pragma", Pragma.class);
+		}
+
+		@Override
+		public Pragma resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getPragma();
+		}
+	}
+
+	static final class ProxyAuthorizationHeader extends RestParam {
+
+		protected ProxyAuthorizationHeader() {
+			super(HEADER, "Proxy-Authorization", ProxyAuthorization.class);
+		}
+
+		@Override
+		public ProxyAuthorization resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getProxyAuthorization();
+		}
+	}
+
+	static final class RangeHeader extends RestParam {
+
+		protected RangeHeader() {
+			super(HEADER, "Range", Range.class);
+		}
+
+		@Override
+		public Range resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getRange();
+		}
+	}
+
+	static final class RefererHeader extends RestParam {
+
+		protected RefererHeader() {
+			super(HEADER, "Referer", Referer.class);
+		}
+
+		@Override
+		public Referer resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getReferer();
+		}
+	}
+
+	static final class TEHeader extends RestParam {
+
+		protected TEHeader() {
+			super(HEADER, "TE", TE.class);
+		}
+
+		@Override
+		public TE resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getTE();
+		}
+	}
+
+	static final class UserAgentHeader extends RestParam {
+
+		protected UserAgentHeader() {
+			super(HEADER, "User-Agent", UserAgent.class);
+		}
+
+		@Override
+		public UserAgent resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getUserAgent();
+		}
+	}
+
+	static final class UpgradeHeader extends RestParam {
+
+		protected UpgradeHeader() {
+			super(HEADER, "Upgrade", Upgrade.class);
+		}
+
+		@Override
+		public Upgrade resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getUpgrade();
+		}
+	}
+
+	static final class ViaHeader extends RestParam {
+
+		protected ViaHeader() {
+			super(HEADER, "Via", Via.class);
+		}
+
+		@Override
+		public Via resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getVia();
+		}
+	}
+
+	static final class WarningHeader extends RestParam {
+
+		protected WarningHeader() {
+			super(HEADER, "Warning", Warning.class);
+		}
+
+		@Override
+		public Warning resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getWarning();
+		}
+	}
+
+	static final class TimeZoneHeader extends RestParam {
+
+		protected TimeZoneHeader() {
+			super(HEADER, "Time-Zone", TimeZone.class);
+		}
+
+		@Override
+		public TimeZone resolve(RestRequest req, RestResponse res) {
+			return req.getHeaders().getTimeZone();
+		}
+	}
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Annotated retrievers
+	//-------------------------------------------------------------------------------------------------------------------
+
+	static final class PathParameterObject extends RestParam {
+
+		protected PathParameterObject(String name, Type type) {
+			super(PATH, name, type);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getPathParams().get(name, type);
+		}
+	}
+
+	static final class BodyObject extends RestParam {
+
+		protected BodyObject(Type type) {
+			super(BODY, null, type);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getBody().asType(type);
+		}
+	}
+
+	static final class HeaderObject extends RestParam {
+
+		protected HeaderObject(Header a, Type type) {
+			super(HEADER, a.value(), type);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getHeaders().get(name, type);
+		}
+	}
+
+	static final class MethodObject extends RestParam {
+
+		protected MethodObject(Method method, Type type) throws ServletException {
+			super(OTHER, null, null);
+			if (type != String.class)
+				throw new RestServletException("Use of @Method annotation on parameter that is not a String on method ''{0}''", method);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getMethod();
+		}
+	}
+
+	static final class FormDataObject extends RestParam {
+		private final boolean multiPart, plainParams;
+
+		protected FormDataObject(Method method, FormData a, Type type, boolean methodPlainParams) throws ServletException {
+			super(FORMDATA, a.value(), type);
+			if (a.multipart() && ! isCollection(type))
+					throw new RestServletException("Use of multipart flag on @FormData parameter that's not an array or Collection on method ''{0}''", method);
+			this.multiPart = a.multipart();
+			this.plainParams = a.format().equals("INHERIT") ? methodPlainParams : a.format().equals("PLAIN");
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			BeanSession bs = req.getBeanSession();
+			if (multiPart)
+				return req.getFormData().getAll(name, type);
+			if (plainParams)
+				return bs.convertToType(req.getFormData(name), bs.getClassMeta(type));
+			return req.getFormData().get(name, type);
+		}
+	}
+
+	static final class QueryObject extends RestParam {
+		private final boolean multiPart, plainParams;
+
+		protected QueryObject(Method method, Query a, Type type, boolean methodPlainParams) throws ServletException {
+			super(QUERY, a.value(), type);
+			if (a.multipart() && ! isCollection(type))
+					throw new RestServletException("Use of multipart flag on @Query parameter that's not an array or Collection on method ''{0}''", method);
+			this.multiPart = a.multipart();
+			this.plainParams = a.format().equals("INHERIT") ? methodPlainParams : a.format().equals("PLAIN");
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			BeanSession bs = req.getBeanSession();
+			if (multiPart)
+				return req.getQuery().getAll(name, type);
+			if (plainParams)
+				return bs.convertToType(req.getQuery(name), bs.getClassMeta(type));
+			return req.getQuery().get(name, type);
+		}
+	}
+
+	static final class HasFormDataObject extends RestParam {
+
+		protected HasFormDataObject(Method method, HasFormData a, Type type) throws ServletException {
+			super(FORMDATA, a.value(), type);
+			if (type != Boolean.class && type != boolean.class)
+				throw new RestServletException("Use of @HasForm annotation on parameter that is not a boolean on method ''{0}''", method);
+	}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			BeanSession bs = req.getBeanSession();
+			return bs.convertToType(req.getFormData().containsKey(name), bs.getClassMeta(type));
+		}
+	}
+
+	static final class HasQueryObject extends RestParam {
+
+		protected HasQueryObject(Method method, HasQuery a, Type type) throws ServletException {
+			super(QUERY, a.value(), type);
+			if (type != Boolean.class && type != boolean.class)
+				throw new RestServletException("Use of @HasQuery annotation on parameter that is not a boolean on method ''{0}''", method);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			BeanSession bs = req.getBeanSession();
+			return bs.convertToType(req.getQuery().containsKey(name), bs.getClassMeta(type));
+		}
+	}
+
+	static final class PathRemainderObject extends RestParam {
+
+		protected PathRemainderObject(Method method, Type type) throws ServletException {
+			super(OTHER, null, null);
+			if (type != String.class)
+				throw new RestServletException("Use of @PathRemainder annotation on parameter that is not a String on method ''{0}''", method);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getPathRemainder();
+		}
+	}
+
+	static final class PropsObject extends RestParam {
+
+		protected PropsObject(Method method, Type type) throws ServletException {
+			super(OTHER, null, null);
+			if (type != ObjectMap.class)
+				throw new RestServletException("Use of @Properties annotation on parameter that is not an ObjectMap on method ''{0}''", method);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getProperties();
+		}
+	}
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Other retrievers
+	//-------------------------------------------------------------------------------------------------------------------
+
+	static final class ResourceBundleObject extends RestParam {
+
+		protected ResourceBundleObject() {
+			super(OTHER, null, ResourceBundle.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getResourceBundle();
+		}
+	}
+
+	static final class MessageBundleObject extends RestParam {
+
+		protected MessageBundleObject() {
+			super(OTHER, null, MessageBundle.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getResourceBundle();
+		}
+	}
+
+	static final class InputStreamObject extends RestParam {
+
+		protected InputStreamObject() {
+			super(OTHER, null, InputStream.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getInputStream();
+		}
+	}
+
+	static final class ServletInputStreamObject extends RestParam {
+
+		protected ServletInputStreamObject() {
+			super(OTHER, null, ServletInputStream.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getInputStream();
+		}
+	}
+
+	static final class ReaderObject extends RestParam {
+
+		protected ReaderObject() {
+			super(OTHER, null, Reader.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getReader();
+		}
+	}
+
+	static final class OutputStreamObject extends RestParam {
+
+		protected OutputStreamObject() {
+			super(OTHER, null, OutputStream.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return res.getOutputStream();
+		}
+	}
+
+	static final class ServletOutputStreamObject extends RestParam {
+
+		protected ServletOutputStreamObject() {
+			super(OTHER, null, ServletOutputStream.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return res.getOutputStream();
+		}
+	}
+
+	static final class WriterObject extends RestParam {
+
+		protected WriterObject() {
+			super(OTHER, null, Writer.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return res.getWriter();
+		}
+	}
+
+	static final class RequestHeadersObject extends RestParam {
+
+		protected RequestHeadersObject() {
+			super(OTHER, null, RequestHeaders.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getHeaders();
+		}
+	}
+
+	static final class RequestQueryParamsObject extends RestParam {
+
+		protected RequestQueryParamsObject() {
+			super(OTHER, null, RequestQuery.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getQuery();
+		}
+	}
+
+	static final class RequestFormDataObject extends RestParam {
+
+		protected RequestFormDataObject() {
+			super(OTHER, null, RequestFormData.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getFormData();
+		}
+	}
+
+	static final class HttpMethodObject extends RestParam {
+
+		protected HttpMethodObject() {
+			super(OTHER, null, HttpMethod.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getHttpMethod();
+		}
+	}
+
+	static final class LoggerObject extends RestParam {
+
+		protected LoggerObject() {
+			super(OTHER, null, Logger.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getContext().getLogger().getLogger();
+		}
+	}
+
+	static final class JuneauLoggerObject extends RestParam {
+
+		protected JuneauLoggerObject() {
+			super(OTHER, null, JuneauLogger.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getContext().getLogger().getLogger();
+		}
+	}
+
+	static final class RestContextObject extends RestParam {
+
+		protected RestContextObject() {
+			super(OTHER, null, RestContext.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getContext();
+		}
+	}
+
+	static final class ParserObject extends RestParam {
+
+		protected ParserObject() {
+			super(OTHER, null, Parser.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getBody().getParser();
+		}
+	}
+
+	static final class LocaleObject extends RestParam {
+
+		protected LocaleObject() {
+			super(OTHER, null, Locale.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getLocale();
+		}
+	}
+
+	static final class SwaggerObject extends RestParam {
+
+		protected SwaggerObject() {
+			super(OTHER, null, Swagger.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getSwagger();
+		}
+	}
+
+	static final class RequestPathParamsObject extends RestParam {
+
+		protected RequestPathParamsObject() {
+			super(OTHER, null, RequestPathParams.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getPathParams();
+		}
+	}
+
+	static final class RequestBodyObject extends RestParam {
+
+		protected RequestBodyObject() {
+			super(BODY, null, RequestBody.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getBody();
+		}
+	}
+
+	static final class ConfigFileObject extends RestParam {
+
+		protected ConfigFileObject() {
+			super(OTHER, null, ConfigFile.class);
+		}
+
+		@Override /* RestParam */
+		public Object resolve(RestRequest req, RestResponse res) throws Exception {
+			return req.getConfigFile();
+		}
+	}
+
+	private static boolean isCollection(Type t) {
+		return BeanContext.DEFAULT.getClassMeta(t).isCollectionOrArray();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c9797b77/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
index 6f0c323..fee53d0 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
@@ -128,6 +128,38 @@ public @interface RestResource {
 	Class<?>[] pojoSwaps() default {};
 
 	/**
+	 * Class-level Java method parameter resolvers.
+	 * <p>
+	 * By default, the Juneau framework will automatically Java method parameters of various types (e.g.
+	 * <code>RestRequest</code>, <code>Accept</code>, <code>Reader</code>).
+	 * This annotation allows you to provide your own resolvers for your own class types that you want resolved.
+	 * <p>
+	 * For example, if you want to pass in instances of <code>MySpecialObject</code> to your Java method, define
+	 * the following resolver:
+	 * <p class='bcode'>
+	 * 	<jk>public class</jk> MyRestParam <jk>extends</jk> RestParam {
+	 *
+	 * 		<jc>// Must have no-arg constructor!</jc>
+	 * 		<jk>public</jk> MyRestParam() {
+	 * 			<jc>// First two parameters help with Swagger doc generation.</jc>
+	 * 			<jk>super</jk>(<jsf>QUERY</jsf>, <js>"myparam"</js>, MySpecialObject.<jk>class</jk>);
+	 * 		}
+	 *
+	 * 		<jc>// The method that creates our object.
+	 * 		// In this case, we're taking in a query parameter and converting it to our object.</jc>
+	 * 		<jk>public</jk> Object resolve(RestRequest req, RestResponse res) <jk>throws</jk> Exception {
+	 * 			<jk>return new</jk> MySpecialObject(req.getQuery().get(<js>"myparam"</js>));
+	 * 		}
+	 * 	}
+	 * </p>
+	 * <p>
+	 * <b>Note:</b>{@link RestParam} classes must have no-arg constructors.
+	 * <p>
+	 * The programmatic equivalent to this annotation is the {@link RestConfig#addParamResolvers(Class...)} method.
+	 */
+	Class<? extends RestParam>[] paramResolvers() default {};
+
+	/**
 	 * Class-level properties.
 	 * <p>
 	 * Shortcut for specifying class-level properties on this servlet to the objects returned by the following methods: