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/05/05 16:30:49 UTC
[juneau] branch master updated: Improvements to @Path annotation.
This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 5423fc9 Improvements to @Path annotation.
5423fc9 is described below
commit 5423fc9d60c477231b0f3636d895d1a5a4fd0ba9
Author: JamesBognar <ja...@apache.org>
AuthorDate: Sat May 5 12:30:33 2018 -0400
Improvements to @Path annotation.
---
juneau-doc/src/main/javadoc/overview.html | 69 +++---
.../examples/rest/MethodExampleResource.java | 6 +-
.../juneau/examples/rest/PhotosResource.java | 6 +-
.../examples/rest/SystemPropertiesResource.java | 6 +-
.../rest/addressbook/AddressBookResource.java | 14 +-
.../examples/rest/petstore/PetStoreResource.java | 18 +-
.../juneau/rest/test/ErrorConditionsResource.java | 2 +-
.../apache/juneau/rest/test/ParamsResource.java | 34 ++-
.../juneau/rest/test/PathVariablesResource.java | 6 +-
.../juneau/rest/test/TransformsResource.java | 4 +-
.../java/org/apache/juneau/rest/RestContext.java | 32 +--
.../org/apache/juneau/rest/RestMethodParam.java | 8 +
.../org/apache/juneau/rest/RestParamDefaults.java | 79 +++++--
.../org/apache/juneau/rest/annotation/Path.java | 38 +---
.../juneau/rest/BasicRestInfoProviderTest.java | 233 +++++++++++++++++++--
15 files changed, 381 insertions(+), 174 deletions(-)
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index 75f9ce4..ecf0eb7 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -11562,9 +11562,9 @@
RestRequest req,
RestResponse res,
<ja>@Method</ja> String method,
- <ja>@Path</ja> String a1,
- <ja>@Path</ja> <jk>int</jk> a2,
- <ja>@Path</ja> UUID a3,
+ <ja>@Path</ja>(<js>"a1"</js>) String a1,
+ <ja>@Path</ja>(<js>"a2"</js>) <jk>int</jk> a2,
+ <ja>@Path</ja>(<js>"a3"</js>) 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,
@@ -11852,7 +11852,7 @@
<jc>// Method with path pattern with arguments</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/xxx/{foo}/{bar}/{baz}/{bing}"</js>)
- <jk>public void</jk> doGetWithArgs(<ja>@Path</ja> String foo, <ja>@Path</ja> <jk>int</jk> bar, <ja>@Path</ja> MyEnum baz, <ja>@Path</ja> UUID bing) {
+ <jk>public void</jk> doGetWithArgs(<ja>@Path</ja>(<js>"foo"</js>) String foo, <ja>@Path</ja>(<js>"bar"</js>) <jk>int</jk> bar, <ja>@Path</ja>(<js>"baz"</js>) MyEnum baz, <ja>@Path</ja>(<js>"bing"</js>) UUID bing) {
...
}
</p>
@@ -12045,14 +12045,14 @@
<p class='bcode w800'>
<jc>// Equivalent method 1</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/example1/{personId}"</js>)
- <jk>public</jk> Person doGet1(<ja>@Path</ja> UUID personId) {
+ <jk>public</jk> Person doGet1(<ja>@Path</ja>(<js>"personId"</js>) UUID personId) {
Person p = getPersonById(personId);
<jk>return</jk> p;
}
<jc>// Equivalent method 2</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/example2/{personId}"</js>)
- <jk>public void</jk> doGet2(RestResponse res, <ja>@Path</ja> UUID personId) {
+ <jk>public void</jk> doGet2(RestResponse res, <ja>@Path</ja>(<js>"personId"</js>) UUID personId) {
Person p = getPersonById(personId);
res.setOutput(p);
}
@@ -12060,7 +12060,7 @@
<jc>// (Sorta) Equivalent method 3</jc>
<jc>// (Ignores any converters or method-level properties)</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/example3/{personId}"</js>)
- <jk>public void</jk> doGet3(RestRequest req, RestResponse res, <ja>@Path</ja> UUID personId) {
+ <jk>public void</jk> doGet3(RestRequest req, RestResponse res, <ja>@Path</ja>(<js>"personId"</js>) UUID personId) {
Person p = getPersonById(personId);
String accept = req.getHeader(<js>"Accept"</js>, <js>"text/json"</js>);
WriterSerializer s = res.getSerializerGroup().getWriterSerializer(accept);
@@ -12976,7 +12976,7 @@
name=<jsf>GET</jsf>, path=<js>"/people/{id}/*"</js>,
converters={Traversable.<jk>class</jk>,Queryable.<jk>class</jk>}
)
- <jk>public</jk> Person getPerson(<ja>@Path</ja> <jk>int</jk> id) {
+ <jk>public</jk> Person getPerson(<ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id) {
<jk>return</jk> findPerson(id);
}
</p>
@@ -14651,7 +14651,7 @@
<jd>/** GET request handler for single photo */</jd>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/{id}"</js>, serializers=ImageSerializer.<jk>class</jk>)
- <jk>public</jk> BufferedImage getPhoto(RestRequest req, <ja>@Path</ja> int id) <jk>throws</jk> Exception {
+ <jk>public</jk> BufferedImage getPhoto(RestRequest req, <ja>@Path</ja>(<js>"id"</js>) int id) <jk>throws</jk> Exception {
Photo p = photos.get(id);
if (p == <jk>null</jk>)
<jk>throw new</jk> RestException(<jsf>SC_NOT_FOUND</jsf>, <js>"Photo not found"</js>);
@@ -14660,7 +14660,7 @@
<jd>/** PUT request handler */</jd>
<ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/{id}"</js>, parsers=ImageParser.<jk>class</jk>)
- <jk>public</jk> String addPhoto(RestRequest req, <ja>@Path</ja> <jk>int</jk> id, <ja>@Body</ja> BufferedImage image) <jk>throws</jk> Exception {
+ <jk>public</jk> String addPhoto(RestRequest req, <ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id, <ja>@Body</ja> BufferedImage image) <jk>throws</jk> Exception {
photos.put(id, <jk>new</jk> Photo(id, image));
<jk>return</jk> <js>"OK"</js>;
}
@@ -14676,7 +14676,7 @@
<jd>/** DELETE request handler */</jd>
<ja>@RestMethod</ja>(name=<jsf>DELETE</jsf>, path=<js>"/{id}"</js>)
- <jk>public</jk> String deletePhoto(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) <jk>throws</jk> Exception {
+ <jk>public</jk> String deletePhoto(RestRequest req, <ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id) <jk>throws</jk> Exception {
Photo p = photos.remove(id);
if (p == <jk>null</jk>)
<jk>throw new</jk> RestException(<jsf>SC_NOT_FOUND</jsf>, <js>"Photo not found"</js>);
@@ -17707,7 +17707,7 @@
<js>"}"</js>
}
)
- <jk>public</jk> String getSystemProperty(<ja>@Path</ja> String propertyName) <jk>throws</jk> Throwable {
+ <jk>public</jk> String getSystemProperty(<ja>@Path</ja>(<js>"propertyName"</js>) String propertyName) <jk>throws</jk> Throwable {
<jk>return</jk> System.<jsm>getProperty</jsm>(propertyName);
}
@@ -17727,7 +17727,7 @@
<js>"}"</js>
}
)
- <jk>public</jk> Redirect setSystemProperty(<ja>@Path</ja> String propertyName, <ja>@Body</ja> String value) {
+ <jk>public</jk> Redirect setSystemProperty(<ja>@Path</ja>(<js>"propertyName"</js>) String propertyName, <ja>@Body</ja> String value) {
System.<jsm>setProperty</jsm>(propertyName, value);
<jk>return new</jk> Redirect(<js>"servlet:/"</js>);
}
@@ -17768,7 +17768,7 @@
<js>"}"</js>
}
)
- <jk>public</jk> Redirect deleteSystemProperty(<ja>@Path</ja> String propertyName) {
+ <jk>public</jk> Redirect deleteSystemProperty(<ja>@Path</ja>(<js>"propertyName"</js>) String propertyName) {
System.<jsm>clearProperty</jsm>(propertyName);
<jk>return new</jk> Redirect(<js>"servlet:/"</js>);
}
@@ -17913,9 +17913,9 @@
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, 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>@Path</ja>(<js>"p1"</js>) String p1, <jc>// Path variables.</jc>
+ <ja>@Path</ja>(<js>"p2"</js>) <jk>int</jk> p2,
+ <ja>@Path</ja>(<js>"p3"</js>) 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,
@@ -18982,7 +18982,7 @@
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/people/{id}/*"</js>,
converters={Traversable.<jk>class</jk>,Queryable.<jk>class</jk>,Introspectable.<jk>class</jk>}
)
- <jk>public</jk> Person getPerson(<ja>@Path</ja> <jk>int</jk> id) <jk>throws</jk> Exception {
+ <jk>public</jk> Person getPerson(<ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id) <jk>throws</jk> Exception {
<jk>return</jk> findPerson(id);
}
@@ -19004,7 +19004,7 @@
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/addresses/{id}/*"</js>,
converters={Traversable.<jk>class</jk>,Queryable.<jk>class</jk>}
)
- <jk>public</jk> Address getAddress(<ja>@Path</ja> <jk>int</jk> id) <jk>throws</jk> Exception {
+ <jk>public</jk> Address getAddress(<ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id) <jk>throws</jk> Exception {
<jk>return</jk> findAddress(id);
}
@@ -19027,7 +19027,7 @@
<ja>@RestMethod</ja>(name=<jsf>POST</jsf>, path=<js>"/people/{id}/addresses"</js>,
guards=AdminGuard.<jk>class</jk>
)
- <jk>public</jk> Redirect createAddress(<ja>@Path</ja> <jk>int</jk> id, <ja>@Body</ja> CreateAddress ca) <jk>throws</jk> Exception {
+ <jk>public</jk> Redirect createAddress(<ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id, <ja>@Body</ja> CreateAddress ca) <jk>throws</jk> Exception {
Person p = findPerson(id);
Address a = p.createAddress(ca);
<jk>return new</jk> Redirect(<js>"addresses/{0}"</js>, a.id);
@@ -19040,7 +19040,7 @@
<ja>@RestMethod</ja>(name=<jsf>DELETE</jsf>, path=<js>"/people/{id}"</js>,
guards=AdminGuard.<jk>class</jk>,
)
- <jk>public</jk> String deletePerson(<ja>@Path</ja> <jk>int</jk> id) <jk>throws</jk> Exception {
+ <jk>public</jk> String deletePerson(<ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id) <jk>throws</jk> Exception {
<jf>addressBook</jf>.removePerson(id);
<jk>return</jk> <js>"DELETE successful"</js>;
}
@@ -19052,7 +19052,7 @@
<ja>@RestMethod</ja>(name=<jsf>DELETE</jsf>, path=<js>"/addresses/{id}"</js>,
guards=AdminGuard.<jk>class</jk>
)
- <jk>public</jk> String deleteAddress(<ja>@Path</ja> <jk>int</jk> addressId) <jk>throws</jk> Exception {
+ <jk>public</jk> String deleteAddress(<ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> addressId) <jk>throws</jk> Exception {
Person p = <jf>addressBook</jf>.findPersonWithAddress(addressId);
<jk>if</jk> (p == <jk>null</jk>)
<jk>throw new</jk> RestException(<jsf>SC_NOT_FOUND</jsf>, <js>"Person not found"</js>);
@@ -19068,7 +19068,7 @@
<ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/people/{id}/*"</js>,
guards=AdminGuard.<jk>class</jk>
)
- <jk>public</jk> String updatePerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id, <ja>@PathRemainder</ja>
+ <jk>public</jk> String updatePerson(RestRequest req, <ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id, <ja>@PathRemainder</ja>
String remainder) <jk>throws</jk> Exception {
<jk>try</jk> {
Person p = findPerson(id);
@@ -19089,7 +19089,7 @@
<ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, 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>public</jk> String updateAddress(RestRequest req, <ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id,
<ja>@PathRemainder</ja> String remainder) <jk>throws</jk> Exception {
<jk>try</jk> {
Address a = findAddress(id);
@@ -20109,7 +20109,7 @@
<jd>/** GET request handler for single photo */</jd>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/{id}"</js>, serializers=ImageSerializer.<jk>class</jk>, summary=<js>"Get a photo by ID"</js>)
- <jk>public</jk> BufferedImage getPhoto(<ja>@Path</ja> String id) <jk>throws</jk> Exception {
+ <jk>public</jk> BufferedImage getPhoto(<ja>@Path</ja>(<js>"id"</js>) String id) <jk>throws</jk> Exception {
Photo p = <jf>photos</jf>.get(id);
<jk>if</jk> (p == <jk>null</jk>)
<jk>throw new</jk> RestException(<jsf>SC_NOT_FOUND</jsf>, <js>"Photo not found"</js>);
@@ -20118,7 +20118,7 @@
<jd>/** PUT request handler */</jd>
<ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/{id}"</js>, parsers=ImageParser.<jk>class</jk>, summary=<js>"Add or overwrite a photo"</js>)
- <jk>public</jk> String addPhoto(<ja>@Path</ja> String id, <ja>@Body</ja> BufferedImage image) <jk>throws</jk> Exception {
+ <jk>public</jk> String addPhoto(<ja>@Path</ja>(<js>"id"</js>) String id, <ja>@Body</ja> BufferedImage image) <jk>throws</jk> Exception {
<jf>photos</jf>.put(id, <jk>new</jk> Photo(id, image));
<jk>return</jk> <js>"OK"</js>;
}
@@ -20133,7 +20133,7 @@
<jd>/** DELETE request handler */</jd>
<ja>@RestMethod</ja>(name=<jsf>DELETE</jsf>, path=<js>"/{id}"</js>, summary=<js>"Delete a photo by ID"</js>)
- <jk>public</jk> String deletePhoto(<ja>@Path</ja> String id) <jk>throws</jk> Exception {
+ <jk>public</jk> String deletePhoto(<ja>@Path</ja>(<js>"id"</js>) String id) <jk>throws</jk> Exception {
Photo p = <jf>photos</jf>.remove(id);
<jk>if</jk> (p == <jk>null</jk>)
<jk>throw new</jk> RestException(<jsf>SC_NOT_FOUND</jsf>, <js>"Photo not found"</js>);
@@ -23066,9 +23066,9 @@
<ja>@RestMethod</ja>(name=<js>"*"</js>, path=<js>"/example1/{a1}/{a2}/{a3}/*"</js>)
<jk>public</jk> String example1(
<ja>@Method</ja> String method,
- <ja>@Path</ja> String a1,
- <ja>@Path</ja> <jk>int</jk> a2,
- <ja>@Path</ja> UUID a3,
+ <ja>@Path</ja>(<js>"a1"</js>) String a1,
+ <ja>@Path</ja>(<js>"a2"</js>) <jk>int</jk> a2,
+ <ja>@Path</ja>(<js>"a3"</js>) 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,
@@ -23424,15 +23424,6 @@
See {@link org.apache.juneau.rest.annotation.RestMethod#name() @RestMethod.name()} for more information.
<li>{@link org.apache.juneau.rest.RestRequest#toString()} can be called at any time to view the headers and content of the request
without affecting functionality. Very useful for debugging.
- <li>You can now use numeric values in path annotations.
- <br>When using numeric variable names, you don't need to specify the variable name in the <ja>@Path</ja> annoation:
- <p class='bcode w800'>
- <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/myurl/{0}/{1}/{2}/*"</js>)
- <jk>public void</jk> doGet(RestRequest req, RestResponse res,
- <ja>@Path</ja> String foo, <ja>@Path</ja> <jk>int</jk> bar, <ja>@Path</ja> UUID baz) {
- ...
- }
- </p>
<li>{@link org.apache.juneau.rest.annotation.RestMethod#name() @RestMethod.name()} annotation is now optional. Defaults to <js>"GET"</js>.
</ul>
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
index 04e2511..25aefd8 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
@@ -81,9 +81,9 @@ public class MethodExampleResource extends BasicRestServlet {
)
public Map<String,Object> example1(
@Method String method, // HTTP method.
- @Path String p1, // Path variables.
- @Path int p2,
- @Path UUID p3,
+ @Path("p1") String p1, // Path variables.
+ @Path("p2") int p2,
+ @Path("p3") UUID p3,
@Query("q1") int q1, // Query parameters.
@Query("q2") String q2,
@Query(name="q3",_default=SAMPLE_UUID_STRING) UUID q3,
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
index 58b576a..eb5a66e 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
@@ -102,7 +102,7 @@ public class PhotosResource extends BasicRestServlet {
/** GET request handler for single photo */
@RestMethod(name=GET, path="/{id}", serializers=ImageSerializer.class, summary="Get a photo by ID")
- public BufferedImage getPhoto(@Path String id) throws NotFound {
+ public BufferedImage getPhoto(@Path("id") String id) throws NotFound {
Photo p = photos.get(id);
if (p == null)
throw new NotFound("Photo not found");
@@ -111,7 +111,7 @@ public class PhotosResource extends BasicRestServlet {
/** PUT request handler */
@RestMethod(name=PUT, path="/{id}", parsers=ImageParser.class, summary="Add or overwrite a photo")
- public String addPhoto(@Path String id, @Body BufferedImage image) throws Exception {
+ public String addPhoto(@Path("id") String id, @Body BufferedImage image) throws Exception {
photos.put(id, new Photo(id, image));
return "OK";
}
@@ -126,7 +126,7 @@ public class PhotosResource extends BasicRestServlet {
/** DELETE request handler */
@RestMethod(name=DELETE, path="/{id}", summary="Delete a photo by ID")
- public String deletePhoto(@Path String id) throws NotFound {
+ public String deletePhoto(@Path("id") String id) throws NotFound {
Photo p = photos.remove(id);
if (p == null)
throw new NotFound("Photo not found");
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
index e2fcf1e..83ab40f 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
@@ -123,7 +123,7 @@ public class SystemPropertiesResource extends BasicRestServlet {
)
)
public String getSystemProperty(
- @Path(description="The system property name.", example="PATH") String propertyName
+ @Path(name="propertyName", description="The system property name.", example="PATH") String propertyName
) throws NotAcceptable {
return System.getProperty(propertyName);
@@ -136,7 +136,7 @@ public class SystemPropertiesResource extends BasicRestServlet {
guards=AdminGuard.class
)
public RedirectToServletRoot setSystemProperty(
- @Path(description="The system property name") String propertyName,
+ @Path(name="propertyName", description="The system property name") String propertyName,
@Body(description="The new system property value") String value
) throws UserNotAdminException, NotAcceptable, UnsupportedMediaType {
@@ -165,7 +165,7 @@ public class SystemPropertiesResource extends BasicRestServlet {
guards=AdminGuard.class
)
public RedirectToServletRoot deleteSystemProperty(
- @Path(description="The system property name", example="PATH") String propertyName
+ @Path(name="propertyName", description="The system property name", example="PATH") String propertyName
) throws UserNotAdminException, NotAcceptable {
System.clearProperty(propertyName);
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
index 14f4637..ed11413 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
@@ -185,7 +185,7 @@ public class AddressBookResource extends BasicRestServletJena {
@RestMethod(name=GET, path="/people/{id}/*",
converters={Traversable.class,Introspectable.class}
)
- public Person getPerson(@Path int id) throws Exception {
+ public Person getPerson(@Path("id") int id) throws Exception {
return findPerson(id);
}
@@ -213,7 +213,7 @@ public class AddressBookResource extends BasicRestServletJena {
@RestMethod(name=GET, path="/addresses/{id}/*",
converters={Traversable.class}
)
- public Address getAddress(@Path int id) throws Exception {
+ public Address getAddress(@Path("id") int id) throws Exception {
return findAddress(id);
}
@@ -236,7 +236,7 @@ public class AddressBookResource extends BasicRestServletJena {
@RestMethod(name=POST, path="/people/{id}/addresses",
guards=AdminGuard.class
)
- public Redirect createAddress(@Path int id, @Body CreateAddress ca) throws Exception {
+ public Redirect createAddress(@Path("id") int id, @Body CreateAddress ca) throws Exception {
Person p = findPerson(id);
Address a = p.createAddress(ca);
return new Redirect("addresses/{0}", a.id);
@@ -249,7 +249,7 @@ public class AddressBookResource extends BasicRestServletJena {
@RestMethod(name=DELETE, path="/people/{id}",
guards=AdminGuard.class
)
- public String deletePerson(@Path int id) throws Exception {
+ public String deletePerson(@Path("id") int id) throws Exception {
addressBook.removePerson(id);
return "DELETE successful";
}
@@ -261,7 +261,7 @@ public class AddressBookResource extends BasicRestServletJena {
@RestMethod(name=DELETE, path="/addresses/{id}",
guards=AdminGuard.class
)
- public String deleteAddress(@Path int addressId) throws NotFound {
+ public String deleteAddress(@Path("id") int addressId) throws NotFound {
Person p = addressBook.findPersonWithAddress(addressId);
if (p == null)
throw new NotFound("Person not found");
@@ -277,7 +277,7 @@ public class AddressBookResource extends BasicRestServletJena {
@RestMethod(name=PUT, path="/people/{id}/*",
guards=AdminGuard.class
)
- public String updatePerson(RequestBody body, @Path int id, @PathRemainder String remainder) throws BadRequest {
+ public String updatePerson(RequestBody body, @Path("id") int id, @PathRemainder String remainder) throws BadRequest {
try {
Person p = findPerson(id);
PojoRest r = new PojoRest(p);
@@ -297,7 +297,7 @@ public class AddressBookResource extends BasicRestServletJena {
@RestMethod(name=PUT, path="/addresses/{id}/*",
guards=AdminGuard.class
)
- public String updateAddress(RestRequest req, @Path int id, @PathRemainder String remainder) throws BadRequest {
+ public String updateAddress(RestRequest req, @Path("id") int id, @PathRemainder String remainder) throws BadRequest {
try {
Address a = findAddress(id);
PojoRest r = new PojoRest(a);
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java
index 7aafeec..beaf3b2 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java
@@ -149,7 +149,7 @@ public class PetStoreResource extends BasicRestServletJena {
)
)
public Pet getPet(
- @Path(description="ID of pet to return", example="123") long petId
+ @Path(name="petId", description="ID of pet to return", example="123") long petId
) throws IdNotFound, NotAcceptable {
return store.getPet(petId);
@@ -206,7 +206,7 @@ public class PetStoreResource extends BasicRestServletJena {
)
)
public Div editPetPage(
- @Path(description="ID of pet to return", example="123") long petId
+ @Path(name="petId", description="ID of pet to return", example="123") long petId
) throws IdConflict, NotAcceptable, UnsupportedMediaType {
Pet pet = getPet(petId);
@@ -328,7 +328,7 @@ public class PetStoreResource extends BasicRestServletJena {
)
public Ok deletePet(
@Header(name="api_key", example="foobar") String apiKey,
- @Path(description="Pet id to delete", example="123") long petId
+ @Path(name="petId", description="Pet id to delete", example="123") long petId
) throws IdNotFound, NotAcceptable {
store.removePet(petId);
@@ -347,7 +347,7 @@ public class PetStoreResource extends BasicRestServletJena {
)
)
public Ok uploadImage(
- @Path(description="ID of pet to update", example="123") long petId,
+ @Path(name="petId", description="ID of pet to update", example="123") long petId,
@FormData(name="additionalMetadata", description="Additional data to pass to server", example="Foobar") String additionalMetadata,
@FormData(name="file", description="file to upload", required="true", type="file") byte[] file
) throws NotAcceptable, UnsupportedMediaType {
@@ -407,7 +407,7 @@ public class PetStoreResource extends BasicRestServletJena {
)
)
public Order getOrder(
- @Path(description="ID of order to fetch", maximum="1000", minimum="101", example="123") long orderId
+ @Path(name="orderId", description="ID of order to fetch", maximum="1000", minimum="101", example="123") long orderId
) throws InvalidId, IdNotFound, NotAcceptable {
if (orderId < 101 || orderId > 1000)
@@ -448,7 +448,7 @@ public class PetStoreResource extends BasicRestServletJena {
)
)
public Ok deletePurchaseOrder(
- @Path(description="ID of the order that needs to be deleted", minimum="1", example="5") long orderId
+ @Path(name="orderId", description="ID of the order that needs to be deleted", minimum="1", example="5") long orderId
) throws InvalidId, IdNotFound, NotAcceptable {
if (orderId < 0)
@@ -502,7 +502,7 @@ public class PetStoreResource extends BasicRestServletJena {
)
)
public User getUser(
- @Path(description="The name that needs to be fetched. Use user1 for testing.") String username
+ @Path(name="username", description="The name that needs to be fetched. Use user1 for testing.") String username
) throws InvalidUsername, IdNotFound, NotAcceptable {
return store.getUser(username);
@@ -552,7 +552,7 @@ public class PetStoreResource extends BasicRestServletJena {
)
)
public Ok updateUser(
- @Path(description="Name that need to be updated") String username,
+ @Path(name="username", description="Name that need to be updated") String username,
@Body(description="Updated user object") User user
) throws InvalidUsername, IdNotFound, NotAcceptable, UnsupportedMediaType {
@@ -570,7 +570,7 @@ public class PetStoreResource extends BasicRestServletJena {
)
)
public Ok deleteUser(
- @Path(description="The name that needs to be deleted") String username
+ @Path(name="username", description="The name that needs to be deleted") String username
) throws InvalidUsername, IdNotFound, NotAcceptable {
store.removeUser(username);
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ErrorConditionsResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ErrorConditionsResource.java
index a7a03af..1a6bf1f 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ErrorConditionsResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ErrorConditionsResource.java
@@ -108,7 +108,7 @@ public class ErrorConditionsResource extends BasicRestServlet {
// Test trying to set parameters to invalid types.
//====================================================================================================
@RestMethod(name=PUT, path="/testSetParameterToInvalidTypes/{a1}")
- public String testSetParameterToInvalidTypes(@Query("p1") int t1, @Path int a1, @Header("h1") int h1) {
+ public String testSetParameterToInvalidTypes(@Query("p1") int t1, @Path("a1") int a1, @Header("h1") int h1) {
return "OK";
}
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
index 1c73265..f3c3fef 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
@@ -63,17 +63,17 @@ public class ParamsResource extends BasicRestServlet {
}
@RestMethod(name=GET, path="/get1/{foo}")
- public void doGet1a(RestResponse res, String foo) {
+ public void doGet1a(RestResponse res, @Path("foo") String foo) {
res.setOutput("GET /get1a " + foo);
}
@RestMethod(name=GET, path="/get1/{foo}/{bar}")
- public void doGet1b(RestResponse res, String foo, String bar) {
+ public void doGet1b(RestResponse res, @Path("foo") String foo, @Path("bar") String bar) {
res.setOutput("GET /get1b " + foo + "," + bar);
}
@RestMethod(name=GET, path="/get3/{foo}/{bar}/*")
- public void doGet3(HttpServletRequest reqx, HttpServletResponse resx, String foo, int bar) {
+ public void doGet3(HttpServletRequest reqx, HttpServletResponse resx, @Path("foo") String foo, @Path("bar") int bar) {
RestRequest req = (RestRequest)reqx;
RestResponse res = (RestResponse)resx;
res.setOutput("GET /get3/"+foo+"/"+bar+" remainder="+req.getPathMatch().getRemainder());
@@ -93,25 +93,45 @@ public class ParamsResource extends BasicRestServlet {
// Bean parameter
@RestMethod(name=POST, path="/person/{person}")
- public void doPost(RestRequest req, RestResponse res, Person p) {
+ public void doPost(RestRequest req, RestResponse res, @Path("person") Person p) {
res.setOutput("POST /person/{name="+p.name+",birthDate.year="+p.birthDate.get(Calendar.YEAR)+"} remainder="+req.getPathMatch().getRemainder());
}
// Various primitive types
@RestMethod(name=PUT, path="/primitives/{xInt}/{xShort}/{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
- public void doPut1(RestResponse res, int xInt, short xShort, long xLong, char xChar, float xFloat, double xDouble, byte xByte, boolean xBoolean) {
+ public void doPut1(
+ RestResponse res,
+ @Path("xInt") int xInt,
+ @Path("xShort") short xShort,
+ @Path("xLong") long xLong,
+ @Path("xChar") char xChar,
+ @Path("xFloat") float xFloat,
+ @Path("xDouble") double xDouble,
+ @Path("xByte") byte xByte,
+ @Path("xBoolean") boolean xBoolean
+ ) {
res.setOutput("PUT /primitives/"+xInt+"/"+xShort+"/"+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
}
// Various primitive objects
@RestMethod(name=PUT, path="/primitiveObjects/{xInt}/{xShort}/{xLong}/{xChar}/{xFloat}/{xDouble}/{xByte}/{xBoolean}")
- public void doPut2(RestResponse res, Integer xInt, Short xShort, Long xLong, Character xChar, Float xFloat, Double xDouble, Byte xByte, Boolean xBoolean) {
+ public void doPut2(
+ RestResponse res,
+ @Path("xInt") Integer xInt,
+ @Path("xShort") Short xShort,
+ @Path("xLong") Long xLong,
+ @Path("xChar") Character xChar,
+ @Path("xFloat") Float xFloat,
+ @Path("xDouble") Double xDouble,
+ @Path("xByte") Byte xByte,
+ @Path("xBoolean") Boolean xBoolean
+ ) {
res.setOutput("PUT /primitiveObjects/"+xInt+"/"+xShort+"/"+xLong+"/"+xChar+"/"+xFloat+"/"+xDouble+"/"+xByte+"/"+xBoolean);
}
// Object with forString(String) method
@RestMethod(name=PUT, path="/uuid/{uuid}")
- public void doPut1(RestResponse res, UUID uuid) {
+ public void doPut1(RestResponse res, @Path("uuid") UUID uuid) {
res.setOutput("PUT /uuid/"+uuid);
}
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathVariablesResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathVariablesResource.java
index 806f516..2689b2f 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathVariablesResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/PathVariablesResource.java
@@ -29,7 +29,7 @@ public class PathVariablesResource extends BasicRestServlet {
private static final long serialVersionUID = 1L;
@RestMethod(name=GET, path="/test1/{x}/foo/{y}/bar/{z}/*")
- public StringMessage test1(@Path String x, @Path int y, @Path boolean z) {
+ public StringMessage test1(@Path("x") String x, @Path("y") int y, @Path("z") boolean z) {
return new StringMessage("x={0},y={1},z={2}", x, y, z);
}
@@ -39,12 +39,12 @@ public class PathVariablesResource extends BasicRestServlet {
}
@RestMethod(name=GET, path="/test3/{0}/foo/{1}/bar/{2}/*")
- public StringMessage test3(@Path String x, @Path int y, @Path boolean z) {
+ public StringMessage test3(@Path("0") String x, @Path("1") int y, @Path("2") boolean z) {
return new StringMessage("x={0},y={1},z={2}", x, y, z);
}
@RestMethod(name=GET, path="/test4/{2}/foo/{1}/bar/{0}/*")
- public StringMessage test4(@Path String x, @Path int y, @Path boolean z) {
+ public StringMessage test4(@Path("0") String x, @Path("1") int y, @Path("2") boolean z) {
return new StringMessage("x={0},y={1},z={2}", x, y, z);
}
}
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/TransformsResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/TransformsResource.java
index 18e6a8a..ae0f3f1 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/TransformsResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/TransformsResource.java
@@ -43,7 +43,7 @@ public class TransformsResource extends TransformsParentResource {
return a;
}
@RestMethod(name=PUT, path="/testClassTransformOverridesParentClassTransform/{a}")
- public A test1c(@Path A a) {
+ public A test1c(@Path("a") A a) {
return a;
}
@@ -60,7 +60,7 @@ public class TransformsResource extends TransformsParentResource {
return a;
}
@RestMethod(name=PUT, path="/testMethodTransformOverridesClassTransform/{a}", pojoSwaps={SwapA3.class})
- public A test2c(@Path A a) {
+ public A test2c(@Path("a") A a) {
return a;
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index cb2cc5b..3e8e096 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -4264,7 +4264,6 @@ public final class RestContext extends BeanContext {
Type[] pt = method.getGenericParameterTypes();
Annotation[][] pa = method.getParameterAnnotations();
RestMethodParam[] rp = new RestMethodParam[pt.length];
- int attrIndex = 0;
PropertyStore ps = getPropertyStore();
for (int i = 0; i < pt.length; i++) {
@@ -4288,6 +4287,8 @@ public final class RestContext extends BeanContext {
rp[i] = new RestParamDefaults.HasQueryObject(method, (HasQuery)a, t);
else if (a instanceof Body)
rp[i] = new RestParamDefaults.BodyObject(method, (Body)a, t, null);
+ else if (a instanceof Path)
+ rp[i] = new RestParamDefaults.PathObject(method, (Path)a, t, ps, rp[i]);
else if (a instanceof PathRemainder)
rp[i] = new RestParamDefaults.PathRemainderObject(method, t);
else if (a instanceof Response)
@@ -4323,6 +4324,8 @@ public final class RestContext extends BeanContext {
rp[i] = new RestParamDefaults.BodyObject(method, (Body)a, t, rp[i]);
else if (a instanceof org.apache.juneau.rest.annotation.Method)
rp[i] = new RestParamDefaults.MethodObject(method, t);
+ else if (a instanceof Path)
+ rp[i] = new RestParamDefaults.PathObject(method, (Path)a, t, ps, rp[i]);
else if (a instanceof PathRemainder)
rp[i] = new RestParamDefaults.PathRemainderObject(method, t);
else if (a instanceof Response)
@@ -4343,33 +4346,10 @@ public final class RestContext extends BeanContext {
}
if (rp[i] == null) {
-
if (isPreOrPost)
throw new RestServletException("Invalid parameter specified for method ''{0}'' at index position {1}", method, i);
-
- Path p = null;
- for (Annotation a : pa[i])
- if (a instanceof Path)
- p = (Path)a;
-
- String name = (p == null ? "" : firstNonEmpty(p.name(), p.value()));
-
- if (isEmpty(name)) {
- int idx = attrIndex++;
- String[] vars = pathPattern.getVars();
- if (vars.length <= idx)
- throw new RestServletException("Number of attribute parameters in method ''{0}'' exceeds the number of URL pattern variables.", method);
-
- // Check for {#} variables.
- String idxs = String.valueOf(idx);
- for (int j = 0; j < vars.length; j++)
- if (isNumeric(vars[j]) && vars[j].equals(idxs))
- name = vars[j];
-
- if (isEmpty(name))
- name = pathPattern.getVars()[idx];
- }
- rp[i] = new RestParamDefaults.PathParameterObject(name, p, t);
+ } else {
+ rp[i].validate();
}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodParam.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodParam.java
index f0b2bd4..ebaf289 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodParam.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodParam.java
@@ -25,6 +25,7 @@ import org.apache.juneau.dto.swagger.*;
import org.apache.juneau.http.*;
import org.apache.juneau.http.Date;
import org.apache.juneau.parser.*;
+import org.apache.juneau.rest.exception.*;
import org.apache.juneau.utils.*;
/**
@@ -204,4 +205,11 @@ public abstract class RestMethodParam {
public Type getType() {
return type;
}
+
+ /**
+ * Performs validation on the parameter.
+ *
+ * @throws InternalServerError
+ */
+ public void validate() throws InternalServerError {}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
index a4346ff..d8caed2 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
@@ -34,6 +34,7 @@ import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.exception.*;
import org.apache.juneau.utils.*;
/**
@@ -545,10 +546,12 @@ class RestParamDefaults {
// Annotated retrievers
//-------------------------------------------------------------------------------------------------------------------
- static final class PathParameterObject extends RestMethodParam {
+ static final class PathObject extends RestMethodParam {
+ private final Method method;
- protected PathParameterObject(String name, Path a, Type type) {
- super(PATH, name, type, getMetaData(a));
+ protected PathObject(Method method, Path a, Type type, PropertyStore ps, RestMethodParam existing) {
+ super(PATH, firstNonEmpty(a.name(), a.value(), existing == null ? null : existing.name), type, getMetaData(a, castOrNull(existing, PathObject.class)));
+ this.method = method;
}
@Override /* RestMethodParam */
@@ -556,10 +559,11 @@ class RestParamDefaults {
return req.getPathMatch().get(name, type);
}
- private static final ObjectMap getMetaData(Path a) {
+ private static final ObjectMap getMetaData(Path a, PathObject existing) {
+ ObjectMap om = existing == null ? new ObjectMap() : existing.metaData;
if (a == null)
- return ObjectMap.EMPTY_MAP;
- return new ObjectMap()
+ return om;
+ return om
.appendSkipEmpty("description", joinnl(a.description()))
.appendSkipEmpty("type", a.type())
.appendSkipEmpty("format", a.format())
@@ -577,6 +581,12 @@ class RestParamDefaults {
.appendSkipEmpty("example", joinnl(a.example()))
;
}
+
+ @Override /* RestMethodParqm */
+ public void validate() throws InternalServerError {
+ if (isEmpty(name))
+ throw new InternalServerError("@Path used without name or value on method ''{0}''.", method);
+ }
}
static final class BodyObject extends RestMethodParam {
@@ -623,10 +633,12 @@ class RestParamDefaults {
}
static final class HeaderObject extends RestMethodParam {
+ private final Method method;
private final HttpPartParser partParser;
protected HeaderObject(Method method, Header a, Type type, PropertyStore ps, RestMethodParam existing) {
- super(HEADER, firstNonEmpty(a.name(), a.value()), type, getMetaData(a, castOrNull(existing, HeaderObject.class)));
+ super(HEADER, firstNonEmpty(a.name(), a.value(), existing == null ? null : existing.name), type, getMetaData(a, castOrNull(existing, HeaderObject.class)));
+ this.method = method;
this.partParser = a.parser() == HttpPartParser.Null.class ? null : ClassUtils.newInstance(HttpPartParser.class, a.parser(), true, ps);
}
@@ -664,13 +676,21 @@ class RestParamDefaults {
.appendSkipEmpty("example", joinnl(a.example()))
;
}
+
+ @Override /* RestMethodParqm */
+ public void validate() throws InternalServerError {
+ if (isEmpty(name))
+ throw new InternalServerError("@Header used without name or value on method ''{0}''.", method);
+ }
}
static final class ResponseHeaderObject extends RestMethodParam {
+ private final Method method;
final HttpPartSerializer partSerializer;
protected ResponseHeaderObject(Method method, ResponseHeader a, Type type, PropertyStore ps, RestMethodParam existing) {
- super(RESPONSE_HEADER, firstNonEmpty(a.name(), a.value(), "Unknown"), type, getMetaData(a, castOrNull(existing, ResponseHeaderObject.class)));
+ super(RESPONSE_HEADER, firstNonEmpty(a.name(), a.value(), existing == null ? null : existing.name), type, getMetaData(a, castOrNull(existing, ResponseHeaderObject.class)));
+ this.method = method;
this.partSerializer = a.serializer() == HttpPartSerializer.Null.class ? null : ClassUtils.newInstance(HttpPartSerializer.class, a.serializer(), true, ps);
}
@@ -737,6 +757,12 @@ class RestParamDefaults {
}
return om;
}
+
+ @Override /* RestMethodParqm */
+ public void validate() throws InternalServerError {
+ if (isEmpty(name))
+ throw new InternalServerError("@ResponseHeader used without name or value on method ''{0}''.", method);
+ }
}
static final class ResponseObject extends RestMethodParam {
@@ -854,13 +880,15 @@ class RestParamDefaults {
}
static final class FormDataObject extends RestMethodParam {
+ private final Method method;
private final boolean multiPart;
private final HttpPartParser partParser;
+ private final Type type;
- protected FormDataObject(Method method, FormData a, Type type, PropertyStore ps, RestMethodParam existing) throws ServletException {
- super(FORM_DATA, firstNonEmpty(a.name(), a.value()), type, getMetaData(a, castOrNull(existing, FormDataObject.class)));
- if (a.multipart() && ! isCollection(type))
- throw new RestServletException("Use of multipart flag on @FormData parameter that's not an array or Collection on method ''{0}''", method);
+ protected FormDataObject(Method method, FormData a, Type type, PropertyStore ps, RestMethodParam existing) {
+ super(FORM_DATA, firstNonEmpty(a.name(), a.value(), existing == null ? null : existing.name), type, getMetaData(a, castOrNull(existing, FormDataObject.class)));
+ this.method = method;
+ this.type = type;
this.multiPart = a.multipart();
this.partParser = a.parser() == HttpPartParser.Null.class ? null : ClassUtils.newInstance(HttpPartParser.class, a.parser(), true, ps);
}
@@ -901,16 +929,26 @@ class RestParamDefaults {
.appendSkipEmpty("example", joinnl(a.example()))
;
}
+
+ @Override /* RestMethodParqm */
+ public void validate() throws InternalServerError {
+ if (isEmpty(name))
+ throw new InternalServerError("@FormData used without name or value on method ''{0}''.", method);
+ if (multiPart && ! isCollection(type))
+ throw new InternalServerError("Use of multipart flag on @FormData parameter that's not an array or Collection on method ''{0}''", method);
+ }
}
static final class QueryObject extends RestMethodParam {
private final boolean multiPart;
+ private final Type type;
+ private final Method method;
private final HttpPartParser partParser;
- protected QueryObject(Method method, Query a, Type type, PropertyStore ps, RestMethodParam existing) throws ServletException {
- super(QUERY, firstNonEmpty(a.name(), a.value()), type, getMetaData(a, castOrNull(existing, QueryObject.class)));
- if (a.multipart() && ! isCollection(type))
- throw new RestServletException("Use of multipart flag on @Query parameter that's not an array or Collection on method ''{0}''", method);
+ protected QueryObject(Method method, Query a, Type type, PropertyStore ps, RestMethodParam existing) {
+ super(QUERY, firstNonEmpty(a.name(), a.value(), existing == null ? null : existing.name), type, getMetaData(a, castOrNull(existing, QueryObject.class)));
+ this.type = type;
+ this.method = method;
this.multiPart = a.multipart();
this.partParser = a.parser() == HttpPartParser.Null.class ? null : ClassUtils.newInstance(HttpPartParser.class, a.parser(), true, ps);
}
@@ -951,7 +989,14 @@ class RestParamDefaults {
.appendSkipEmpty("example", joinnl(a.example()))
;
}
-
+
+ @Override /* RestMethodParqm */
+ public void validate() throws InternalServerError {
+ if (isEmpty(name))
+ throw new InternalServerError("@Query used without name or value on method ''{0}''.", method);
+ if (multiPart && ! isCollection(type))
+ throw new InternalServerError("Use of multipart flag on @Query parameter that's not an array or Collection on method ''{0}''", method);
+ }
}
static final class HasFormDataObject extends RestMethodParam {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Path.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Path.java
index 1e304f7..3e4cdf6 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Path.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Path.java
@@ -28,43 +28,7 @@ import org.apache.juneau.rest.*;
* <p class='bcode'>
* <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/myurl/{foo}/{bar}/{baz}/*"</js>)
* <jk>public void</jk> doGet(RestRequest req, RestResponse res,
- * <ja>@Path</ja> String foo, <ja>@Path</ja> <jk>int</jk> bar, <ja>@Path</ja> UUID baz) {
- * ...
- * }
- * </p>
- *
- * <p>
- * The <ja>@Path</ja> annotation is optional if the parameters are specified immediately following the
- * <code>RestRequest</code> and <code>RestResponse</code> parameters, and are specified in the same order as the
- * variables in the URL path pattern.
- * The following example is equivalent to the previous example.
- * <p class='bcode'>
- * <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/myurl/{foo}/{bar}/{baz}/*"</js>)
- * <jk>public void</jk> doGet(RestRequest req, RestResponse res,
- * String foo, <jk>int</jk> bar, UUID baz) {
- * ...
- * }
- * </p>
- *
- * <p>
- * If the order of parameters is not the default order shown above, the attribute names must be specified (since
- * parameter names are lost during compilation).
- * The following example is equivalent to the previous example, except the parameter order has been switched, requiring
- * the use of the <ja>@Path</ja> annotations.
- * <p class='bcode'>
- * <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/myurl/{foo}/{bar}/{baz}/*"</js>)
- * <jk>public void</jk> doGet(RestRequest req, RestResponse res,
- * <ja>@Path</ja>(<js>"baz"</js>) UUID baz, <ja>@Path</ja>(<js>"foo"</js>) String foo, <ja>@Path</ja>(<js>"bar"</js>) <jk>int</jk> bar) {
- * ...
- * }
- * </p>
- *
- * <p>
- * You can also use <code>{#}</code> notation to specify path parameters without specifying names.
- * <p class='bcode'>
- * <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/myurl/{0}/{1}/{2}/*"</js>)
- * <jk>public void</jk> doGet(RestRequest req, RestResponse res,
- * <ja>@Path</ja> String foo, <ja>@Path</ja> <jk>int</jk> bar, <ja>@Path</ja> UUID baz) {
+ * <ja>@Path</ja>(<js>"foo"</js>) String foo, <ja>@Path</ja>(<js>"bar"</js>) <jk>int</jk> bar, <ja>@Path</ja>(<js>"baz"</js>) UUID baz) {
* ...
* }
* </p>
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
index 933ec19..6a7b997 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
@@ -5067,23 +5067,222 @@ public class BasicRestInfoProviderTest {
@RestResource()
public static class SA {
-// String name() default "";
-// String value() default "";
-// String[] description() default {};
-// String type() default "";
-// String format() default "";
-// String pattern() default "";
-// String maximum() default "";
-// String minimum() default "";
-// String multipleOf() default "";
-// String maxLength() default "";
-// String minLength() default "";
-// String allowEmptyValue() default "";
-// String exclusiveMaximum() default "";
-// String exclusiveMinimum() default "";
-// String[] schema() default {};
-// String[] _enum() default {};
-// String[] example() default {};
+
+ @Path(name="P")
+ public static class SA01h {}
+
+ @RestMethod(name=GET,path="/name/{P}")
+ public Foo sa01(SA01h h) { return null; }
+
+ // String value() default "";
+ @Path("P")
+ public static class SA02h {}
+
+ @RestMethod(name=GET,path="/value/{P}")
+ public Foo sa02(SA02h h) { return null; }
+
+ @Path(name="P", description="a")
+ public static class SA03h {}
+
+ @RestMethod(name=GET,path="/description1/{P}")
+ public Foo sa03(SA03h h) { return null; }
+
+ @Path(name="P", description={"a","b"})
+ public static class SA04h {}
+
+ @RestMethod(name=GET,path="/description2/{P}")
+ public Foo sa04(SA04h h) { return null; }
+
+ @Path(name="P", type="a")
+ public static class SA05h {}
+
+ @RestMethod(name=GET,path="/type/{P}")
+ public Foo sa05(SA05h h) { return null; }
+
+ @Path(name="P", format="a")
+ public static class SA06h {}
+
+ @RestMethod(name=GET,path="/format/{P}")
+ public Foo sa06(SA06h h) { return null; }
+
+ @Path(name="P", pattern="a")
+ public static class SA07h {}
+
+ @RestMethod(name=GET,path="/pattern/{P}")
+ public Foo sa07(SA07h h) { return null; }
+
+ @Path(name="P", maximum="1")
+ public static class SA08h {}
+
+ @RestMethod(name=GET,path="/maximum/{P}")
+ public Foo sa08(SA08h h) { return null; }
+
+ @Path(name="P", minimum="1")
+ public static class SA09h {}
+
+ @RestMethod(name=GET,path="/minimum/{P}")
+ public Foo sa09(SA09h h) { return null; }
+
+ @Path(name="P", multipleOf="1")
+ public static class SA10h {}
+
+ @RestMethod(name=GET,path="/multipleOf/{P}")
+ public Foo sa10(SA10h h) { return null; }
+
+ @Path(name="P", maxLength="1")
+ public static class SA11h {}
+
+ @RestMethod(name=GET,path="/maxLength/{P}")
+ public Foo sa11(SA11h h) { return null; }
+
+ @Path(name="P", minLength="1")
+ public static class SA12h {}
+
+ @RestMethod(name=GET,path="/minLength/{P}")
+ public Foo sa12(SA12h h) { return null; }
+
+ @Path(name="P", allowEmptyValue="true")
+ public static class SA13h {}
+
+ @RestMethod(name=GET,path="/allowEmptyValue/{P}")
+ public Foo sa13(SA13h h) { return null; }
+
+ @Path(name="P", exclusiveMaximum="true")
+ public static class SA14h {}
+
+ @RestMethod(name=GET,path="/exclusiveMaximum/{P}")
+ public Foo sa14(SA14h h) { return null; }
+
+ @Path(name="P", exclusiveMinimum="true")
+ public static class SA15h {}
+
+ @RestMethod(name=GET,path="/exclusiveMinimum/{P}")
+ public Foo sa15(SA15h h) { return null; }
+
+ @Path(name="P", schema=" {type:'a'} ")
+ public static class SA16h {}
+
+ @RestMethod(name=GET,path="/schema1/{P}")
+ public Foo sa16(SA16h h) { return null; }
+
+ @Path(name="P", schema= {" type:'b' "})
+ public static class SA17h {}
+
+ @RestMethod(name=GET,path="/schema2/{P}")
+ public Foo sa17(SA17h h) { return null; }
+
+ @Path(name="P", _enum="a,b")
+ public static class SA18h {}
+
+ @RestMethod(name=GET,path="/_enum1/{P}")
+ public Foo sa18(SA18h h) { return null; }
+
+ @Path(name="P", _enum={" ['a','b'] "})
+ public static class SA19h {}
+
+ @RestMethod(name=GET,path="/_enum2/{P}")
+ public Foo sa19(SA19h h) { return null; }
+
+ @Path(name="P", example="'a'")
+ public static class SA20h {
+ public SA20h(String value) {}
+ }
+
+ @RestMethod(name=GET,path="/example1/{P}")
+ public Foo sa20(SA20h h) { return null; }
+
+ @Path(name="P", example={" {f1:'a'} "})
+ public static class SA21h {
+ public String f1;
+ }
+
+ @RestMethod(name=GET,path="/example2/{P}")
+ public Foo sa21(SA21h h) { return null; }
+ }
+
+ @Test
+ public void sa01_Path_onPojo_name() throws Exception {
+ assertEquals("P", getSwagger(new SA()).getPaths().get("/name/{P}").get("get").getParameter("path", "P").getName());
+ }
+ @Test
+ public void sa02_Path_onPojo_value() throws Exception {
+ assertEquals("P", getSwagger(new SA()).getPaths().get("/value/{P}").get("get").getParameter("path", "P").getName());
+ }
+ @Test
+ public void sa03_Path_onPojo_description() throws Exception {
+ assertEquals("a", getSwagger(new SA()).getPaths().get("/description1/{P}").get("get").getParameter("path", "P").getDescription());
+ }
+ @Test
+ public void sa04_Path_onPojo_description() throws Exception {
+ assertEquals("a\nb", getSwagger(new SA()).getPaths().get("/description2/{P}").get("get").getParameter("path", "P").getDescription());
+ }
+ @Test
+ public void sa05_Path_onPojo_type() throws Exception {
+ assertEquals("a", getSwagger(new SA()).getPaths().get("/type/{P}").get("get").getParameter("path", "P").getType());
+ }
+ @Test
+ public void sa06_Path_onPojo_format() throws Exception {
+ assertEquals("a", getSwagger(new SA()).getPaths().get("/format/{P}").get("get").getParameter("path", "P").getFormat());
+ }
+ @Test
+ public void sa07_Path_onPojo_pattern() throws Exception {
+ assertEquals("a", getSwagger(new SA()).getPaths().get("/pattern/{P}").get("get").getParameter("path", "P").getPattern());
+ }
+ @Test
+ public void sa08_Path_onPojo_maximum() throws Exception {
+ assertObjectEquals("1", getSwagger(new SA()).getPaths().get("/maximum/{P}").get("get").getParameter("path", "P").getMaximum());
+ }
+ @Test
+ public void sa09_Path_onPojo_minimum() throws Exception {
+ assertObjectEquals("1", getSwagger(new SA()).getPaths().get("/minimum/{P}").get("get").getParameter("path", "P").getMinimum());
+ }
+ @Test
+ public void sa10_Path_onPojo_multipleOf() throws Exception {
+ assertObjectEquals("1", getSwagger(new SA()).getPaths().get("/multipleOf/{P}").get("get").getParameter("path", "P").getMultipleOf());
+ }
+ @Test
+ public void sa11_Path_onPojo_maxLength() throws Exception {
+ assertObjectEquals("1", getSwagger(new SA()).getPaths().get("/maxLength/{P}").get("get").getParameter("path", "P").getMaxLength());
+ }
+ @Test
+ public void sa12_Path_onPojo_minLength() throws Exception {
+ assertObjectEquals("1", getSwagger(new SA()).getPaths().get("/minLength/{P}").get("get").getParameter("path", "P").getMinLength());
+ }
+ @Test
+ public void sa13_Path_onPojo_allowEmptyValue() throws Exception {
+ assertObjectEquals("true", getSwagger(new SA()).getPaths().get("/allowEmptyValue/{P}").get("get").getParameter("path", "P").getAllowEmptyValue());
+ }
+ @Test
+ public void sa14_Path_onPojo_exclusiveMaximum() throws Exception {
+ assertObjectEquals("true", getSwagger(new SA()).getPaths().get("/exclusiveMaximum/{P}").get("get").getParameter("path", "P").getExclusiveMaximum());
+ }
+ @Test
+ public void sa15_Path_onPojo_exclusiveMinimum() throws Exception {
+ assertObjectEquals("true", getSwagger(new SA()).getPaths().get("/exclusiveMinimum/{P}").get("get").getParameter("path", "P").getExclusiveMinimum());
+ }
+ @Test
+ public void sa16_Path_onPojo_schema1() throws Exception {
+ assertObjectEquals("{type:'a'}", getSwagger(new SA()).getPaths().get("/schema1/{P}").get("get").getParameter("path", "P").getSchema());
+ }
+ @Test
+ public void sa17_Path_onPojo_schema2() throws Exception {
+ assertObjectEquals("{type:'b'}", getSwagger(new SA()).getPaths().get("/schema2/{P}").get("get").getParameter("path", "P").getSchema());
+ }
+ @Test
+ public void sa18_Path_onPojo__enum1() throws Exception {
+ assertObjectEquals("['a','b']", getSwagger(new SA()).getPaths().get("/_enum1/{P}").get("get").getParameter("path", "P").getEnum());
+ }
+ @Test
+ public void sa19_Path_onPojo__enum2() throws Exception {
+ assertObjectEquals("['a','b']", getSwagger(new SA()).getPaths().get("/_enum2/{P}").get("get").getParameter("path", "P").getEnum());
+ }
+ @Test
+ public void sa20_Path_onPojo_example1() throws Exception {
+ assertObjectEquals("'a'", getSwagger(new SA()).getPaths().get("/example1/{P}").get("get").getParameter("path", "P").getExample());
+ }
+ @Test
+ public void sa21_Path_onPojo_example2() throws Exception {
+ assertObjectEquals("{f1:'a'}", getSwagger(new SA()).getPaths().get("/example2/{P}").get("get").getParameter("path", "P").getExample());
}
//-----------------------------------------------------------------------------------------------------------------
--
To stop receiving notification emails like this one, please contact
jamesbognar@apache.org.