Code cleanup. Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/98a53eb3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/98a53eb3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/98a53eb3
Branch: refs/heads/master Commit: 98a53eb3143d1420464b25a5f8289f4dc1a0c495 Parents: 80e8061 Author: JamesBognar <[email protected]> Authored: Thu May 11 17:17:01 2017 -0400 Committer: JamesBognar <[email protected]> Committed: Thu May 11 17:17:01 2017 -0400 ---------------------------------------------------------------------- juneau-core/src/main/javadoc/overview.html | 229 ++++++++++--------- .../src/main/javadoc/resources/juneau-doc.css | 1 + .../examples/rest/MethodExampleResource.java | 122 +++++++--- .../rest/addressbook/AddressBookResource.java | 16 +- .../org/apache/juneau/microservice/package.html | 8 +- .../juneau/rest/test/OnPostCallResource.java | 4 +- .../juneau/rest/test/OnPreCallResource.java | 2 +- .../rest/test/OverlappingMethodsResource.java | 8 +- .../apache/juneau/rest/test/ParamsResource.java | 24 +- .../apache/juneau/rest/test/PathsResource.java | 4 +- .../apache/juneau/rest/test/UrisResource.java | 2 +- .../java/org/apache/juneau/rest/CallMethod.java | 15 +- .../org/apache/juneau/rest/RequestBody.java | 34 +-- .../apache/juneau/rest/RequestPathMatch.java | 213 +++++++++++++++++ .../apache/juneau/rest/RequestPathParams.java | 137 ----------- .../apache/juneau/rest/RestParamDefaults.java | 12 +- .../org/apache/juneau/rest/RestRequest.java | 185 ++------------- .../org/apache/juneau/rest/annotation/Body.java | 2 +- .../juneau/rest/converters/Introspectable.java | 4 +- .../juneau/rest/converters/Traversable.java | 4 +- .../java/org/apache/juneau/rest/package.html | 26 +-- .../juneau/rest/response/DefaultHandler.java | 4 +- .../org/apache/juneau/rest/vars/RequestVar.java | 8 +- 23 files changed, 525 insertions(+), 539 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/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 3f5683f..f0bd247 100644 --- a/juneau-core/src/main/javadoc/overview.html +++ b/juneau-core/src/main/javadoc/overview.html @@ -3026,106 +3026,123 @@ <jd>/** Example GET request that redirects to our example method */</jd> <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/"</js>) - <jk>public</jk> Redirect doGetExample() <jk>throws</jk> Exception { - <jk>return new</jk> Redirect(<js>"example1/xxx/123/{0}/xRemainder?p1=123&p2=yyy"</js>, UUID.<jsm>randomUUID</jsm>()); + <jk>public</jk> Redirect doExample() <jk>throws</jk> Exception { + <jk>return new</jk> Redirect(<js>"example1/xxx/123/{0}/xRemainder?q1=123&q2=yyy"</js>, UUID.<jsm>randomUUID</jsm>()); } - <jd>/** Example GET request using annotated attributes */</jd> - <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/example1/{a1}/{a2}/{a3}/*"</js>, rc={200}) - <jk>public</jk> String doGetExample1( - <ja>@Method</ja> String method, - <ja>@Path</ja> String a1, - <ja>@Path</ja> <jk>int</jk> a2, - <ja>@Path</ja> UUID a3, - <ja>@Query</ja>(<js>"p1"</js>) <jk>int</jk> p1, - <ja>@Query</ja>(<js>"p2"</js>) String p2, - <ja>@Query</ja>(<js>"p3"</js>) UUID p3, - <ja>@PathRemainder</ja> String remainder, - <ja>@Header</ja>(<js>"Accept-Language"</js>) String lang, - <ja>@Header</ja>(<js>"Accept"</js>) String accept, - <ja>@Header</ja>(<js>"DNT"</js>) <jk>int</jk> doNotTrack - ) { - String output = String.format( - <js>"method=%s, a1=%s, a2=%d, a3=%s, remainder=%s, p1=%d, p2=%s, p3=%s, lang=%s, accept=%s, dnt=%d"</js>, - method, a1, a2, a3, remainder, p1, p2, p3, lang, accept, doNotTrack); - <jk>return</jk> output; - } - - <jd>/** Example GET request using methods on RestRequest and RestResponse */</jd> - <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/example2/{a1}/{a2}/{a3}/*"</js>, rc={200}) - <jk>public void</jk> doGetExample2(RestRequest req, RestResponse res) <jk>throws</jk> Exception { - String method = req.getMethod(); - - <jc>// Attributes (from URL pattern variables)</jc> - RequestPathParams path = req.getPathParams(); - String a1 = path.get(<js>"a1"</js>, String.<jk>class</jk>); - <jk>int</jk> a2 = path.get(<js>"a2"</js>, <jk>int</jk>.<jk>class</jk>); - UUID a3 = path.get(<js>"a3"</js>, UUID.<jk>class</jk>); + <jd>/** + * Methodology #1 - GET request using annotated attributes. + * This approach uses annotated parameters for retrieving input. + */</jd> + <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/example1/{p1}/{p2}/{p3}/*"</js>) + <jk>public</jk> String example1( + <ja>@Method</ja> String method, <jc>// HTTP method.</jc> + <ja>@Path</ja> String p1, <jc>// Path variables.</jc> + <ja>@Path</ja> <jk>int</jk> p2, + <ja>@Path</ja> UUID p3, + <ja>@Query</ja>(<js>"q1"</js>) <jk>int</jk> q1, <jc>// Query parameters.</jc> + <ja>@Query</ja>(<js>"q2"</js>) String q2, + <ja>@Query</ja>(<js>"q3"</js>) UUID q3, + <ja>@PathRemainder</ja> String remainder, <jc>// Path remainder after pattern match.</jc> + <ja>@Header</ja>(<js>"Accept-Language"</js>) String lang, <jc>// Headers.</jc> + <ja>@Header</ja>(<js>"Accept"</js>) String accept, + <ja>@Header</ja>(<js>"DNT"</js>) <jk>int</jk> doNotTrack + ) { + + <jc>// Send back a simple String response</jc> + String output = String.<jsm>format</jsm>( + <js>"method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s, accept=%s, dnt=%d"</js>, + method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack); + <jk>return</jk> output; + } + + <jd>/** + * Methodology #2 - GET request using methods on RestRequest and RestResponse. + * This approach uses low-level request/response objects to perform the same as above. + */</jd> + <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/example2/{p1}/{p2}/{p3}/*"</js>) + <jk>public</jk> String example2( + RestRequest req, <jc>// A direct subclass of HttpServletRequest.</jc> + RestResponse res <jc>// A direct subclass of HttpServletResponse.</jc> + ) { - <jc>// Optional GET parameters</jc> + <jc>// HTTP method.</jc> + String method = req.getMethod(); + + <jc>// Path variables.</jc> + RequestPathMatch path = req.getPathMatch(); + String p1 = path.get(<js>"p1"</js>, String.<jk>class</jk>); + <jk>int</jk> p2 = path.get(<js>"p2"</js>, <jk>int</jk>.<jk>class</jk>); + UUID p3 = path.get(<js>"p3"</js>, UUID.<jk>class</jk>); + + <jc>// Query parameters.</jc> RequestQuery query = req.getQuery(); - <jk>int</jk> p1 = query.get(<js>"p1"</js>, <jk>int</jk>.<jk>class</jk>, 0); - String p2 = query.get(<js>"p2"</js>, String.<jk>class</jk>); - UUID p3 = query.get(<js>"p3"</js>, UUID.<jk>class</jk>); - - <jc>// URL pattern post-match</jc> - String remainder = req.getPathRemainder(); - - <jc>// Headers</jc> - String lang = req.getHeader(<js>"Accept-Language"</js>); - <jk>int</jk> doNotTrack = req.getHeader(<js>"DNT"</js>, <jk>int</jk>.<jk>class</jk>); - - <jc>// Send back a simple String response</jc> - String output = String.format( - <js>"method=%s, a1=%s, a2=%d, a3=%s, remainder=%s, p1=%d, p2=%s, p3=%s, lang=%s, dnt=%d"</js>, - method, a1, a2, a3, remainder, p1, p2, p3, lang, doNotTrack); - res.setOutput(output); - } + <jk>int</jk> q1 = query.get(<js>"q1"</js>, 0, <jk>int</jk>.<jk>class</jk>); + String q2 = query.get(<js>"q2"</js>, String.<jk>class</jk>); + UUID q3 = query.get(<js>"q3"</js>, UUID.<jk>class</jk>); + + <jc>// Path remainder after pattern match.</jc> + String remainder = req.getPathMatch().getRemainder(); + + <jc>// Headers.</jc> + String lang = req.getHeader(<js>"Accept-Language"</js>); + String accept = req.getHeader(<js>"Accept"</js>); + <jk>int</jk> doNotTrack = req.getHeaders().get(<js>"DNT"</js>, <jk>int</jk>.<jk>class</jk>); + + <jc>// Send back a simple String response</jc> + String output = String.format( + <js>"method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s, accept=%s, dnt=%d"</js>, + method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack); + res.setOutput(output); <jc>// Or use getWriter().</jc> + } - <jd>/** Example GET request using resolved parameter objects */</jd> - <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/example3/{a1}/{a2}/{a3}/*"</js>, rc={200}) - <jk>public void</jk> doGetExample3( - HttpMethod httpMethod, - RequestPathParams path, - RequestQuery query, - <ja>@PathRemainder</ja> String remainder, - AcceptLanguage acceptLanguage, - Accept accept, - DNT dnt - ) <jk>throws</jk> Exception { - - String method = httpMethod.toString(); - - <jc>// Attributes (from URL pattern variables)</jc> - String a1 = path.get(<js>"a1"</js>, String.<jk>class</jk>); - <jk>int</jk> a2 = path.get(<js>"a2"</js>, <jk>int</jk>.<jk>class</jk>); - UUID a3 = path.get(<js>"a3"</js>, UUID.<jk>class</jk>); - - <jc>// Optional GET parameters</jc> - <jk>int</jk> p1 = query.get(<js>"p1"</js>, <jk>int</jk>.<jk>class</jk>, 0); - String p2 = query.get(<js>"p2"</js>, String.<jk>class</jk>); - UUID p3 = query.get(<js>"p3"</js>, UUID.<jk>class</jk>); - - <jc>// Headers</jc> - String lang = acceptLanguage.toString(); - <jk>int</jk> doNotTrack = dnt.asType(<jk>int</jk>.<jk>class</jk>); + <jd>/** + * Methodology #3 - GET request using special objects. + * This approach uses intermediate-level APIs. + * The framework recognizes the parameter types and knows how to resolve them. + */</jd> + <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/example3/{p1}/{p2}/{p3}/*"</js>) + <jk>public</jk> String example3( + HttpMethod method, <jc>// HTTP method.</jc> + RequestPathMatch path, <jc>// Path variables.</jc> + RequestQuery query, <jc>// Query parameters.</jc> + RequestHeaders headers, <jc>// Headers.</jc> + AcceptLanguage lang, <jc>// Specific header classes.</jc> + Accept accept + ) { - <jc>// Send back a simple String response</jc> - String output = String.format( - <js>"method=%s, a1=%s, a2=%d, a3=%s, remainder=%s, p1=%d, p2=%s, p3=%s, lang=%s, dnt=%d"</js>, - method, a1, a2, a3, remainder, p1, p2, p3, lang, doNotTrack); - res.setOutput(output); - } - } + <jc>// Path variables.</jc> + String p1 = path.get(<js>"p1"</js>, String.<jk>class</jk>); + <jk>int</jk> p2 = path.get(<js>"p2"</js>, <jk>int</jk>.<jk>class</jk>); + UUID p3 = path.get(<js>"p3"</js>, UUID.<jk>class</jk>); + + <jc>// Query parameters.</jc> + <jk>int</jk> q1 = query.get(<js>"q1"</js>, 0, <jk>int</jk>.<jk>class</jk>); + String q2 = query.get(<js>"q2"</js>, String.<jk>class</jk>); + UUID q3 = query.get(<js>"q3"</js>, UUID.<jk>class</jk>); + + <jc>// Path remainder after pattern match.</jc> + String remainder = path.getRemainder(); + + <jc>// Headers.</jc> + int doNotTrack = headers.get(<js>"DNT"</js>, <jk>int</jk>.<jk>class</jk>); + + <jc>// Send back a simple String response</jc> + String output = String.format( + <js>"method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s, accept=%s, dnt=%d"</js>, + method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack); + res.setOutput(output); + } + } </p> <p> The class consists of 4 methods: </p> <ul class='javahierarchy'> - <li class='m'><l>doGetExample()</l> + <li class='m'><l>doExample()</l> <br>The root page. <br>Performs a simple redirection to the <l>doGetExample1()</l> method using a {@link org.apache.juneau.rest.Redirect} object. - <li class='m'><l>doGetExample1()</l> + <li class='m'><l>example1()</l> <br>Shows how to use the following annotations: <ul> <li class='n'>{@link org.apache.juneau.rest.annotation.Path @Path} @@ -3135,18 +3152,18 @@ <li class='n'>{@link org.apache.juneau.rest.annotation.PathRemainder @PathRemainder} </ul> Method returns a POJO to be serialized as the output. - <li class='m'><l>doGetExample2()</l> + <li class='m'><l>example2()</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#getPathParams()} + <li class='m'>{@link org.apache.juneau.rest.RestRequest#getPathMatch()} <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()} + <li class='m'>{@link org.apache.juneau.rest.RequestPathMatch#getRemainder()} </ul> Method sets the POJO to be serialized using the {@link org.apache.juneau.rest.RestResponse#setOutput(Object)} method. - <li class='m'><l>doGetExample2()</l> + <li class='m'><l>example3()</l> <br>Identical to <l>doGetExample1()</l> but uses automatically resolved parameters based on class type. <br>Juneau automatically recognizes specific class types such as common header types and automatically resolves them to objects for you. @@ -4103,14 +4120,13 @@ <ja>@RestMethod</ja>(name=<js>"PUT"</js>, path=<js>"/people/{id}/*"</js>, guards=AdminGuard.<jk>class</jk> ) - <jk>public</jk> String updatePerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) <jk>throws</jk> Exception { + <jk>public</jk> String updatePerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id, <ja>@PathRemainder</ja> String remainder) <jk>throws</jk> Exception { <jk>try</jk> { Person p = findPerson(id); - String pathRemainder = req.getPathRemainder(); PojoRest r = <jk>new</jk> PojoRest(p); - ClassMeta<?> cm = r.getClassMeta(pathRemainder); - Object in = req.getBody(cm); - r.put(pathRemainder, in); + ClassMeta<?> cm = r.getClassMeta(remainder); + Object in = req.getBody().asType(cm); + r.put(remainder, in); <jk>return</jk> <js>"PUT successful"</js>; } <jk>catch</jk> (Exception e) { <jk>throw new</jk> RestException(<jsf>SC_BAD_REQUEST</jsf>, <js>"PUT unsuccessful"</js>).initCause(e); @@ -4124,14 +4140,13 @@ <ja>@RestMethod</ja>(name=<js>"PUT"</js>, path=<js>"/addresses/{id}/*"</js>, guards=AdminGuard.<jk>class</jk> ) - <jk>public</jk> String updateAddress(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) <jk>throws</jk> Exception { + <jk>public</jk> String updateAddress(RestRequest req, <ja>@Path</ja> <jk>int</jk> id, <ja>@PathRemainder</ja> String remainder) <jk>throws</jk> Exception { <jk>try</jk> { Address a = findAddress(id); - String pathInfo = req.getPathInfo(); PojoRest r = <jk>new</jk> PojoRest(a); - ClassMeta<?> cm = r.getClassMeta(pathInfo); - Object in = req.getBody(cm); - r.put(pathInfo, in); + ClassMeta<?> cm = r.getClassMeta(remainder); + Object in = req.getBody().asType(cm); + r.put(remainder, in); <jk>return</jk> <js>"PUT successful"</js>; } <jk>catch</jk> (Exception e) { <jk>throw new</jk> RestException(<jsf>SC_BAD_REQUEST</jsf>, <js>"PUT unsuccessful"</js>).initCause(e); @@ -5969,7 +5984,7 @@ <li>{@link org.apache.juneau.rest.RestRequest#getHeaders()} - The request headers. <li>{@link org.apache.juneau.rest.RestRequest#getQuery()} - The request query parameters. <li>{@link org.apache.juneau.rest.RestRequest#getFormData()} - The request form data parameters. - <li>{@link org.apache.juneau.rest.RestRequest#getPathParams()} - The path variables. + <li>{@link org.apache.juneau.rest.RestRequest#getPathMatch()} - The path variables and remainder. </ul> The following classes have been introduced: <ul> @@ -5977,7 +5992,7 @@ <li>{@link org.apache.juneau.rest.RequestHeaders} <li>{@link org.apache.juneau.rest.RequestQuery} <li>{@link org.apache.juneau.rest.RequestFormData} - <li>{@link org.apache.juneau.rest.RequestPathParams} + <li>{@link org.apache.juneau.rest.RequestPathMatch} </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: @@ -6030,7 +6045,7 @@ <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.RequestPathMatch} - 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. @@ -7502,7 +7517,7 @@ <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><code><del>RestRequest.getPathRemainderUndecoded()</del></code> <li>{@link org.apache.juneau.rest.RestRequest#getTrimmedRequestURI()} <li>{@link org.apache.juneau.rest.RestRequest#getTrimmedRequestURL()} <li>{@link org.apache.juneau.rest.RestRequest#getServletTitle()} @@ -7511,8 +7526,8 @@ </ul> <li>Behavior changes to {@link org.apache.juneau.rest.RestRequest#getPathInfo()} to follow Servlet specs. Returns <jk>null</jk> instead of blank for no path info. - <li>{@link org.apache.juneau.rest.RestRequest#getPathRemainder()} now automatically decodes the path remainder. - Use {@link org.apache.juneau.rest.RestRequest#getPathRemainderUndecoded()} to get the unencoded path remainder. + <li><code><del>RestRequest.getPathRemainder()</del></code> now automatically decodes the path remainder. + Use <code><del>RestRequest.getPathRemainderUndecoded()</del></code> to get the unencoded path remainder. <li>Bug fixes in {@link org.apache.juneau.rest.RestRequest#getRequestParentURI()} when servlet is mapped to <js>"/*"</js>. <li>Bug fixes in {@link org.apache.juneau.rest.RestRequest#getServletURI()} when servlet is mapped to <js>"/*"</js>. </ul> http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-core/src/main/javadoc/resources/juneau-doc.css ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/javadoc/resources/juneau-doc.css b/juneau-core/src/main/javadoc/resources/juneau-doc.css index 572b253..1bc7c23 100755 --- a/juneau-core/src/main/javadoc/resources/juneau-doc.css +++ b/juneau-core/src/main/javadoc/resources/juneau-doc.css @@ -343,6 +343,7 @@ l { p.severe, p.warn, p.info { background-repeat: no-repeat; background-position: left center; + background-size: 16px; padding-left: 30px; min-height: 24px; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java index ba6ce35..4aad593 100644 --- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java @@ -14,12 +14,14 @@ package org.apache.juneau.examples.rest; import java.util.*; +import org.apache.juneau.http.*; import org.apache.juneau.microservice.*; import org.apache.juneau.rest.*; import org.apache.juneau.rest.annotation.*; +import org.apache.juneau.rest.annotation.Method; /** - * Sample REST resource that shows how to define REST methods and OPTIONS pages + * Sample REST resource that shows how to define REST methods. */ @RestResource( path="/methodExample", @@ -31,59 +33,111 @@ public class MethodExampleResource extends Resource { /** Example GET request that redirects to our example method */ @RestMethod(name="GET", path="/") - public Redirect doGetExample() throws Exception { - return new Redirect("example1/xxx/123/{0}/xRemainder?p1=123&p2=yyy", UUID.randomUUID()); + public Redirect doExample() throws Exception { + return new Redirect("example1/xxx/123/{0}/xRemainder?q1=123&q2=yyy", UUID.randomUUID()); } - /** Example GET request using annotated attributes */ - @RestMethod(name="GET", path="/example1/{a1}/{a2}/{a3}/*", responses={@Response(200)}) - public String doGetExample1( - @Method String method, - @Path String a1, - @Path int a2, - @Path UUID a3, - @Query("p1") int p1, - @Query("p2") String p2, - @Query("p3") UUID p3, - @PathRemainder String remainder, - @Header("Accept-Language") String lang, + /** + * Methodology #1 - GET request using annotated attributes. + * This approach uses annotated parameters for retrieving input. + */ + @RestMethod(name="GET", path="/example1/{p1}/{p2}/{p3}/*") + public String example1( + @Method String method, // HTTP method. + @Path String p1, // Path variables. + @Path int p2, + @Path UUID p3, + @Query("q1") int q1, // Query parameters. + @Query("q2") String q2, + @Query("q3") UUID q3, + @PathRemainder String remainder, // Path remainder after pattern match. + @Header("Accept-Language") String lang, // Headers. @Header("Accept") String accept, @Header("DNT") int doNotTrack ) { + + // Send back a simple String response String output = String.format( - "method=%s, a1=%s, a2=%d, a3=%s, remainder=%s, p1=%d, p2=%s, p3=%s, lang=%s, accept=%s, dnt=%d", - method, a1, a2, a3, remainder, p1, p2, p3, lang, accept, doNotTrack); + "method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s, accept=%s, dnt=%d", + method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack); return output; } - /** Example GET request using methods on RestRequest and RestResponse */ - @RestMethod(name="GET", path="/example2/{a1}/{a2}/{a3}/*", responses={@Response(200)}) - public void doGetExample2(RestRequest req, RestResponse res) throws Exception { + /** + * Methodology #2 - GET request using methods on RestRequest and RestResponse. + * This approach uses low-level request/response objects to perform the same as above. + */ + @RestMethod(name="GET", path="/example2/{p1}/{p2}/{p3}/*") + public void example2( + RestRequest req, // A direct subclass of HttpServletRequest. + RestResponse res // A direct subclass of HttpServletResponse. + ) throws Exception { + + // HTTP method. String method = req.getMethod(); - // Attributes (from URL pattern variables) - RequestPathParams path = req.getPathParams(); - String a1 = path.get("a1", String.class); - int a2 = path.get("a2", int.class); - UUID a3 = path.get("a3", UUID.class); + // Path variables. + RequestPathMatch path = req.getPathMatch(); + String p1 = path.get("p1", String.class); + int p2 = path.get("p2", int.class); + UUID p3 = path.get("p3", UUID.class); - // Optional GET parameters + // Query parameters. RequestQuery query = req.getQuery(); - int p1 = query.get("p1", 0, int.class); - String p2 = query.get("p2", String.class); - UUID p3 = query.get("p3", UUID.class); + int q1 = query.get("q1", 0, int.class); + String q2 = query.get("q2", String.class); + UUID q3 = query.get("q3", UUID.class); - // URL pattern post-match - String remainder = req.getPathRemainder(); + // Path remainder after pattern match. + String remainder = req.getPathMatch().getRemainder(); - // Headers + // Headers. String lang = req.getHeader("Accept-Language"); + String accept = req.getHeader("Accept"); int doNotTrack = req.getHeaders().get("DNT", int.class); // Send back a simple String response String output = String.format( - "method=%s, a1=%s, a2=%d, a3=%s, remainder=%s, p1=%d, p2=%s, p3=%s, lang=%s, dnt=%d", - method, a1, a2, a3, remainder, p1, p2, p3, lang, doNotTrack); + "method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s, accept=%s, dnt=%d", + method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack); res.setOutput(output); } + + /** + * Methodology #3 - GET request using special objects. + * This approach uses intermediate-level APIs. + * The framework recognizes the parameter types and knows how to resolve them. + */ + @RestMethod(name="GET", path="/example3/{p1}/{p2}/{p3}/*") + public String example3( + HttpMethod method, // HTTP method. + RequestPathMatch path, // Path variables. + RequestQuery query, // Query parameters. + RequestHeaders headers, // Headers. + AcceptLanguage lang, // Specific header classes. + Accept accept + ) throws Exception { + + // Path variables. + String p1 = path.get("p1", String.class); + int p2 = path.get("p2", int.class); + UUID p3 = path.get("p3", UUID.class); + + // Query parameters. + int q1 = query.get("q1", 0, int.class); + String q2 = query.get("q2", String.class); + UUID q3 = query.get("q3", UUID.class); + + // Path remainder after pattern match. + String remainder = path.getRemainder(); + + // Headers. + int doNotTrack = headers.get("DNT", int.class); + + // Send back a simple String response + String output = String.format( + "method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s, accept=%s, dnt=%d", + method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack); + return output; + } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java ---------------------------------------------------------------------- diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java index 122d949..5fed44f 100644 --- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java +++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java @@ -203,14 +203,13 @@ public class AddressBookResource extends ResourceJena { @RestMethod(name="PUT", path="/people/{id}/*", guards=AdminGuard.class ) - public String updatePerson(RestRequest req, @Path int id) throws Exception { + public String updatePerson(RequestBody body, @Path int id, @PathRemainder String remainder) throws Exception { try { Person p = findPerson(id); - String pathRemainder = req.getPathRemainder(); PojoRest r = new PojoRest(p); - ClassMeta<?> cm = r.getClassMeta(pathRemainder); - Object in = req.getBody().asType(cm); - r.put(pathRemainder, in); + ClassMeta<?> cm = r.getClassMeta(remainder); + Object in = body.asType(cm); + r.put(remainder, in); return "PUT successful"; } catch (Exception e) { throw new RestException(SC_BAD_REQUEST, "PUT unsuccessful").initCause(e); @@ -224,14 +223,13 @@ public class AddressBookResource extends ResourceJena { @RestMethod(name="PUT", path="/addresses/{id}/*", guards=AdminGuard.class ) - public String updateAddress(RestRequest req, @Path int id) throws Exception { + public String updateAddress(RestRequest req, @Path int id, @PathRemainder String remainder) throws Exception { try { Address a = findAddress(id); - String pathInfo = req.getPathInfo(); PojoRest r = new PojoRest(a); - ClassMeta<?> cm = r.getClassMeta(pathInfo); + ClassMeta<?> cm = r.getClassMeta(remainder); Object in = req.getBody().asType(cm); - r.put(pathInfo, in); + r.put(remainder, in); return "PUT successful"; } catch (Exception e) { throw new RestException(SC_BAD_REQUEST, "PUT unsuccessful").initCause(e); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/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 2595771..a643da5 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#getFormData(String)}. - <li><l>$R{header.X}</l> - Value returned by {@link org.apache.juneau.rest.RestRequest#getHeader(String)}. + <li><l>$R{formData.X}</l> - Value returned by {@link org.apache.juneau.rest.RequestFormData#getFirst(String)}. + <li><l>$R{header.X}</l> - Value returned by {@link org.apache.juneau.rest.RequestHeaders#getFirst(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{path.X}</l> - Value returned by {@link org.apache.juneau.rest.RequestPathMatch#get(Object)}. <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#getQuery(String)}. + <li><l>$R{query.X}</l> - Value returned by {@link org.apache.juneau.rest.RequestQuery#getFirst(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/98a53eb3/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java index c18b5e3..e046779 100644 --- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java @@ -63,7 +63,7 @@ public class OnPostCallResource extends RestServlet { properties.put("p5", "xp5"); // New property String overrideAccept = req.getHeader("Override-Accept"); if (overrideAccept != null) - req.setHeader("Accept", overrideAccept); + req.getHeaders().put("Accept", overrideAccept); String overrideContentType = req.getHeader("Override-Content-Type"); if (overrideContentType != null) properties.put("Override-Content-Type", overrideContentType); @@ -93,7 +93,7 @@ public class OnPostCallResource extends RestServlet { properties.put("p4", "pp4"); String accept = req.getHeader("Accept"); if (accept == null || accept.isEmpty()) - req.setHeader("Accept", "text/s2"); + req.getHeaders().put("Accept", "text/s2"); return ""; } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java index 9479ab4..feefe2f 100644 --- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java @@ -61,7 +61,7 @@ public class OnPreCallResource extends RestServlet { properties.put("p5", "xp5"); // New property String overrideContentType = req.getHeader("Override-Content-Type"); if (overrideContentType != null) - req.setHeader("Content-Type", overrideContentType); + req.getHeaders().put("Content-Type", overrideContentType); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OverlappingMethodsResource.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OverlappingMethodsResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OverlappingMethodsResource.java index c5dfce1..0e943d4 100644 --- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OverlappingMethodsResource.java +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OverlappingMethodsResource.java @@ -45,14 +45,14 @@ public class OverlappingMethodsResource extends RestServletDefault { public static class Test1Guard extends RestGuard { @Override /* RestGuard */ public boolean isRequestAllowed(RestRequest req) { - return req.getQuery("t1","").equals("1"); + return req.getQuery().getFirst("t1","").equals("1"); } } public static class Test2Guard extends RestGuard { @Override /* RestGuard */ public boolean isRequestAllowed(RestRequest req) { - return req.getQuery("t2","").equals("2"); + return req.getQuery().getFirst("t2","").equals("2"); } } @@ -77,14 +77,14 @@ public class OverlappingMethodsResource extends RestServletDefault { public static class Test3aMatcher extends RestMatcher { @Override /* RestMatcher */ public boolean matches(RestRequest req) { - return req.getQuery("t1","").equals("1"); + return req.getQuery().getFirst("t1","").equals("1"); } } public static class Test3bMatcher extends RestMatcher { @Override /* RestMatcher */ public boolean matches(RestRequest req) { - return req.getQuery("t2","").equals("2"); + return req.getQuery().getFirst("t2","").equals("2"); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java index 0c29593..cfd7f15 100644 --- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java @@ -68,25 +68,25 @@ public class ParamsResource extends RestServletDefault { public void doGet3(HttpServletRequest reqx, HttpServletResponse resx, String foo, int bar) { RestRequest req = (RestRequest)reqx; RestResponse res = (RestResponse)resx; - res.setOutput("GET /get3/"+foo+"/"+bar+" remainder="+req.getPathRemainder()); + res.setOutput("GET /get3/"+foo+"/"+bar+" remainder="+req.getPathMatch().getRemainder()); } // Test method name with overlapping name, remainder allowed. @RestMethod(name="GET2") public void get2(RestRequest req, RestResponse res) { - res.setOutput("GET2 remainder="+req.getPathRemainder()); + res.setOutput("GET2 remainder="+req.getPathMatch().getRemainder()); } // Default POST @RestMethod(name="POST") public void doPost(RestRequest req, RestResponse res) { - res.setOutput("POST remainder="+req.getPathRemainder()); + res.setOutput("POST remainder="+req.getPathMatch().getRemainder()); } // Bean parameter @RestMethod(name="POST", path="/person/{person}") public void doPost(RestRequest req, RestResponse res, Person p) { - res.setOutput("POST /person/{name="+p.name+",birthDate.year="+p.birthDate.get(Calendar.YEAR)+"} remainder="+req.getPathRemainder()); + res.setOutput("POST /person/{name="+p.name+",birthDate.year="+p.birthDate.get(Calendar.YEAR)+"} remainder="+req.getPathMatch().getRemainder()); } // Various primitive types @@ -113,7 +113,7 @@ public class ParamsResource extends RestServletDefault { @RestMethod(name="GET", path="/testParamGet/*") public String testParamGet(RestRequest req, @Query("p1") String p1, @Query("p2") int p2) throws Exception { RequestQuery q = req.getQuery(); - return "p1=["+p1+","+req.getQuery("p1")+","+q.get("p1", String.class)+"],p2=["+p2+","+q.getFirst("p2")+","+q.get("p2", int.class)+"]"; + return "p1=["+p1+","+req.getQuery().getFirst("p1")+","+q.get("p1", String.class)+"],p2=["+p2+","+q.getFirst("p2")+","+q.get("p2", int.class)+"]"; } //==================================================================================================== @@ -122,7 +122,7 @@ public class ParamsResource extends RestServletDefault { @RestMethod(name="POST", path="/testParamPost/*") public String testParamPost(RestRequest req, @FormData("p1") String p1, @FormData("p2") int p2) throws Exception { RequestFormData f = req.getFormData(); - return "p1=["+p1+","+req.getFormData("p1")+","+f.get("p1", String.class)+"],p2=["+p2+","+req.getFormData("p2")+","+f.get("p2", int.class)+"]"; + return "p1=["+p1+","+req.getFormData().getFirst("p1")+","+f.get("p1", String.class)+"],p2=["+p2+","+req.getFormData().getFirst("p2")+","+f.get("p2", int.class)+"]"; } //==================================================================================================== @@ -131,7 +131,7 @@ public class ParamsResource extends RestServletDefault { @RestMethod(name="GET", path="/testQParamGet/*") public String testQParamGet(RestRequest req, @Query("p1") String p1, @Query("p2") int p2) throws Exception { RequestQuery q = req.getQuery(); - return "p1=["+p1+","+req.getQuery("p1")+","+q.get("p1", String.class)+"],p2=["+p2+","+q.getFirst("p2")+","+q.get("p2", int.class)+"]"; + return "p1=["+p1+","+req.getQuery().getFirst("p1")+","+q.get("p1", String.class)+"],p2=["+p2+","+q.getFirst("p2")+","+q.get("p2", int.class)+"]"; } //==================================================================================================== @@ -140,7 +140,7 @@ public class ParamsResource extends RestServletDefault { @RestMethod(name="POST", path="/testQParamPost/*") public String testQParamPost(RestRequest req, @Query("p1") String p1, @Query("p2") int p2) throws Exception { RequestQuery q = req.getQuery(); - return "p1=["+p1+","+req.getQuery("p1")+","+q.get("p1", String.class)+"],p2=["+p2+","+q.getFirst("p2")+","+q.get("p2", int.class)+"]"; + return "p1=["+p1+","+req.getQuery().getFirst("p1")+","+q.get("p1", String.class)+"],p2=["+p2+","+q.getFirst("p2")+","+q.get("p2", int.class)+"]"; } //==================================================================================================== @@ -149,7 +149,7 @@ public class ParamsResource extends RestServletDefault { @RestMethod(name="GET", path="/testPlainParamGet/*") public String testPlainParamGet(RestRequest req, @Query(value="p1",format="PLAIN") String p1) throws Exception { RequestQuery q = req.getQuery(); - return "p1=["+p1+","+req.getQuery("p1")+","+q.get("p1", String.class)+"]"; + return "p1=["+p1+","+req.getQuery().getFirst("p1")+","+q.get("p1", String.class)+"]"; } //==================================================================================================== @@ -158,7 +158,7 @@ public class ParamsResource extends RestServletDefault { @RestMethod(name="POST", path="/testPlainParamPost/*") public String testPlainParamPost(RestRequest req, @FormData(value="p1",format="PLAIN") String p1) throws Exception { RequestFormData f = req.getFormData(); - return "p1=["+p1+","+req.getFormData("p1")+","+f.get("p1", String.class)+"]"; + return "p1=["+p1+","+req.getFormData().getFirst("p1")+","+f.get("p1", String.class)+"]"; } //==================================================================================================== @@ -167,7 +167,7 @@ public class ParamsResource extends RestServletDefault { @RestMethod(name="GET", path="/testPlainQParamGet/*") public String testPlainQParamGet(RestRequest req, @Query(value="p1",format="PLAIN") String p1) throws Exception { RequestQuery q = req.getQuery(); - return "p1=["+p1+","+req.getQuery("p1")+","+q.get("p1", String.class)+"]"; + return "p1=["+p1+","+req.getQuery().getFirst("p1")+","+q.get("p1", String.class)+"]"; } //==================================================================================================== @@ -176,7 +176,7 @@ public class ParamsResource extends RestServletDefault { @RestMethod(name="POST", path="/testPlainQParamPost/*") public String testPlainQParamPost(RestRequest req, @Query(value="p1",format="PLAIN") String p1) throws Exception { RequestQuery q = req.getQuery(); - return "p1=["+p1+","+req.getQuery("p1")+","+q.get("p1", String.class)+"]"; + return "p1=["+p1+","+req.getQuery().getFirst("p1")+","+q.get("p1", String.class)+"]"; } //==================================================================================================== http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PathsResource.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PathsResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PathsResource.java index c0fc94f..3621c59 100644 --- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PathsResource.java +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PathsResource.java @@ -59,8 +59,8 @@ public class PathsResource extends RestServletDefault { .append("pathInfo", req.getPathInfo()) .append("pathInfoUndecoded", req.getPathInfoUndecoded()) .append("pathInfoParts", req.getPathInfoParts()) - .append("pathRemainder", req.getPathRemainder()) - .append("pathRemainderUndecoded", req.getPathRemainderUndecoded()) + .append("pathRemainder", req.getPathMatch().getRemainder()) + .append("pathRemainderUndecoded", req.getPathMatch().getRemainderUndecoded()) .append("requestURI", req.getRequestURI()) .append("requestParentURI", req.getRequestParentURI()) .append("requestURL", req.getRequestURL()) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/UrisResource.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/UrisResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/UrisResource.java index 8de0852..b5579d2 100644 --- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/UrisResource.java +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/UrisResource.java @@ -106,7 +106,7 @@ public class UrisResource extends RestServletDefault { ObjectMap m = new ObjectMap(); m.put("contextPath", req.getContextPath()); m.put("pathInfo", req.getPathInfo()); - m.put("pathRemainder", req.getPathRemainder()); + m.put("pathRemainder", req.getPathMatch().getRemainder()); m.put("pathTranslated", req.getPathTranslated()); m.put("requestParentURI", req.getRequestParentURI()); m.put("requestURI", req.getRequestURI()); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/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 4fe77de..869684c 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 @@ -658,10 +658,11 @@ class CallMethod implements Comparable<CallMethod> { if (patternVals.length > pathPattern.getVars().length) remainder = patternVals[pathPattern.getVars().length]; for (int i = 0; i < pathPattern.getVars().length; i++) - req.setPathParameter(pathPattern.getVars()[i], patternVals[i]); - + req.getPathMatch().put(pathPattern.getVars()[i], patternVals[i]); + req.getPathMatch().setRemainder(remainder); + ObjectMap requestProperties = createRequestProperties(properties, req); - req.init(method, remainder, requestProperties, defaultRequestHeaders, defaultCharset, serializers, parsers, urlEncodingParser, encoders, pageTitle, pageText, pageLinks); + req.init(method, requestProperties, defaultRequestHeaders, defaultCharset, serializers, parsers, urlEncodingParser, encoders, pageTitle, pageText, pageLinks); res.init(requestProperties, defaultCharset, serializers, urlEncodingSerializer, encoders); // Class-level guards @@ -753,11 +754,11 @@ class CallMethod implements Comparable<CallMethod> { String prefix = k.substring(0, k.indexOf('.')); String remainder = k.substring(k.indexOf('.')+1); if ("path".equals(prefix)) - return req.getPathParameter(remainder); + return req.getPathMatch().get(remainder); if ("query".equals(prefix)) - return req.getQuery(remainder); + return req.getQuery().get(remainder); if ("formData".equals(prefix)) - return req.getFormData(remainder); + return req.getFormData().get(remainder); if ("header".equals(prefix)) return req.getHeader(remainder); } @@ -792,7 +793,7 @@ class CallMethod implements Comparable<CallMethod> { return req.getPageText(); if (k.equals(HtmlDocSerializerContext.HTMLDOC_links)) return req.getPageLinks(); - o = req.getPathParameter(k); + o = req.getPathMatch().get(k); if (o == null) o = req.getHeader(k); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest/src/main/java/org/apache/juneau/rest/RequestBody.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestBody.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestBody.java index 1b509b4..5663bf3 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestBody.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestBody.java @@ -85,10 +85,10 @@ public class RequestBody { /** * Reads the input from the HTTP request as JSON, XML, or HTML and converts the input to a POJO. * <p> - * If {@code allowHeaderParams} init parameter is <jk>true</jk>, then first looks for {@code &body=xxx} in the URL + * If {@code allowHeaderParams} init parameter is <jk>true</jk>, then first looks for {@code &body=xxx} in the URL * query string. * <p> - * If type is <jk>null</jk> or <code>Object.<jk>class</jk></code>, then the actual type will be determined + * If type is <jk>null</jk> or <code>Object.<jk>class</jk></code>, then the actual type will be determined * automatically based on the following input: * <table class='styled'> * <tr><th>Type</th><th>JSON input</th><th>XML input</th><th>Return type</th></tr> @@ -130,32 +130,32 @@ public class RequestBody { * </tr> * </table> * <p> - * Refer to <a class="doclink" href="../../../../overview-summary.html#Core.PojoCategories">POJO Categories</a> for + * Refer to <a class="doclink" href="../../../../overview-summary.html#Core.PojoCategories">POJO Categories</a> for * a complete definition of supported POJOs. * <p> * <h5 class='section'>Examples:</h5> * <p class='bcode'> * <jc>// Parse into an integer.</jc> - * <jk>int</jk> body = req.getBody(<jk>int</jk>.<jk>class</jk>); + * <jk>int</jk> body = req.getBody().asType(<jk>int</jk>.<jk>class</jk>); * * <jc>// Parse into an int array.</jc> - * <jk>int</jk>[] body = req.getBody(<jk>int</jk>[].<jk>class</jk>); + * <jk>int</jk>[] body = req.getBody().asType(<jk>int</jk>[].<jk>class</jk>); * <jc>// Parse into a bean.</jc> - * MyBean body = req.getBody(MyBean.<jk>class</jk>); + * MyBean body = req.getBody().asType(MyBean.<jk>class</jk>); * * <jc>// Parse into a linked-list of objects.</jc> - * List body = req.getBody(LinkedList.<jk>class</jk>); + * List body = req.getBody().asType(LinkedList.<jk>class</jk>); * * <jc>// Parse into a map of object keys/values.</jc> - * Map body = req.getBody(TreeMap.<jk>class</jk>); + * Map body = req.getBody().asType(TreeMap.<jk>class</jk>); * </p> * * @param type The class type to instantiate. * @param <T> The class type to instantiate. * @return The input parsed to a POJO. * @throws IOException If a problem occurred trying to read from the reader. - * @throws ParseException If the input contains a syntax error or is malformed for the requested {@code Accept} + * @throws ParseException If the input contains a syntax error or is malformed for the requested {@code Accept} * header or is not valid for the specified type. */ public <T> T asType(Class<T> type) throws IOException, ParseException { @@ -168,23 +168,23 @@ public class RequestBody { * <h5 class='section'>Examples:</h5> * <p class='bcode'> * <jc>// Parse into a linked-list of strings.</jc> - * List<String> body = req.getBody(LinkedList.<jk>class</jk>, String.<jk>class</jk>); + * List<String> body = req.getBody().asType(LinkedList.<jk>class</jk>, String.<jk>class</jk>); * * <jc>// Parse into a linked-list of linked-lists of strings.</jc> - * List<List<String>> body = req.getBody(LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>); + * List<List<String>> body = req.getBody().asType(LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>); * * <jc>// Parse into a map of string keys/values.</jc> - * Map<String,String> body = req.getBody(TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>); + * Map<String,String> body = req.getBody().asType(TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>); * * <jc>// Parse into a map containing string keys and values of lists containing beans.</jc> - * Map<String,List<MyBean>> body = req.getBody(TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>); + * Map<String,List<MyBean>> body = req.getBody().asType(TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>); * </p> * * @param type The type of object to create. - * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, + * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, * {@link GenericArrayType} * @param args The type arguments of the class if it's a collection or map. - * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, + * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, * {@link GenericArrayType} * <br>Ignored if the main type is not a map or collection. * @param <T> The class type to instantiate. @@ -197,7 +197,7 @@ public class RequestBody { /** * Returns the HTTP body content as a plain string. * <p> - * If {@code allowHeaderParams} init parameter is true, then first looks for {@code &body=xxx} in the URL query + * If {@code allowHeaderParams} init parameter is true, then first looks for {@code &body=xxx} in the URL query * string. * * @return The incoming input from the connection as a plain string. @@ -224,7 +224,7 @@ public class RequestBody { /** * Returns the HTTP body content as a {@link Reader}. * <p> - * If {@code allowHeaderParams} init parameter is true, then first looks for {@code &body=xxx} in the URL query + * If {@code allowHeaderParams} init parameter is true, then first looks for {@code &body=xxx} in the URL query * string. * <p> * Automatically handles GZipped input streams. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathMatch.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathMatch.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathMatch.java new file mode 100644 index 0000000..de40e53 --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathMatch.java @@ -0,0 +1,213 @@ +// *************************************************************************************************************************** +// * 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.internal.StringUtils.*; + +import java.lang.reflect.*; +import java.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.parser.*; +import org.apache.juneau.urlencoding.*; + +/** + * Contains information about the matched path on the HTTP request. + * <p> + * Provides access to the matched path variables and path match remainder. + */ +@SuppressWarnings("unchecked") +public class RequestPathMatch extends TreeMap<String,String> { + private static final long serialVersionUID = 1L; + + private UrlEncodingParser parser; + private BeanSession beanSession; + private String remainder; + + RequestPathMatch() { + super(String.CASE_INSENSITIVE_ORDER); + } + + RequestPathMatch setParser(UrlEncodingParser parser) { + this.parser = parser; + return this; + } + + RequestPathMatch setBeanSession(BeanSession beanSession) { + this.beanSession = beanSession; + return this; + } + + RequestPathMatch setRemainder(String remainder) { + this.remainder = remainder; + return this; + } + + /** + * Sets a request query parameter value. + * + * @param name The parameter name. + * @param value The parameter value. + */ + public void put(String name, Object value) { + put(name, value); + } + + /** + * Returns the specified path parameter converted to a POJO. + * <p> + * The type can be any POJO type convertable from a <code>String</code> (See <a class="doclink" + * href="package-summary.html#PojosConvertableFromString">POJOs Convertable From Strings</a>). + * <p> + * <h5 class='section'>Examples:</h5> + * <p class='bcode'> + * <jc>// Parse into an integer.</jc> + * <jk>int</jk> myparam = req.getPathParameter(<js>"myparam"</js>, <jk>int</jk>.<jk>class</jk>); + * + * <jc>// Parse into an int array.</jc> + * <jk>int</jk>[] myparam = req.getPathParameter(<js>"myparam"</js>, <jk>int</jk>[].<jk>class</jk>); + + * <jc>// Parse into a bean.</jc> + * MyBean myparam = req.getPathParameter(<js>"myparam"</js>, MyBean.<jk>class</jk>); + * + * <jc>// Parse into a linked-list of objects.</jc> + * List myparam = req.getPathParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>); + * + * <jc>// Parse into a map of object keys/values.</jc> + * Map myparam = req.getPathParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>); + * </p> + * + * @param name The attribute name. + * @param type The class type to convert the attribute value to. + * @param <T> The class type to convert the attribute value to. + * @return The attribute value converted to the specified class type. + * @throws ParseException + */ + public <T> T get(String name, Class<T> type) throws ParseException { + return parse(name, beanSession.getClassMeta(type)); + } + + /** + * Returns the specified path parameter converted to a POJO. + * <p> + * The type can be any POJO type convertable from a <code>String</code> (See <a class="doclink" href="package-summary.html#PojosConvertableFromString">POJOs Convertable From Strings</a>). + * <p> + * Use this method if you want to parse into a parameterized <code>Map</code>/<code>Collection</code> object. + * <p> + * <h5 class='section'>Examples:</h5> + * <p class='bcode'> + * <jc>// Parse into a linked-list of strings.</jc> + * List<String> myparam = req.getPathParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, String.<jk>class</jk>); + * + * <jc>// Parse into a linked-list of linked-lists of strings.</jc> + * List<List<String>> myparam = req.getPathParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>); + * + * <jc>// Parse into a map of string keys/values.</jc> + * Map<String,String> myparam = req.getPathParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>); + * + * <jc>// Parse into a map containing string keys and values of lists containing beans.</jc> + * Map<String,List<MyBean>> myparam = req.getPathParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>); + * </p> + * + * @param name The attribute name. + * @param type The type of object to create. + * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + * @param args The type arguments of the class if it's a collection or map. + * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} + * <br>Ignored if the main type is not a map or collection. + * @param <T> The class type to convert the attribute value to. + * @return The attribute value converted to the specified class type. + * @throws ParseException + */ + public <T> T get(String name, Type type, Type...args) throws ParseException { + return (T)parse(name, beanSession.getClassMeta(type, args)); + } + + /* Workhorse method */ + <T> T parse(String name, ClassMeta<T> cm) throws ParseException { + Object attr = get(name); + T t = null; + if (attr != null) + t = parser.parsePart(attr.toString(), cm); + if (t == null && cm.isPrimitive()) + return cm.getPrimitiveDefault(); + return t; + } + + /** + * Returns the decoded remainder of the URL following any path pattern matches. + * <p> + * The behavior of path remainder is shown below given the path pattern "/foo/*": + * <p> + * <table class='styled'> + * <tr> + * <th>URL</th> + * <th>Path Remainder</th> + * </tr> + * <tr> + * <td><code>/foo</code></td> + * <td><jk>null</jk></td> + * </tr> + * <tr> + * <td><code>/foo/</code></td> + * <td><js>""</js></td> + * </tr> + * <tr> + * <td><code>/foo//</code></td> + * <td><js>"/"</js></td> + * </tr> + * <tr> + * <td><code>/foo///</code></td> + * <td><js>"//"</js></td> + * </tr> + * <tr> + * <td><code>/foo/a/b</code></td> + * <td><js>"a/b"</js></td> + * </tr> + * <tr> + * <td><code>/foo//a/b/</code></td> + * <td><js>"/a/b/"</js></td> + * </tr> + * <tr> + * <td><code>/foo/a%2Fb</code></td> + * <td><js>"a/b"</js></td> + * </tr> + * </table> + * + * <h5 class='section'>Example:</h5> + * <p class='bcode'> + * <jc>// REST method</jc> + * <ja>@RestMethod</ja>(name=<js>"GET"</js>,path=<js>"/foo/{bar}/*"</js>) + * <jk>public</jk> String doGetById(RequestPathParams pathParams, <jk>int</jk> bar) { + * <jk>return</jk> pathParams.getRemainder(); + * } + * + * <jc>// Prints "path/remainder"</jc> + * <jk>new</jk> RestCall(servletPath + <js>"/foo/123/path/remainder"</js>).connect(); + * </p> + * + * @return The path remainder string. + */ + public String getRemainder() { + return urlDecode(remainder); + } + + /** + * Same as {@link #getRemainder()} but doesn't decode characters. + * + * @return The undecoded path remainder. + */ + public String getRemainderUndecoded() { + return remainder; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathParams.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathParams.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathParams.java deleted file mode 100644 index 8a12a0e..0000000 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestPathParams.java +++ /dev/null @@ -1,137 +0,0 @@ -// *************************************************************************************************************************** -// * 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 java.lang.reflect.*; -import java.util.*; - -import org.apache.juneau.*; -import org.apache.juneau.parser.*; -import org.apache.juneau.urlencoding.*; - -/** - * Represents the path parameters on an HTTP request. - */ -@SuppressWarnings("unchecked") -public class RequestPathParams extends TreeMap<String,String> { - private static final long serialVersionUID = 1L; - - private UrlEncodingParser parser; - private BeanSession beanSession; - - RequestPathParams() { - super(String.CASE_INSENSITIVE_ORDER); - } - - RequestPathParams setParser(UrlEncodingParser parser) { - this.parser = parser; - return this; - } - - RequestPathParams setBeanSession(BeanSession beanSession) { - this.beanSession = beanSession; - return this; - } - - /** - * Sets a request query parameter value. - * - * @param name The parameter name. - * @param value The parameter value. - */ - public void put(String name, Object value) { - put(name, value); - } - - /** - * Returns the specified path parameter converted to a POJO. - * <p> - * The type can be any POJO type convertable from a <code>String</code> (See <a class="doclink" - * href="package-summary.html#PojosConvertableFromString">POJOs Convertable From Strings</a>). - * <p> - * <h5 class='section'>Examples:</h5> - * <p class='bcode'> - * <jc>// Parse into an integer.</jc> - * <jk>int</jk> myparam = req.getPathParameter(<js>"myparam"</js>, <jk>int</jk>.<jk>class</jk>); - * - * <jc>// Parse into an int array.</jc> - * <jk>int</jk>[] myparam = req.getPathParameter(<js>"myparam"</js>, <jk>int</jk>[].<jk>class</jk>); - - * <jc>// Parse into a bean.</jc> - * MyBean myparam = req.getPathParameter(<js>"myparam"</js>, MyBean.<jk>class</jk>); - * - * <jc>// Parse into a linked-list of objects.</jc> - * List myparam = req.getPathParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>); - * - * <jc>// Parse into a map of object keys/values.</jc> - * Map myparam = req.getPathParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>); - * </p> - * - * @param name The attribute name. - * @param type The class type to convert the attribute value to. - * @param <T> The class type to convert the attribute value to. - * @return The attribute value converted to the specified class type. - * @throws ParseException - */ - public <T> T get(String name, Class<T> type) throws ParseException { - return parse(name, beanSession.getClassMeta(type)); - } - - /** - * Returns the specified path parameter converted to a POJO. - * <p> - * The type can be any POJO type convertable from a <code>String</code> (See <a class="doclink" href="package-summary.html#PojosConvertableFromString">POJOs Convertable From Strings</a>). - * <p> - * Use this method if you want to parse into a parameterized <code>Map</code>/<code>Collection</code> object. - * <p> - * <h5 class='section'>Examples:</h5> - * <p class='bcode'> - * <jc>// Parse into a linked-list of strings.</jc> - * List<String> myparam = req.getPathParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, String.<jk>class</jk>); - * - * <jc>// Parse into a linked-list of linked-lists of strings.</jc> - * List<List<String>> myparam = req.getPathParameter(<js>"myparam"</js>, LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>); - * - * <jc>// Parse into a map of string keys/values.</jc> - * Map<String,String> myparam = req.getPathParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>); - * - * <jc>// Parse into a map containing string keys and values of lists containing beans.</jc> - * Map<String,List<MyBean>> myparam = req.getPathParameter(<js>"myparam"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>); - * </p> - * - * @param name The attribute name. - * @param type The type of object to create. - * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} - * @param args The type arguments of the class if it's a collection or map. - * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} - * <br>Ignored if the main type is not a map or collection. - * @param <T> The class type to convert the attribute value to. - * @return The attribute value converted to the specified class type. - * @throws ParseException - */ - public <T> T get(String name, Type type, Type...args) throws ParseException { - return (T)parse(name, beanSession.getClassMeta(type, args)); - } - - /* Workhorse method */ - <T> T parse(String name, ClassMeta<T> cm) throws ParseException { - Object attr = get(name); - T t = null; - if (attr != null) - t = parser.parsePart(attr.toString(), cm); - if (t == null && cm.isPrimitive()) - return cm.getPrimitiveDefault(); - return t; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/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 index dc29cc6..18d0e2f 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestParamDefaults.java @@ -538,7 +538,7 @@ class RestParamDefaults { @Override /* RestParam */ public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getPathParams().get(name, type); + return req.getPathMatch().get(name, type); } } @@ -597,7 +597,7 @@ class RestParamDefaults { if (multiPart) return req.getFormData().getAll(name, type); if (plainParams) - return bs.convertToType(req.getFormData(name), bs.getClassMeta(type)); + return bs.convertToType(req.getFormData().getFirst(name), bs.getClassMeta(type)); return req.getFormData().get(name, type); } } @@ -619,7 +619,7 @@ class RestParamDefaults { if (multiPart) return req.getQuery().getAll(name, type); if (plainParams) - return bs.convertToType(req.getQuery(name), bs.getClassMeta(type)); + return bs.convertToType(req.getQuery().getFirst(name), bs.getClassMeta(type)); return req.getQuery().get(name, type); } } @@ -664,7 +664,7 @@ class RestParamDefaults { @Override /* RestParam */ public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getPathRemainder(); + return req.getPathMatch().getRemainder(); } } @@ -905,12 +905,12 @@ class RestParamDefaults { static final class RequestPathParamsObject extends RestParam { protected RequestPathParamsObject() { - super(OTHER, null, RequestPathParams.class); + super(OTHER, null, RequestPathMatch.class); } @Override /* RestParam */ public Object resolve(RestRequest req, RestResponse res) throws Exception { - return req.getPathParams(); + return req.getPathMatch(); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java index dfced43..774fb5c 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java @@ -67,7 +67,6 @@ public final class RestRequest extends HttpServletRequestWrapper { private final RestContext context; private final String method; - private String pathRemainder; private RequestBody body; private Method javaMethod; private ObjectMap properties; @@ -79,7 +78,7 @@ public final class RestRequest extends HttpServletRequestWrapper { private VarResolverSession varSession; private final RequestQuery queryParams; private RequestFormData formData; - private RequestPathParams pathParams; + private RequestPathMatch pathParams; private boolean isPost; private String servletURI, relativeServletURI; private String charset, defaultCharset; @@ -111,7 +110,7 @@ public final class RestRequest extends HttpServletRequestWrapper { // Can be overridden through a "method" GET attribute. String _method = super.getMethod(); - String m = getQuery("method"); + String m = getQuery().getFirst("method"); if (context.allowMethodParam(m)) _method = m; @@ -126,7 +125,7 @@ public final class RestRequest extends HttpServletRequestWrapper { body = new RequestBody(this); if (context.isAllowBodyParam()) { - String b = getQuery("body"); + String b = getQuery().getFirst("body"); if (b != null) { headers.put("Content-Type", UonSerializer.DEFAULT.getResponseContentType()); body.load(b.getBytes(IOUtils.UTF8)); @@ -136,9 +135,9 @@ public final class RestRequest extends HttpServletRequestWrapper { if (context.isAllowHeaderParams()) headers.setQueryParams(queryParams); - debug = "true".equals(getQuery("debug", "false")) || "true".equals(getHeader("Debug", "false")); + debug = "true".equals(getQuery().getFirst("debug", "false")) || "true".equals(getHeaders().getFirst("Debug", "false")); - this.pathParams = new RequestPathParams(); + this.pathParams = new RequestPathMatch(); } catch (RestException e) { throw e; @@ -151,9 +150,8 @@ public final class RestRequest extends HttpServletRequestWrapper { * Called from RestServlet after a match has been made but before the guard or method invocation. */ @SuppressWarnings("hiding") - final void init(Method javaMethod, String pathRemainder, ObjectMap properties, Map<String,String> mDefaultRequestHeaders, String defaultCharset, SerializerGroup mSerializers, ParserGroup mParsers, UrlEncodingParser mUrlEncodingParser, EncoderGroup encoders, String pageTitle, String pageText, String pageLinks) { + final void init(Method javaMethod, ObjectMap properties, Map<String,String> mDefaultRequestHeaders, String defaultCharset, SerializerGroup mSerializers, ParserGroup mParsers, UrlEncodingParser mUrlEncodingParser, EncoderGroup encoders, String pageTitle, String pageText, String pageLinks) { this.javaMethod = javaMethod; - this.pathRemainder = pathRemainder; this.properties = properties; this.urlEncodingParser = mUrlEncodingParser; this.beanSession = urlEncodingParser.getBeanContext().createSession(); @@ -238,35 +236,11 @@ public final class RestRequest extends HttpServletRequestWrapper { return headers; } - /** - * Convenience method for calling <code>getHeaders().put(name, value);</code> - * - * @param name The header name. - * @param value The header value. - */ - public void setHeader(String name, Object value) { - getHeaders().put(name, value); - } - - /** - * Convenience method for calling <code>getHeaders().getFirst(name);</code> - */ @Override /* ServletRequest */ public String getHeader(String name) { return getHeaders().getFirst(name); } - /** - * Convenience method for calling <code>getHeaders().getFirst(name, def);</code> - * - * @param name The HTTP header name. - * @param def The default value to return if the header value isn't found. - * @return The header value, or the default value if the header isn't present. - */ - public String getHeader(String name, String def) { - return getHeaders().getFirst(name, def); - } - @Override /* ServletRequest */ public Enumeration<String> getHeaders(String name) { String[] v = headers.get(name); @@ -360,36 +334,14 @@ public final class RestRequest extends HttpServletRequestWrapper { } /** - * Convenience method for calling <code>getQueryParams().put(name, value);</code>. - * - * @param name The parameter name. - * @param value The parameter value. - */ - public void setQuery(String name, Object value) { - queryParams.put(name, value); - } - - /** - * Convenience method for calling <code>getQueryParams().getFirst(name);</code> - * - * @param name The URL parameter name. - * @return The parameter value, or <jk>null</jk> if parameter not specified or has no value (e.g. <js>"&foo"</js>. + * Shortcut for calling <code>getQuery().getFirst(name)</code>. + * @param name The query parameter name. + * @return The query parameter value, or <jk>null<jk> if not found. */ public String getQuery(String name) { return getQuery().getFirst(name); } - /** - * Convenience method for calling <code>getQueryParams().getFirst(name, def);</code> - * - * @param name The URL parameter name. - * @param def The default value. - * @return The parameter value, or the default value if parameter not specified or has no value (e.g. <js>"&foo"</js>. - */ - public String getQuery(String name, String def) { - return getQuery().getFirst(name, def); - } - //-------------------------------------------------------------------------------- // Form data parameters @@ -421,37 +373,15 @@ public final class RestRequest extends HttpServletRequestWrapper { } /** - * Convenience method for calling <code>getFormData().put(name, value);</code>. - * - * @param name The parameter name. - * @param value The parameter value. - */ - public void setFormData(String name, Object value) { - getFormData().put(name, value); - } - - /** - * Convenience method for calling <code>getFormData().getFirst(name);</code>. - * + * Shortcut for calling <code>getFormData().getFirst(name)</code>. * @param name The form data parameter name. - * @return The parameter value, or <jk>null</jk> if parameter does not exist. + * @return The form data parameter value, or <jk>null<jk> if not found. */ public String getFormData(String name) { return getFormData().getFirst(name); } - /** - * Convenience method for calling <code>getFormData().getFirst(name, def);</code>. - * - * @param name The form data parameter name. - * @param def The default value. - * @return The parameter value, or the default value if <jk>null</jk> or empty. - */ - public String getFormData(String name, String def) { - return getFormData().getFirst(name, def); - } - - + //-------------------------------------------------------------------------------- // Path parameters //-------------------------------------------------------------------------------- @@ -461,30 +391,10 @@ public final class RestRequest extends HttpServletRequestWrapper { * * @return The URL-encoded form data from the request. */ - public RequestPathParams getPathParams() { + public RequestPathMatch getPathMatch() { return pathParams; } - /** - * Convenience method for calling <code>getPathParams().put(name, value);</code>. - * - * @param name The parameter name. - * @param value The parameter value. - */ - public void setPathParameter(String name, String value) { - pathParams.put(name, StringUtils.toString(value)); - } - - /** - * Convenience method for calling <code>getPathParams().get(name);</code>. - * - * @param name The parameter name. - * @return The parameter value, or <jk>null</jk> if path parameter not specified. - */ - public String getPathParameter(String name) { - return pathParams.get(name); - } - //-------------------------------------------------------------------------------- // Body methods @@ -603,73 +513,6 @@ public final class RestRequest extends HttpServletRequestWrapper { } /** - * Returns the decoded remainder of the URL following any path pattern matches. - * <p> - * The behavior of path remainder is shown below given the path pattern "/foo/*": - * <p> - * <table class='styled'> - * <tr> - * <th>URL</th> - * <th>Path Remainder</th> - * </tr> - * <tr> - * <td><code>/foo</code></td> - * <td><jk>null</jk></td> - * </tr> - * <tr> - * <td><code>/foo/</code></td> - * <td><js>""</js></td> - * </tr> - * <tr> - * <td><code>/foo//</code></td> - * <td><js>"/"</js></td> - * </tr> - * <tr> - * <td><code>/foo///</code></td> - * <td><js>"//"</js></td> - * </tr> - * <tr> - * <td><code>/foo/a/b</code></td> - * <td><js>"a/b"</js></td> - * </tr> - * <tr> - * <td><code>/foo//a/b/</code></td> - * <td><js>"/a/b/"</js></td> - * </tr> - * <tr> - * <td><code>/foo/a%2Fb</code></td> - * <td><js>"a/b"</js></td> - * </tr> - * </table> - * - * <h5 class='section'>Example:</h5> - * <p class='bcode'> - * <jc>// REST method</jc> - * <ja>@RestMethod</ja>(name=<js>"GET"</js>,path=<js>"/foo/{bar}/*"</js>) - * <jk>public</jk> doGetById(RestServlet res, RestResponse res, <jk>int</jk> bar) { - * System.<jsm>err</jsm>.println(res.getRemainder()); - * } - * - * <jc>// Prints "path/remainder"</jc> - * <jk>new</jk> RestCall(servletPath + <js>"/foo/123/path/remainder"</js>).connect(); - * </p> - * - * @return The path remainder string. - */ - public String getPathRemainder() { - return urlDecode(pathRemainder); - } - - /** - * Same as {@link #getPathRemainder()} but doesn't decode characters. - * - * @return The undecoded path remainder. - */ - public String getPathRemainderUndecoded() { - return pathRemainder; - } - - /** * Returns the URI of the parent resource. * <p> * Trailing slashes in the path are ignored by this method. @@ -935,7 +778,7 @@ public final class RestRequest extends HttpServletRequestWrapper { * @return <jk>true</jk> if {@code &plainText=true} was specified as a URL parameter */ public boolean isPlainText() { - return "true".equals(getQuery("plainText", "false")); + return "true".equals(getQuery().getFirst("plainText", "false")); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Body.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Body.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Body.java index db5dcbe..8641e60 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Body.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/Body.java @@ -35,7 +35,7 @@ import java.lang.annotation.*; * <p class='bcode'> * <ja>@RestMethod</ja>(name=<js>"POST"</js>) * <jk>public void</jk> doPostPerson(RestRequest req, RestResponse res) { - * Person person = req.getBody(Person.<jk>class</jk>); + * Person person = req.getBody().asType(Person.<jk>class</jk>); * ... * } * </p> http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java index cf5f16d..f84368e 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Introspectable.java @@ -40,8 +40,8 @@ public final class Introspectable implements RestConverter { @Override /* RestConverter */ @SuppressWarnings({"unchecked", "rawtypes"}) public Object convert(RestRequest req, Object o, ClassMeta cm) throws RestException { - String method = req.getQuery("invokeMethod"); - String args = req.getQuery("invokeArgs"); + String method = req.getQuery().getFirst("invokeMethod"); + String args = req.getQuery().getFirst("invokeArgs"); if (method == null) return o; try { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/98a53eb3/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java index 4816453..734a804 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/converters/Traversable.java @@ -49,12 +49,12 @@ public final class Traversable implements RestConverter { if (o == null) return null; - if (req.getPathRemainder() != null) { + if (req.getPathMatch().getRemainder() != null) { try { if (cm.getPojoSwap() != null) o = cm.getPojoSwap().swap(req.getBeanSession(), o); PojoRest p = new PojoRest(o, req.getBody().getReaderParser()); - o = p.get(req.getPathRemainder()); + o = p.get(req.getPathMatch().getRemainder()); } catch (SerializeException e) { throw new RestException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); } catch (PojoRestException e) {
