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 2018/01/07 18:00:38 UTC

juneau git commit: Update javadocs.

Repository: juneau
Updated Branches:
  refs/heads/master 5c21b4caa -> 34c9be07d


Update javadocs.

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

Branch: refs/heads/master
Commit: 34c9be07dd6341b161b90af8f1e6c34dd04cf722
Parents: 5c21b4c
Author: JamesBognar <ja...@apache.org>
Authored: Sun Jan 7 13:00:33 2018 -0500
Committer: JamesBognar <ja...@apache.org>
Committed: Sun Jan 7 13:00:33 2018 -0500

----------------------------------------------------------------------
 .../org/apache/juneau/rest/RestJavaMethod.java  |   23 +-
 .../juneau/rest/annotation/RestMethod.java      | 1085 ++++++++----------
 2 files changed, 506 insertions(+), 602 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/juneau/blob/34c9be07/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
index 3f0374a..55af351 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
@@ -144,6 +144,8 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 				RestMethod m = method.getAnnotation(RestMethod.class);
 				if (m == null)
 					throw new RestServletException("@RestMethod annotation not found on method ''{0}''", sig);
+				
+				VarResolver vr = context.getVarResolver();
 
 				if (! m.description().isEmpty())
 					description = m.description();
@@ -168,9 +170,9 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 				maxInput = context.getMaxInput();
 
 				if (! m.defaultCharset().isEmpty())
-					defaultCharset = context.getVarResolver().resolve(m.defaultCharset());
+					defaultCharset = vr.resolve(m.defaultCharset());
 				if (! m.maxInput().isEmpty())
-					maxInput = StringUtils.parseLongWithSuffix(context.getVarResolver().resolve(m.maxInput()));
+					maxInput = StringUtils.parseLongWithSuffix(vr.resolve(m.maxInput()));
 
 				HtmlDocBuilder hdb = new HtmlDocBuilder(properties);
 
@@ -349,7 +351,7 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 
 				defaultRequestHeaders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
 				for (String s : m.defaultRequestHeaders()) {
-					String[] h = RestUtils.parseKeyValuePair(s);
+					String[] h = RestUtils.parseKeyValuePair(vr.resolve(s));
 					if (h == null)
 						throw new RestServletException(
 							"Invalid default request header specified on method ''{0}'': ''{1}''.  Must be in the format: ''name[:=]value''", sig, s);
@@ -358,7 +360,7 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 
 				defaultQuery = new LinkedHashMap<>();
 				for (String s : m.defaultQuery()) {
-					String[] h = RestUtils.parseKeyValuePair(s);
+					String[] h = RestUtils.parseKeyValuePair(vr.resolve(s));
 					if (h == null)
 						throw new RestServletException(
 							"Invalid default query parameter specified on method ''{0}'': ''{1}''.  Must be in the format: ''name[:=]value''", sig, s);
@@ -367,7 +369,7 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 
 				defaultFormData = new LinkedHashMap<>();
 				for (String s : m.defaultFormData()) {
-					String[] h = RestUtils.parseKeyValuePair(s);
+					String[] h = RestUtils.parseKeyValuePair(vr.resolve(s));
 					if (h == null)
 						throw new RestServletException(
 							"Invalid default form data parameter specified on method ''{0}'': ''{1}''.  Must be in the format: ''name[:=]value''", sig, s);
@@ -409,11 +411,11 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 
 				supportedAcceptTypes = 
 					m.supportedAcceptTypes().length > 0 
-					? Collections.unmodifiableList(new ArrayList<>(Arrays.asList(MediaType.forStrings(m.supportedAcceptTypes())))) 
+					? Collections.unmodifiableList(new ArrayList<>(Arrays.asList(MediaType.forStrings(resolveVars(vr, m.supportedAcceptTypes()))))) 
 					: serializers.getSupportedMediaTypes();
 				supportedContentTypes =
 					m.supportedContentTypes().length > 0 
-					? Collections.unmodifiableList(new ArrayList<>(Arrays.asList(MediaType.forStrings(m.supportedContentTypes())))) 
+					? Collections.unmodifiableList(new ArrayList<>(Arrays.asList(MediaType.forStrings(resolveVars(vr, m.supportedContentTypes()))))) 
 					: parsers.getSupportedMediaTypes();
 					
 				params = context.findParams(method, pathPattern, false);
@@ -922,4 +924,11 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 	public int hashCode() {
 		return super.hashCode();
 	}
+	
+	static String[] resolveVars(VarResolver vr, String[] in) {
+		String[] out = new String[in.length];
+		for (int i = 0; i < in.length; i++) 
+			out[i] = vr.resolve(in[i]);
+		return out;
+	}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/juneau/blob/34c9be07/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index fc8a494..765ef25 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -18,12 +18,14 @@ import static java.lang.annotation.RetentionPolicy.*;
 import java.lang.annotation.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.encoders.*;
-import org.apache.juneau.http.*;
+import org.apache.juneau.encoders.Encoder;
+import org.apache.juneau.ini.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.remoteable.*;
 import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.vars.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.svl.vars.*;
 
 /**
  * Identifies a REST Java method on a {@link RestServlet} implementation class.
@@ -37,272 +39,392 @@ import org.apache.juneau.serializer.*;
 public @interface RestMethod {
 
 	/**
-	 * REST method name.
+	 * Appends the specified bean filters to all serializers and parsers used by this method.
+	 * 
+	 * <p>
+	 * See {@link BeanContext#BEAN_beanFilters} for more information.
+	 */
+	Class<?>[] beanFilters() default {};
+
+	/**
+	 * Shortcut for specifying the {@link BeanContext#BEAN_includeProperties} property on all serializers.
 	 *
 	 * <p>
-	 * Typically <js>"GET"</js>, <js>"PUT"</js>, <js>"POST"</js>, <js>"DELETE"</js>, or <js>"OPTIONS"</js>.
+	 * The typical use case is when you're rendering summary and details views of the same bean in a resource and
+	 * you want to expose or hide specific properties depending on the level of detail you want.
 	 *
 	 * <p>
-	 * Method names are case-insensitive (always folded to upper-case).
+	 * In the example below, our 'summary' view is a list of beans where we only want to show the ID property,
+	 * and our detail view is a single bean where we want to expose different fields:
+	 * <p class='bcode'>
+	 *	<jc>// Our bean</jc>
+	 * 	<jk>public class</jk> MyBean {
+	 *
+	 * 		<jc>// Summary properties</jc>
+	 * 		<ja>@Html</ja>(link=<js>"servlet:/mybeans/{id}"</js>)
+	 * 		<jk>public</jk> String <jf>id</jf>;
+	 *
+	 * 		<jc>// Detail properties</jc>
+	 * 		<jk>public</jk> String <jf>a</jf>, <jf>b</jf>;
+	 * 	}
+	 *
+	 *	<jc>// Only render "id" property.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/mybeans"</js>, bpi=<js>"MyBean: id"</js>)
+	 * 	<jk>public</jk> List&lt;MyBean&gt; getBeanSummary();
+	 *
+	 *	<jc>// Only render "a" and "b" properties.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/mybeans/{id}"</js>, bpi=<js>"MyBean: a,b"</js>)
+	 * 	<jk>public</jk> MyBean getBeanDetails(<ja>@Path</ja> String id);
+	 * </p>
 	 *
 	 * <p>
-	 * Note that you can use {@link org.apache.juneau.http.HttpMethodName} for constant values.
+	 * The format of each value is: <js>"Key: comma-delimited-tokens"</js>.
+	 * <br>Keys can be fully-qualified or short class names or <js>"*"</js> to represent all classes.
+	 * <br>Values are comma-delimited lists of bean property names.
+	 * <br>Properties apply to specified class and all subclasses.
 	 *
 	 * <p>
-	 * Besides the standard HTTP method names, the following can also be specified:
-	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		<js>"*"</js>
-	 * 		- Denotes any method.
-	 * 		<br>Use this if you want to capture any HTTP methods in a single Java method.
-	 * 		<br>The {@link Method @Method} annotation and/or {@link RestRequest#getMethod()} method can be used to
-	 * 		distinguish the actual HTTP method name.
-	 * 	<li>
-	 * 		<js>""</js>
-	 * 		- Auto-detect.
-	 * 		<br>The method name is determined based on the Java method name.
-	 * 		<br>For example, if the method is <code>doPost(...)</code>, then the method name is automatically detected
-	 * 		as <js>"POST"</js>.
-	 * 		<br>Otherwise, defaults to <js>"GET"</js>.
-	 * 	<li>
-	 * 		<js>"PROXY"</js>
-	 * 		- Remote-proxy interface.
-	 * 		<br>This denotes a Java method that returns an object (usually an interface, often annotated with the
-	 * 		{@link Remoteable @Remoteable} annotation) to be used as a remote proxy using
-	 * 		<code>RestClient.getRemoteableProxy(Class&lt;T&gt; interfaceClass, String url)</code>.
-	 * 		<br>This allows you to construct client-side interface proxies using REST as a transport medium.
-	 * 		<br>Conceptually, this is simply a fancy <code>POST</code> against the url <js>"/{path}/{javaMethodName}"</js>
-	 * 		where the arguments are marshalled from the client to the server as an HTTP body containing an array of
-	 * 		objects, passed to the method as arguments, and then the resulting object is marshalled back to the client.
-	 * 	<li>
-	 * 		Anything else
-	 * 		- Overloaded non-HTTP-standard names that are passed in through a <code>&amp;method=methodName</code> URL
-	 * 		parameter.
-	 * </ul>
+	 * Semicolons can be used as an additional separator for multiple values:
+	 * <p class='bcode'>
+	 * 	<jc>// Equivalent</jc>
+	 * 	bpi={<js>"Bean1: foo"</js>,<js>"Bean2: bar,baz"</js>}
+	 * 	bpi=<js>"Bean1: foo; Bean2: bar,baz"</js>
+	 * </p>
 	 */
-	String name() default "";
+	String[] bpi() default {};
 
 	/**
-	 * Optional path pattern for the specified method.
+	 * Shortcut for specifying the {@link BeanContext#BEAN_excludeProperties} property on all serializers.
 	 *
 	 * <p>
-	 * Appending <js>"/*"</js> to the end of the path pattern will make it match any remainder too.
-	 * <br>Not appending <js>"/*"</js> to the end of the pattern will cause a 404 (Not found) error to occur if the exact
-	 * pattern is not found.
+	 * Same as {@link #bpi()} except you specify a list of bean property names that you want to exclude from
+	 * serialization.
 	 *
 	 * <p>
-	 * The path can contain variables that get resolved to {@link Path @Path} parameters:
+	 * In the example below, our 'summary' view is a list of beans where we want to exclude some properties:
 	 * <p class='bcode'>
-	 * 	<jc>// Example 1</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/myurl/{foo}/{bar}/{baz}/*"</js>)
+	 *	<jc>// Our bean</jc>
+	 * 	<jk>public class</jk> MyBean {
 	 *
-	 * 	<jc>// Example 2</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/myurl/{0}/{1}/{2}/*"</js>)
+	 * 		<jc>// Summary properties</jc>
+	 * 		<ja>@Html</ja>(link=<js>"servlet:/mybeans/{id}"</js>)
+	 * 		<jk>public</jk> String <jf>id</jf>;
+	 *
+	 * 		<jc>// Detail properties</jc>
+	 * 		<jk>public</jk> String <jf>a</jf>, <jf>b</jf>;
+	 * 	}
+	 *
+	 *	<jc>// Don't show "a" and "b" properties.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/mybeans"</js>, bpx=<js>"MyBean: a,b"</js>)
+	 * 	<jk>public</jk> List&lt;MyBean&gt; getBeanSummary();
+	 *
+	 *	<jc>// Render all properties.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/mybeans/{id}"</js>)
+	 * 	<jk>public</jk> MyBean getBeanDetails(<ja>@Path</ja> String id);
 	 * </p>
 	 *
 	 * <p>
-	 * Refer to {@link Path @Path} on how path variables get resolved.
+	 * The format of each value is: <js>"Key: comma-delimited-tokens"</js>.
+	 * <br>Keys can be fully-qualified or short class names or <js>"*"</js> to represent all classes.
+	 * <br>Values are comma-delimited lists of bean property names.
+	 * <br>Properties apply to specified class and all subclasses.
+	 *
+	 * <p>
+	 * Semicolons can be used as an additional separator for multiple values:
+	 * <p class='bcode'>
+	 * 	<jc>// Equivalent</jc>
+	 * 	bpx={<js>"Bean1: foo"</js>,<js>"Bean2: bar,baz"</js>}
+	 * 	bpx=<js>"Bean1: foo; Bean2: bar,baz"</js>
+	 * </p>
 	 */
-	String path() default "/*";
+	String[] bpx() default {};
 
 	/**
-	 * URL path pattern priority.
+	 * Specifies whether this method can be called based on the client version.
 	 *
 	 * <p>
-	 * To force path patterns to be checked before other path patterns, use a higher priority number.
+	 * The client version is identified via the HTTP request header identified by
+	 * {@link RestResource#clientVersionHeader()} which by default is <js>"X-Client-Version"</js>.
 	 *
 	 * <p>
-	 * By default, it's <code>0</code>, which means it will use an internal heuristic to determine a best match.
-	 */
-	int priority() default 0;
-
-	/**
-	 * Method-level guards.
+	 * This is a specialized kind of {@link RestMatcher} that allows you to invoke different Java methods for the same
+	 * method/path based on the client version.
 	 *
 	 * <p>
-	 * Associates one or more {@link RestGuard RestGuards} with all REST methods defined in this class.
-	 * These guards get called immediately before execution of any REST method in this class.
+	 * The format of the client version range is similar to that of OSGi versions.
 	 *
 	 * <p>
-	 * Typically, guards will be used for permissions checking on the user making the request, but it can also be used
-	 * for other purposes like pre-call validation of a request.
+	 * In the following example, the Java methods are mapped to the same HTTP method and URL <js>"/foobar"</js>.
+	 * <p class='bcode'>
+	 * 	<jc>// Call this method if X-Client-Version is at least 2.0.
+	 * 	// Note that this also matches 2.0.1.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>)
+	 * 	<jk>public</jk> Object method1() {
+	 * 		...
+	 * 	}
 	 *
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_guards}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#guards()}
-	 * 			<li>{@link RestMethod#guards()}
-	 * 		</ul>
-	 * 	<li>Methods:
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#guards(Class...)}
-	 * 			<li>{@link RestContextBuilder#guards(RestGuard...)}
-	 * 		</ul>
-	 * 	<li>{@link RestGuard} classes must have either a no-arg or {@link PropertyStore} argument constructors.
-	 * 	<li>Values are added AFTER those found in the annotation and therefore take precedence over those defined via the
-	 * 		annotation.
-	 *	</ul>
+	 * 	<jc>// Call this method if X-Client-Version is at least 1.1, but less than 2.0.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>)
+	 * 	<jk>public</jk> Object method2() {
+	 * 		...
+	 * 	}
+	 *
+	 * 	<jc>// Call this method if X-Client-Version is less than 1.1.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[0,1.1)"</js>)
+	 * 	<jk>public</jk> Object method3() {
+	 * 		...
+	 * 	}
+	 * </p>
+	 *
+	 * <p>
+	 * It's common to combine the client version with transforms that will convert new POJOs into older POJOs for
+	 * backwards compatibility.
+	 * <p class='bcode'>
+	 * 	<jc>// Call this method if X-Client-Version is at least 2.0.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>)
+	 * 	<jk>public</jk> NewPojo newMethod() {
+	 * 		...
+	 * 	}
+	 *
+	 * 	<jc>// Call this method if X-Client-Version is at least 1.1, but less than 2.0.</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>, transforms={NewToOldPojoSwap.<jk>class</jk>})
+	 * 	<jk>public</jk> NewPojo oldMethod() {
+	 * 		<jk>return</jk> newMethod()
+	 * 	}
+	 *
+	 * <p>
+	 * Note that in the previous example, we're returning the exact same POJO, but using a transform to convert it into
+	 * an older form.
+	 * The old method could also just return back a completely different object.
+	 * The range can be any of the following:
+	 * <ul>
+	 * 	<li><js>"[0,1.0)"</js> = Less than 1.0.  1.0 and 1.0.0 does not match.
+	 * 	<li><js>"[0,1.0]"</js> = Less than or equal to 1.0.  Note that 1.0.1 will match.
+	 * 	<li><js>"1.0"</js> = At least 1.0.  1.0 and 2.0 will match.
+	 * </ul>
 	 */
-	Class<? extends RestGuard>[] guards() default {};
+	String clientVersion() default "";
 
 	/**
 	 *	Class-level response converters.
 	 *
 	 * <p>
-	 * Associates one or more {@link RestConverter converters} with a resource class.
-	 * These converters get called immediately after execution of the REST method in the same order specified in the
-	 * annotation.
-	 *
+	 * Associates one or more {@link RestConverter converters} with this method.
+	 * 
 	 * <p>
-	 * Can be used for performing post-processing on the response object before serialization.
-	 *
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_converters}
-	 * 	<li>Annotations:  
-	 * 		<ul>
-	 * 			<li>{@link RestResource#converters()}
-	 * 			<li>{@link RestMethod#converters()}
-	 * 		</ul>
-	 * 	<li>Methods: 
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#converters(Class...)}
-	 * 			<li>{@link RestContextBuilder#converters(RestConverter...)}
-	 * 		</ul>
-	 *	</ul>
-	 *
-	 *	<h5 class='section'>Documentation:</h5>
-	 *	<ul>
-	 *		<li><a class="doclink" href="../package-summary.html#RestResources.Converters">Converters</a>
-	 *	</ul>
+	 * See {@link RestContext#REST_converters} for more information.
 	 */
 	Class<? extends RestConverter>[] converters() default {};
 
 	/**
-	 * Method matchers.
+	 * Default character encoding.
+	 * 
+	 * <p>
+	 * The default character encoding for the request and response if not specified on the request.
 	 *
 	 * <p>
-	 * Associates one more more {@link RestMatcher RestMatchers} with this method.
+	 * Value can contain any of the following variables:  
+	 * {@link ConfigFileVar $C} 
+	 * {@link CoalesceVar $CO}
+	 * {@link CoalesceAndRecurseVar $CR}
+	 * {@link EnvVariablesVar $E} 
+	 * {@link IfVar $IF}
+	 * {@link SystemPropertiesVar $S}
+	 * {@link SwitchVar $SW}
+	 * 
+	 * <p>
+	 * See {@link RestContext#REST_defaultCharset} for more information.
+	 */
+	String defaultCharset() default "";
+
+	/**
+	 * Specifies default values for form-data parameters.
 	 *
 	 * <p>
-	 * Matchers are used to allow multiple Java methods to handle requests assigned to the same URL path pattern, but
-	 * differing based on some request attribute, such as a specific header value.
+	 * Strings are of the format <js>"name=value"</js>.
 	 *
 	 * <p>
-	 * See {@link RestMatcher} for details.
+	 * Affects values returned by {@link RestRequest#getFormData(String)} when the parameter is not present on the
+	 * request.
+	 *
+	 * <h5 class='section'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>POST</jsf>, path=<js>"/*"</js>, defaultFormData={<js>"foo=bar"</js>})
+	 * 	<jk>public</jk> String doGet(<ja>@FormData</ja>(<js>"foo"</js>) String foo) {
+	 * 		...
+	 * 	}
+	 * </p>
+	 *
+	 * <p>
+	 * You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
+	 * Key and value is trimmed of whitespace.
+	 * 
+	 * <p>
+	 * Values can contain any of the following variables:  
+	 * {@link ConfigFileVar $C} 
+	 * {@link CoalesceVar $CO}
+	 * {@link CoalesceAndRecurseVar $CR}
+	 * {@link EnvVariablesVar $E} 
+	 * {@link IfVar $IF}
+	 * {@link SystemPropertiesVar $S}
+	 * {@link SwitchVar $SW}
 	 */
-	Class<? extends RestMatcher>[] matchers() default {};
+	String[] defaultFormData() default {};
 
 	/**
-	 * Serializers. 
+	 * Specifies default values for query parameters.
 	 *
 	 * <p>
-	 * Overrides the list of serializers assigned at the method level.
+	 * Strings are of the format <js>"name=value"</js>.
 	 *
 	 * <p>
-	 * Use this annotation when the list of serializers assigned to a method differs from the list of serializers
-	 * assigned at the servlet level.
+	 * Affects values returned by {@link RestRequest#getQuery(String)} when the parameter is not present on the request.
+	 *
+	 * <h5 class='section'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultQuery={<js>"foo=bar"</js>})
+	 * 	<jk>public</jk> String doGet(<ja>@Query</ja>(<js>"foo"</js>) String foo) {
+	 * 		...
+	 * 	}
+	 * </p>
+	 *
+	 * <p>
+	 * You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
+	 * Key and value is trimmed of whitespace.
 	 * 
 	 * <p>
-	 * To append to the list of serializers assigned at the servlet level, use <code>inherit=<js>"SERIALIZERS"</js></code>.
+	 * Values can contain any of the following variables:  
+	 * {@link ConfigFileVar $C} 
+	 * {@link CoalesceVar $CO}
+	 * {@link CoalesceAndRecurseVar $CR}
+	 * {@link EnvVariablesVar $E} 
+	 * {@link IfVar $IF}
+	 * {@link SystemPropertiesVar $S}
+	 * {@link SwitchVar $SW}
+	 */
+	String[] defaultQuery() default {};
+
+	/**
+	 * Default request headers.
+	 * 
+	 * <p>
+	 * Specifies default values for request headers.
 	 *
+	 * <h5 class='section'>Example:</h5>
 	 * <p class='bcode'>
-	 * 	<jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
-	 *
-	 * 		<ja>@RestMethod</ja>(
-	 * 			name=<jsf>GET</jsf>,
-	 * 			path=<js>"/foo"</js>,
-	 * 			serializers=MySpecialSerializer.<jk>class</jk>,
-	 * 			inherit=<js>"SERIALIZERS"</js>
-	 * 		)
-	 * 		<jk>public</jk> Object doGetWithSpecialAcceptType() {
-	 * 			<jc>// Handle request for special Accept type</jc>
-	 * 		}
+	 * 	<jc>// Assume "text/json" Accept value when Accept not specified</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultRequestHeaders={<js>"Accept: text/json"</js>})
+	 * 	<jk>public</jk> String doGet() {
+	 * 		...
 	 * 	}
 	 * </p>
 	 * 
-	 * <h5 class='section'>Notes:</h5>
+	 * <p>
+	 * Values can contain any of the following variables:  
+	 * {@link ConfigFileVar $C} 
+	 * {@link CoalesceVar $CO}
+	 * {@link CoalesceAndRecurseVar $CR}
+	 * {@link EnvVariablesVar $E} 
+	 * {@link IfVar $IF}
+	 * {@link SystemPropertiesVar $S}
+	 * {@link SwitchVar $SW}
+	 * 
+	 * <p>
+	 * See {@link RestContext#REST_defaultRequestHeaders} for more information.
+	 */
+	String[] defaultRequestHeaders() default {};
+
+	/**
+	 * Optional description for the exposed API.
+	 *
+	 * <p>
+	 * This description is used in the following locations:
 	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_serializers}
-	 * 	<li>Annotations: 
-	 * 		<ul>
-	 * 			<li>{@link RestResource#serializers()} 
-	 * 			<li>{@link RestMethod#serializers()} 
-	 * 		</ul>
-	 * 	<li>Methods: 
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#serializers(Object...)}
-	 * 			<li>{@link RestContextBuilder#serializers(Class...)}
-	 * 			<li>{@link RestContextBuilder#serializers(boolean,Object...)}
-	 * 		</ul>
-	 * 	<li>When defined as a class, properties/transforms defined on the resource/method are inherited.
-	 * 	<li>When defined as an instance, properties/transforms defined on the resource/method are NOT inherited.
+	 * 	<li>
+	 * 		The value returned by {@link RestRequest#getMethodDescription()}.
+	 * 	<li>
+	 * 		The <js>"$R{methodDescription}"</js> variable.
+	 * 	<li>
+	 * 		The description of the method in the Swagger page.
 	 * </ul>
 	 *
-	 *	<h5 class='section'>Documentation:</h5>
-	 *	<ul>
-	 *		<li><a class="doclink" href="../package-summary.html#RestResources.Serializers">Serializers</a>
-	 *	</ul>
+	 * <p>
+	 * The default value pulls the description from the <code>(className.?)[javaMethodName].description</code> entry in
+	 * the servlet resource bundle. (e.g. <js>"MyClass.myMethod.description = foo"</js> or
+	 * <js>"myMethod.description = foo"</js>).
+	 *
+	 * <p>
+	 * Value can contain any of the following variables:  
+	 * {@link ConfigFileVar $C} 
+	 * {@link CoalesceVar $CO}
+	 * {@link CoalesceAndRecurseVar $CR}
+	 * {@link EnvVariablesVar $E} 
+	 * {@link FileVar $F} 
+	 * {@link ServletInitParamVar $I},
+	 * {@link IfVar $IF}
+	 * {@link LocalizationVar $L}
+	 * {@link RequestAttributeVar $RA} 
+	 * {@link RequestFormDataVar $RF} 
+	 * {@link RequestHeaderVar $RH} 
+	 * {@link RequestPathVar $RP} 
+	 * {@link RequestQueryVar $RQ} 
+	 * {@link RequestVar $R} 
+	 * {@link SystemPropertiesVar $S}
+	 * {@link SerializedRequestAttrVar $SA}
+	 * {@link SwitchVar $SW}
+	 * {@link UrlVar $U}
+	 * {@link UrlEncodeVar $UE}
+	 * {@link WidgetVar $W}
+	 * 
+	 * <p>
+	 * Corresponds to the swagger field <code>/paths/{path}/{method}/description</code>.
 	 */
-	Class<? extends Serializer>[] serializers() default {};
+	String description() default "";
 
 	/**
-	 * Parsers. 
-	 *
-	 * <p>
-	 * Overrides the list of parsers assigned at the method level.
+	 * Compression encoders. 
 	 *
 	 * <p>
-	 * Use this annotation when the list of parsers assigned to a method differs from the list of parsers assigned at
+	 * Use this annotation when the list of encoders assigned to a method differs from the list of encoders assigned at
 	 * the servlet level.
-	 *
+	 * 
 	 * <p>
-	 * To append to the list of parsers assigned at the servlet level, use
-	 * <code>inherit=<js>"PARSERS"</js></code>.
+	 * These can be used to enable various kinds of compression (e.g. <js>"gzip"</js>) on requests and responses.
+	 * 
+	 * <p>
+	 * Use <code>inherit={<js>"ENCODERS"</js>}</code> to inherit encoders from the resource class.
+	 * 
+	 * <p>
+	 * See {@link RestContext#REST_encoders} for more information.
+	 */
+	Class<? extends Encoder>[] encoders() default {};
+
+	/**
+	 * Shortcut for setting {@link #properties()} of simple boolean types.
 	 *
-	 * <p class='bcode'>
-	 * 	<jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
+	 * <p>
+	 * Setting a flag is equivalent to setting the same property to <js>"true"</js>.
+	 */
+	String[] flags() default {};
+
+	/**
+	 * Method-level guards.
 	 *
-	 * 		<ja>@RestMethod</ja>(
-	 * 			name=<jsf>PUT</jsf>,
-	 * 			path=<js>"/foo"</js>,
-	 * 			parsers=MySpecialParser.<jk>class</jk>,
-	 * 			inherit=<js>"PARSERS"</js>
-	 * 		)
-	 * 		<jk>public</jk> Object doGetWithSpecialAcceptType() {
-	 * 			<jc>// Handle request for special Accept type</jc>
-	 * 		}
-	 * 	}
-	 * </p>
+	 * <p>
+	 * Associates one or more {@link RestGuard RestGuards} with this method.
 	 * 
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_parsers}
-	 * 	<li>Annotations: 
-	 * 		<ul>
-	 * 			<li>{@link RestResource#parsers()} 
-	 * 			<li>{@link RestMethod#parsers()} 
-	 * 		</ul>
-	 * 	<li>Methods: 
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#parsers(Object...)}
-	 * 			<li>{@link RestContextBuilder#parsers(Class...)}
-	 * 			<li>{@link RestContextBuilder#parsers(boolean,Object...)}
-	 * 		</ul>
-	 * 	<li>When defined as a class, properties/transforms defined on the resource/method are inherited.
-	 * 	<li>When defined as an instance, properties/transforms defined on the resource/method are NOT inherited.
-	 * 	<li>Values are added AFTER those found in the annotation and therefore take precedence over those defined via the
-	 * 		annotation.
-	 * </ul>
+	 * <p>
+	 * See {@link RestContext#REST_guards} for more information.
+	 */
+	Class<? extends RestGuard>[] guards() default {};
+
+	/**
+	 * Provides HTML-doc-specific metadata on this method.
 	 *
-	 *	<h5 class='section'>Documentation:</h5>
-	 *	<ul>
-	 *		<li><a class="doclink" href="../package-summary.html#RestResources.Parsers">Parsers</a>
-	 *	</ul>
+	 * <p>
+	 * Information provided here overrides information provided in the servlet-level annotation.
 	 */
-	Class<? extends Parser>[] parsers() default {};
+	HtmlDoc htmldoc() default @HtmlDoc;
 
 	/**
 	 * Identifies what class-level properties are inherited by the serializers and parsers defined on the method.
@@ -331,340 +453,212 @@ public @interface RestMethod {
 	String inherit() default "";
 	
 	/**
-	 * Supported accept media types.
-	 *
-	 * <p>
-	 * Overrides the media types inferred from the serializers that identify what media types can be produced by the resource.
-	 * 
-	 * <p>
-	 * This affects the values returned by {@link RestRequest#getSupportedAcceptTypes()} and the supported accept
-	 * types shown in {@link RestInfoProvider#getSwagger(RestRequest)}.
+	 * Method matchers.
 	 *
 	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_supportedAcceptTypes}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#supportedAcceptTypes()}
-	 * 			<li>{@link RestMethod#supportedAcceptTypes()}
-	 * 		</ul> 
-	 * 	<li>Methods:  
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#supportedAcceptTypes(boolean,String...)}
-	 * 			<li>{@link RestContextBuilder#supportedAcceptTypes(boolean,MediaType...)}
-	 * 		</ul>
-	 *	</ul>
-	 */
-	String[] supportedAcceptTypes() default {};
-	
-	/**
-	 * Supported content media types.
+	 * Associates one more more {@link RestMatcher RestMatchers} with this method.
 	 *
 	 * <p>
-	 * Overrides the media types inferred from the parsers that identify what media types can be consumed by the resource.
+	 * Matchers are used to allow multiple Java methods to handle requests assigned to the same URL path pattern, but
+	 * differing based on some request attribute, such as a specific header value.
 	 *
 	 * <p>
-	 * This affects the values returned by {@link RestRequest#getSupportedContentTypes()} and the supported content
-	 * types shown in {@link RestInfoProvider#getSwagger(RestRequest)}.
-	 * 
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_supportedContentTypes}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#supportedContentTypes()}
-	 * 			<li>{@link RestMethod#supportedContentTypes()}
-	 * 		</ul> 
-	 * 	<li>Methods:  
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#supportedContentTypes(boolean,String...)}
-	 * 			<li>{@link RestContextBuilder#supportedContentTypes(boolean,MediaType...)}
-	 * 		</ul>
-	 *	</ul>
+	 * See {@link RestMatcher} for more information.
 	 */
-	String[] supportedContentTypes() default {};
+	Class<? extends RestMatcher>[] matchers() default {};
 
 	/**
-	 * Compression encoders. 
+	 * The maximum allowed input size (in bytes) on HTTP requests.
 	 *
 	 * <p>
-	 * Use this annotation when the list of encoders assigned to a method differs from the list of encoders assigned at
-	 * the servlet level.
+	 * Useful for alleviating DoS attacks by throwing an exception when too much input is received instead of resulting
+	 * in out-of-memory errors which could affect system stability.
 	 * 
-	 * <p>
-	 * These can be used to enable various kinds of compression (e.g. <js>"gzip"</js>) on requests and responses.
-	 *
 	 * <h5 class='section'>Example:</h5>
 	 * <p class='bcode'>
-	 * 	<jc>// Servlet with automated support for GZIP compression</jc>
-	 * 	<ja>@RestResource</ja>(encoders={GzipEncoder.<jk>class</jk>})
-	 * 	<jk>public</jk> MyRestServlet <jk>extends</jk> RestServlet {
-	 * 		...
-	 * 	}
+	 * 	<ja>@RestMethod</ja>(
+	 * 		maxInput=<js>"100M"</js>
+	 * 	)
 	 * </p>
 	 * 
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_encoders}
-	 * 	<li>Annotations: 
-	 * 		<ul>
-	 * 			<li>{@link RestResource#encoders()} 
-	 * 			<li>{@link RestMethod#encoders()} 
-	 * 		</ul>
-	 * 	<li>Methods: 
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#encoders(Class...)}
-	 * 			<li>{@link RestContextBuilder#encoders(Encoder...)}
-	 * 		</ul>
-	 * 	<li>Instance classes must provide a public no-arg constructor, or a public constructor that takes in a
-	 * 		{@link PropertyStore} object.
-	 * 	<li>Instance class can be defined as an inner class of the REST resource class.
-	 * 	<li>Use <code>inherit={<js>"ENCODERS"</js>}</code> to inherit encoders from the resource class.
-	 * </ul>
+	 * <p>
+	 * Value can contain any of the following variables:  
+	 * {@link ConfigFileVar $C} 
+	 * {@link CoalesceVar $CO}
+	 * {@link CoalesceAndRecurseVar $CR}
+	 * {@link EnvVariablesVar $E} 
+	 * {@link IfVar $IF}
+	 * {@link SystemPropertiesVar $S}
+	 * {@link SwitchVar $SW}
+	 * 
+	 * <p>
+	 * See {@link RestContext#REST_maxInput} for more information.
 	 */
-	Class<? extends Encoder>[] encoders() default {};
+	String maxInput() default "";
 
 	/**
-	 * Same as {@link RestResource#properties()}, except defines property values by default when this method is called.
+	 * REST method name.
 	 *
 	 * <p>
-	 * This is equivalent to simply calling <code>res.addProperties()</code> in the Java method, but is provided for
-	 * convenience.
-	 */
-	Property[] properties() default {};
-
-	/**
-	 * Shortcut for setting {@link #properties()} of simple boolean types.
+	 * Typically <js>"GET"</js>, <js>"PUT"</js>, <js>"POST"</js>, <js>"DELETE"</js>, or <js>"OPTIONS"</js>.
 	 *
 	 * <p>
-	 * Setting a flag is equivalent to setting the same property to <js>"true"</js>.
-	 */
-	String[] flags() default {};
-
-	/**
-	 * Appends the specified bean filters to all serializers and parsers used by this method.
+	 * Method names are case-insensitive (always folded to upper-case).
 	 *
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link BeanContext#BEAN_beanFilters}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#beanFilters()}
-	 * 			<li>{@link RestMethod#beanFilters()}
-	 * 		</ul>
-	 * 	<li>Methods:
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#beanFilters(Object...)}
-	 * 			<li>{@link RestContextBuilder#beanFilters(boolean, Object...)}
-	 * 			<li>{@link RestContextBuilder#beanFiltersRemove(Object...)}
-	 * 		</ul>
-	 *	</ul>
-	 */
-	Class<?>[] beanFilters() default {};
-
-	/**
-	 * Appends the specified POJO swaps to all serializers and parsers used by this method.
+	 * <p>
+	 * Note that you can use {@link org.apache.juneau.http.HttpMethodName} for constant values.
 	 *
-	 * <h5 class='section'>Notes:</h5>
+	 * <p>
+	 * Besides the standard HTTP method names, the following can also be specified:
 	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link BeanContext#BEAN_pojoSwaps}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#pojoSwaps()}
-	 * 			<li>{@link RestMethod#pojoSwaps()}
-	 * 		</ul>
-	 * 	<li>Methods:
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#pojoSwaps(Object...)}
-	 * 			<li>{@link RestContextBuilder#pojoSwaps(Class...)}
-	 * 			<li>{@link RestContextBuilder#pojoSwaps(boolean, Object...)}
-	 * 			<li>{@link RestContextBuilder#pojoSwapsRemove(Object...)}
-	 * 		</ul>
-	 *	</ul>
+	 * 	<li>
+	 * 		<js>"*"</js>
+	 * 		- Denotes any method.
+	 * 		<br>Use this if you want to capture any HTTP methods in a single Java method.
+	 * 		<br>The {@link Method @Method} annotation and/or {@link RestRequest#getMethod()} method can be used to
+	 * 		distinguish the actual HTTP method name.
+	 * 	<li>
+	 * 		<js>""</js>
+	 * 		- Auto-detect.
+	 * 		<br>The method name is determined based on the Java method name.
+	 * 		<br>For example, if the method is <code>doPost(...)</code>, then the method name is automatically detected
+	 * 		as <js>"POST"</js>.
+	 * 		<br>Otherwise, defaults to <js>"GET"</js>.
+	 * 	<li>
+	 * 		<js>"PROXY"</js>
+	 * 		- Remote-proxy interface.
+	 * 		<br>This denotes a Java method that returns an object (usually an interface, often annotated with the
+	 * 		{@link Remoteable @Remoteable} annotation) to be used as a remote proxy using
+	 * 		<code>RestClient.getRemoteableProxy(Class&lt;T&gt; interfaceClass, String url)</code>.
+	 * 		<br>This allows you to construct client-side interface proxies using REST as a transport medium.
+	 * 		<br>Conceptually, this is simply a fancy <code>POST</code> against the url <js>"/{path}/{javaMethodName}"</js>
+	 * 		where the arguments are marshalled from the client to the server as an HTTP body containing an array of
+	 * 		objects, passed to the method as arguments, and then the resulting object is marshalled back to the client.
+	 * 	<li>
+	 * 		Anything else
+	 * 		- Overloaded non-HTTP-standard names that are passed in through a <code>&amp;method=methodName</code> URL
+	 * 		parameter.
+	 * </ul>
 	 */
-	Class<?>[] pojoSwaps() default {};
+	String name() default "";
 
 	/**
-	 * Shortcut for specifying the {@link BeanContext#BEAN_includeProperties} property on all serializers.
+	 * Parsers. 
 	 *
 	 * <p>
-	 * The typical use case is when you're rendering summary and details views of the same bean in a resource and
-	 * you want to expose or hide specific properties depending on the level of detail you want.
+	 * Overrides the list of parsers assigned at the method level.
 	 *
 	 * <p>
-	 * In the example below, our 'summary' view is a list of beans where we only want to show the ID property,
-	 * and our detail view is a single bean where we want to expose different fields:
-	 * <p class='bcode'>
-	 *	<jc>// Our bean</jc>
-	 * 	<jk>public class</jk> MyBean {
-	 *
-	 * 		<jc>// Summary properties</jc>
-	 * 		<ja>@Html</ja>(link=<js>"servlet:/mybeans/{id}"</js>)
-	 * 		<jk>public</jk> String <jf>id</jf>;
-	 *
-	 * 		<jc>// Detail properties</jc>
-	 * 		<jk>public</jk> String <jf>a</jf>, <jf>b</jf>;
-	 * 	}
-	 *
-	 *	<jc>// Only render "id" property.</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/mybeans"</js>, bpi=<js>"MyBean: id"</js>)
-	 * 	<jk>public</jk> List&lt;MyBean&gt; getBeanSummary();
-	 *
-	 *	<jc>// Only render "a" and "b" properties.</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/mybeans/{id}"</js>, bpi=<js>"MyBean: a,b"</js>)
-	 * 	<jk>public</jk> MyBean getBeanDetails(<ja>@Path</ja> String id);
-	 * </p>
+	 * Use this annotation when the list of parsers assigned to a method differs from the list of parsers assigned at
+	 * the servlet level.
 	 *
 	 * <p>
-	 * The format of each value is: <js>"Key: comma-delimited-tokens"</js>.
-	 * <br>Keys can be fully-qualified or short class names or <js>"*"</js> to represent all classes.
-	 * <br>Values are comma-delimited lists of bean property names.
-	 * <br>Properties apply to specified class and all subclasses.
+	 * To append to the list of parsers assigned at the servlet level, use <code>inherit=<js>"PARSERS"</js></code>.
 	 *
-	 * <p>
-	 * Semicolons can be used as an additional separator for multiple values:
 	 * <p class='bcode'>
-	 * 	<jc>// Equivalent</jc>
-	 * 	bpi={<js>"Bean1: foo"</js>,<js>"Bean2: bar,baz"</js>}
-	 * 	bpi=<js>"Bean1: foo; Bean2: bar,baz"</js>
+	 * 	<jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
+	 *
+	 * 		<ja>@RestMethod</ja>(
+	 * 			name=<jsf>PUT</jsf>,
+	 * 			path=<js>"/foo"</js>,
+	 * 			parsers=MySpecialParser.<jk>class</jk>,
+	 * 			inherit=<js>"PARSERS"</js>
+	 * 		)
+	 * 		<jk>public</jk> Object doGetWithSpecialAcceptType() {
+	 * 			<jc>// Handle request for special Accept type</jc>
+	 * 		}
+	 * 	}
 	 * </p>
+	 * 
+	 * <p>
+	 * See {@link RestContext#REST_parsers} for more information.
 	 */
-	String[] bpi() default {};
+	Class<? extends Parser>[] parsers() default {};
 
 	/**
-	 * Shortcut for specifying the {@link BeanContext#BEAN_excludeProperties} property on all serializers.
+	 * Optional path pattern for the specified method.
 	 *
 	 * <p>
-	 * Same as {@link #bpi()} except you specify a list of bean property names that you want to exclude from
-	 * serialization.
+	 * Appending <js>"/*"</js> to the end of the path pattern will make it match any remainder too.
+	 * <br>Not appending <js>"/*"</js> to the end of the pattern will cause a 404 (Not found) error to occur if the exact
+	 * pattern is not found.
 	 *
 	 * <p>
-	 * In the example below, our 'summary' view is a list of beans where we want to exclude some properties:
+	 * The path can contain variables that get resolved to {@link Path @Path} parameters:
 	 * <p class='bcode'>
-	 *	<jc>// Our bean</jc>
-	 * 	<jk>public class</jk> MyBean {
-	 *
-	 * 		<jc>// Summary properties</jc>
-	 * 		<ja>@Html</ja>(link=<js>"servlet:/mybeans/{id}"</js>)
-	 * 		<jk>public</jk> String <jf>id</jf>;
-	 *
-	 * 		<jc>// Detail properties</jc>
-	 * 		<jk>public</jk> String <jf>a</jf>, <jf>b</jf>;
-	 * 	}
-	 *
-	 *	<jc>// Don't show "a" and "b" properties.</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/mybeans"</js>, bpx=<js>"MyBean: a,b"</js>)
-	 * 	<jk>public</jk> List&lt;MyBean&gt; getBeanSummary();
+	 * 	<jc>// Example 1</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/myurl/{foo}/{bar}/{baz}/*"</js>)
 	 *
-	 *	<jc>// Render all properties.</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/mybeans/{id}"</js>)
-	 * 	<jk>public</jk> MyBean getBeanDetails(<ja>@Path</ja> String id);
+	 * 	<jc>// Example 2</jc>
+	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/myurl/{0}/{1}/{2}/*"</js>)
 	 * </p>
 	 *
 	 * <p>
-	 * The format of each value is: <js>"Key: comma-delimited-tokens"</js>.
-	 * <br>Keys can be fully-qualified or short class names or <js>"*"</js> to represent all classes.
-	 * <br>Values are comma-delimited lists of bean property names.
-	 * <br>Properties apply to specified class and all subclasses.
-	 *
-	 * <p>
-	 * Semicolons can be used as an additional separator for multiple values:
-	 * <p class='bcode'>
-	 * 	<jc>// Equivalent</jc>
-	 * 	bpx={<js>"Bean1: foo"</js>,<js>"Bean2: bar,baz"</js>}
-	 * 	bpx=<js>"Bean1: foo; Bean2: bar,baz"</js>
-	 * </p>
+	 * Refer to {@link Path @Path} on how path variables get resolved.
 	 */
-	String[] bpx() default {};
+	String path() default "/*";
 
 	/**
-	 * Default request headers.
-	 * 
-	 * <p>
-	 * Specifies default values for request headers.
+	 * Appends the specified POJO swaps to all serializers and parsers used by this method.
 	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<jc>// Assume "text/json" Accept value when Accept not specified</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultRequestHeaders={<js>"Accept: text/json"</js>})
-	 * 	<jk>public</jk> String doGet() {
-	 * 		...
-	 * 	}
-	 * </p>
-	 * 
 	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_defaultRequestHeaders}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#defaultRequestHeaders()}
-	 * 			<li>{@link RestMethod#defaultRequestHeaders()} 
-	 * 		</ul>
-	 * 	<li>Methods:
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#defaultRequestHeader(String,Object)}
-	 * 			<li>{@link RestContextBuilder#defaultRequestHeaders(String...)}
-	 * 		</ul>
-	 * 	<li>Strings are of the format <js>"Header-Name: header-value"</js>.
-	 * 	<li>You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
-	 * 	<li>Key and value is trimmed of whitespace.
-	 * 	<li>Only one header value can be specified per entry (i.e. it's not a delimited list of header entries).
-	 * 	<li>Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request.
-	 * 	<li>The most useful reason for this annotation is to provide a default <code>Accept</code> header when one is not
-	 * 		specified so that a particular default {@link Serializer} is picked.
-	 *	</ul>
+	 * See {@link BeanContext#BEAN_pojoSwaps} for more information.
 	 */
-	String[] defaultRequestHeaders() default {};
+	Class<?>[] pojoSwaps() default {};
 
 	/**
-	 * Specifies default values for query parameters.
+	 * URL path pattern priority.
 	 *
 	 * <p>
-	 * Strings are of the format <js>"name=value"</js>.
+	 * To force path patterns to be checked before other path patterns, use a higher priority number.
 	 *
 	 * <p>
-	 * Affects values returned by {@link RestRequest#getQuery(String)} when the parameter is not present on the request.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultQuery={<js>"foo=bar"</js>})
-	 * 	<jk>public</jk> String doGet(<ja>@Query</ja>(<js>"foo"</js>) String foo) {
-	 * 		...
-	 * 	}
-	 * </p>
+	 * By default, it's <code>0</code>, which means it will use an internal heuristic to determine a best match.
+	 */
+	int priority() default 0;
+
+	/**
+	 * Same as {@link RestResource#properties()}, except defines property values by default when this method is called.
 	 *
 	 * <p>
-	 * You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
-	 * Key and value is trimmed of whitespace.
+	 * This is equivalent to simply calling <code>res.addProperties()</code> in the Java method, but is provided for
+	 * convenience.
 	 */
-	String[] defaultQuery() default {};
+	Property[] properties() default {};
 
 	/**
-	 * Specifies default values for form-data parameters.
+	 * Serializers. 
 	 *
 	 * <p>
-	 * Strings are of the format <js>"name=value"</js>.
+	 * Overrides the list of serializers assigned at the method level.
 	 *
 	 * <p>
-	 * Affects values returned by {@link RestRequest#getFormData(String)} when the parameter is not present on the
-	 * request.
+	 * Use this annotation when the list of serializers assigned to a method differs from the list of serializers
+	 * assigned at the servlet level.
+	 * 
+	 * <p>
+	 * To append to the list of serializers assigned at the servlet level, use <code>inherit=<js>"SERIALIZERS"</js></code>.
 	 *
 	 * <h5 class='section'>Example:</h5>
 	 * <p class='bcode'>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>POST</jsf>, path=<js>"/*"</js>, defaultFormData={<js>"foo=bar"</js>})
-	 * 	<jk>public</jk> String doGet(<ja>@FormData</ja>(<js>"foo"</js>) String foo) {
-	 * 		...
+	 * 	<jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
+	 *
+	 * 		<ja>@RestMethod</ja>(
+	 * 			name=<jsf>GET</jsf>,
+	 * 			path=<js>"/foo"</js>,
+	 * 			serializers=MySpecialSerializer.<jk>class</jk>,
+	 * 			inherit=<js>"SERIALIZERS"</js>
+	 * 		)
+	 * 		<jk>public</jk> Object doGetWithSpecialAcceptType() {
+	 * 			<jc>// Handle request for special Accept type</jc>
+	 * 		}
 	 * 	}
 	 * </p>
-	 *
+	 * 
 	 * <p>
-	 * You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
-	 * Key and value is trimmed of whitespace.
+	 * See {@link RestContext#REST_serializers} for more information.
 	 */
-	String[] defaultFormData() default {};
+	Class<? extends Serializer>[] serializers() default {};
 
 	/**
 	 * Optional summary for the exposed API.
@@ -685,8 +679,27 @@ public @interface RestMethod {
 	 * servlet resource bundle. (e.g. <js>"MyClass.myMethod.summary = foo"</js> or <js>"myMethod.summary = foo"</js>).
 	 *
 	 * <p>
-	 * This field can contain variables (e.g. <js>"$L{my.localized.variable}"</js>).
-	 * <br>See {@link RestContext#getVarResolver()} for the list of supported variables.
+	 * Value can contain any of the following variables:  
+	 * {@link ConfigFileVar $C} 
+	 * {@link CoalesceVar $CO}
+	 * {@link CoalesceAndRecurseVar $CR}
+	 * {@link EnvVariablesVar $E} 
+	 * {@link FileVar $F} 
+	 * {@link ServletInitParamVar $I},
+	 * {@link IfVar $IF}
+	 * {@link LocalizationVar $L}
+	 * {@link RequestAttributeVar $RA} 
+	 * {@link RequestFormDataVar $RF} 
+	 * {@link RequestHeaderVar $RH} 
+	 * {@link RequestPathVar $RP} 
+	 * {@link RequestQueryVar $RQ} 
+	 * {@link RequestVar $R} 
+	 * {@link SystemPropertiesVar $S}
+	 * {@link SerializedRequestAttrVar $SA}
+	 * {@link SwitchVar $SW}
+	 * {@link UrlVar $U}
+	 * {@link UrlEncodeVar $UE}
+	 * {@link WidgetVar $W}
 	 *
 	 * <p>
 	 * Corresponds to the swagger field <code>/paths/{path}/{method}/summary</code>.
@@ -694,167 +707,49 @@ public @interface RestMethod {
 	String summary() default "";
 
 	/**
-	 * Optional description for the exposed API.
-	 *
-	 * <p>
-	 * This description is used in the following locations:
-	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		The value returned by {@link RestRequest#getMethodDescription()}.
-	 * 	<li>
-	 * 		The <js>"$R{methodDescription}"</js> variable.
-	 * 	<li>
-	 * 		The description of the method in the Swagger page.
-	 * </ul>
+	 * Supported accept media types.
 	 *
 	 * <p>
-	 * The default value pulls the description from the <code>(className.?)[javaMethodName].description</code> entry in
-	 * the servlet resource bundle. (e.g. <js>"MyClass.myMethod.description = foo"</js> or
-	 * <js>"myMethod.description = foo"</js>).
-	 *
+	 * Overrides the media types inferred from the serializers that identify what media types can be produced by the resource.
+	 * 
 	 * <p>
-	 * This field can contain variables (e.g. <js>"$L{my.localized.variable}"</js>).
-	 * <br>See {@link RestContext#getVarResolver()} for the list of supported variables.
-	 *
+	 * Values can contain any of the following variables:  
+	 * {@link ConfigFileVar $C} 
+	 * {@link CoalesceVar $CO}
+	 * {@link CoalesceAndRecurseVar $CR}
+	 * {@link EnvVariablesVar $E} 
+	 * {@link IfVar $IF}
+	 * {@link SystemPropertiesVar $S}
+	 * {@link SwitchVar $SW}
+	 * 
 	 * <p>
-	 * Corresponds to the swagger field <code>/paths/{path}/{method}/description</code>.
+	 * See {@link RestContext#REST_supportedAcceptTypes} for more information.
 	 */
-	String description() default "";
-
+	String[] supportedAcceptTypes() default {};
+	
 	/**
-	 * Specifies whether this method can be called based on the client version.
-	 *
-	 * <p>
-	 * The client version is identified via the HTTP request header identified by
-	 * {@link RestResource#clientVersionHeader()} which by default is <js>"X-Client-Version"</js>.
-	 *
-	 * <p>
-	 * This is a specialized kind of {@link RestMatcher} that allows you to invoke different Java methods for the same
-	 * method/path based on the client version.
-	 *
-	 * <p>
-	 * The format of the client version range is similar to that of OSGi versions.
+	 * Supported content media types.
 	 *
 	 * <p>
-	 * In the following example, the Java methods are mapped to the same HTTP method and URL <js>"/foobar"</js>.
-	 * <p class='bcode'>
-	 * 	<jc>// Call this method if X-Client-Version is at least 2.0.
-	 * 	// Note that this also matches 2.0.1.</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>)
-	 * 	<jk>public</jk> Object method1() {
-	 * 		...
-	 * 	}
-	 *
-	 * 	<jc>// Call this method if X-Client-Version is at least 1.1, but less than 2.0.</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>)
-	 * 	<jk>public</jk> Object method2() {
-	 * 		...
-	 * 	}
-	 *
-	 * 	<jc>// Call this method if X-Client-Version is less than 1.1.</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[0,1.1)"</js>)
-	 * 	<jk>public</jk> Object method3() {
-	 * 		...
-	 * 	}
-	 * </p>
-	 *
+	 * Overrides the media types inferred from the parsers that identify what media types can be consumed by the resource.
+	 * 
 	 * <p>
-	 * It's common to combine the client version with transforms that will convert new POJOs into older POJOs for
-	 * backwards compatibility.
-	 * <p class='bcode'>
-	 * 	<jc>// Call this method if X-Client-Version is at least 2.0.</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>)
-	 * 	<jk>public</jk> NewPojo newMethod() {
-	 * 		...
-	 * 	}
-	 *
-	 * 	<jc>// Call this method if X-Client-Version is at least 1.1, but less than 2.0.</jc>
-	 * 	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>, transforms={NewToOldPojoSwap.<jk>class</jk>})
-	 * 	<jk>public</jk> NewPojo oldMethod() {
-	 * 		<jk>return</jk> newMethod()
-	 * 	}
-	 *
+	 * Values can contain any of the following variables:  
+	 * {@link ConfigFileVar $C} 
+	 * {@link CoalesceVar $CO}
+	 * {@link CoalesceAndRecurseVar $CR}
+	 * {@link EnvVariablesVar $E} 
+	 * {@link IfVar $IF}
+	 * {@link SystemPropertiesVar $S}
+	 * {@link SwitchVar $SW}
+	 * 
 	 * <p>
-	 * Note that in the previous example, we're returning the exact same POJO, but using a transform to convert it into
-	 * an older form.
-	 * The old method could also just return back a completely different object.
-	 * The range can be any of the following:
-	 * <ul>
-	 * 	<li><js>"[0,1.0)"</js> = Less than 1.0.  1.0 and 1.0.0 does not match.
-	 * 	<li><js>"[0,1.0]"</js> = Less than or equal to 1.0.  Note that 1.0.1 will match.
-	 * 	<li><js>"1.0"</js> = At least 1.0.  1.0 and 2.0 will match.
-	 * </ul>
+	 * See {@link RestContext#REST_supportedContentTypes} for more information.
 	 */
-	String clientVersion() default "";
+	String[] supportedContentTypes() default {};
 
 	/**
 	 * Provides swagger-specific metadata on this method.
 	 */
 	MethodSwagger swagger() default @MethodSwagger;
-
-	/**
-	 * Provides HTML-doc-specific metadata on this method.
-	 *
-	 * <p>
-	 * Information provided here overrides information provided in the servlet-level annotation.
-	 */
-	HtmlDoc htmldoc() default @HtmlDoc;
-
-	/**
-	 * Default character encoding.
-	 * 
-	 * <p>
-	 * The default character encoding for the request and response if not specified on the request.
-	 *
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_defaultCharset}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#defaultCharset()}
-	 * 			<li>{@link RestMethod#defaultCharset()}
-	 * 		</ul>
-	 * 	<li>Methods:
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#defaultCharset(String)}
-	 * 		</ul>
-	 * 	<li>String value.
-	 * 	<li>Can contain variables.
-	 *	</ul>
-	 */
-	String defaultCharset() default "";
-	/**
-	 * The maximum allowed input size (in bytes) on HTTP requests.
-	 *
-	 * <p>
-	 * Useful for alleviating DoS attacks by throwing an exception when too much input is received instead of resulting
-	 * in out-of-memory errors which could affect system stability.
-	 * 
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<ja>@RestMethod</ja>(
-	 * 		maxInput=<js>"100M"</js>
-	 * 	)
-	 * </p>
-	 * 
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_maxInput}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#maxInput()}
-	 * 			<li>{@link RestMethod#maxInput()}
-	 * 		</ul>
-	 * 	<li>Methods:
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#maxInput(String)}
-	 * 		</ul>
-	 * 	<li>String value that gets resolved to a <jk>long</jk>.
-	 * 	<li>Can contain variables.
-	 * 	<li>Can be suffixed with any of the following representing kilobytes, megabytes, and gigabytes:  
-	 * 		<js>'K'</js>, <js>'M'</js>, <js>'G'</js>.
-	 * 	<li>A value of <js>"-1"</js> can be used to represent no limit.
-	 *	</ul>
-	 */
-	String maxInput() default "";
 }