| <!-- |
| /*************************************************************************************************************************** |
| * 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. |
| ***************************************************************************************************************************/ |
| --> |
| |
| @RestMethod(path) |
| |
| <p> |
| The {@link oajr.annotation.RestMethod#path() @RestMethod(path)} annotation allows |
| you to define URL path patterns to match against. |
| These patterns can contain variables of the form <l>"{xxx}"</l> that can be passed in directly to the |
| Java methods as extra parameters. |
| </p> |
| <p> |
| In the following example, 3 separate GET request handlers are defined with different path patterns. |
| Note how the variables are passed in as additional arguments on the method, and how those arguments are |
| automatically converted to the specified class type... |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Default method</jc> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>) |
| <jk>public void</jk> doGetDefault() { |
| ... |
| } |
| |
| <jc>// Method with path pattern</jc> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/xxx"</js>) |
| <jk>public void</jk> doGetNoArgs(...) { |
| ... |
| } |
| |
| <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>(<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> |
| <p> |
| By default, path patterns are matched using a best-match heuristic. |
| When overlaps occur, URLs are matched from most-specific to most-general order: |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Try first </jc> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foo/bar"</js>) |
| <jk>public void</jk> method1() { |
| ... |
| } |
| |
| <jc>// Try second</jc> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foo/{bar}"</js>) |
| <jk>public void</jk> method2(...) { |
| ... |
| } |
| |
| <jc>// Try third</jc> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foo/*"</js>) |
| <jk>public void</jk> method3(...) { |
| ... |
| } |
| |
| <jc>// Try last</jc> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>) |
| <jk>public void</jk> method4(...) { |
| ... |
| } |
| </p> |
| <p> |
| The match heuristic behavior can be overridden by the |
| {@link oajr.annotation.RestMethod#priority() @RestMethod(priority)} annotation |
| property. |
| However, in practice this is almost never needed. |
| </p> |
| <p> |
| Paths that end with <js>"/*"</js> will do a prefix match on the incoming URL. |
| Any remainder after the match can be accessed through |
| {@link oajr.RequestPath#getRemainder()} or parameters with the |
| <c><ja>@Path</ja>(<js>"/*"</js>)</c> annotation. |
| On the other hand, paths that don't end with <js>"/*"</js> (e.g. <js>"/"</js> or <js>"/foo"</js>) will |
| require an exact URL match, and if any remainder exists, a 404 (not found) error will be thrown. |
| </p> |
| <p> |
| The following example shows the distinction. |
| </p> |
| <p class='bpcode w800'> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>) |
| <jk>public void</jk> doGet(<ja>@Path</ja>(<js>"/*"</js>) String remainder) { |
| <jc>// URL path pattern can have remainder accessible through req.getRemainder().</jc> |
| } |
| |
| <ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/"</js>) |
| <jk>public void</jk> doPut() { |
| <jc>// URL path pattern must match exactly and will cause a 404 error if a remainder exists.</jc> |
| } |
| </p> |
| <p> |
| Annotations are provided for easy access to URL parameters with automatic conversion to any {@doc PojoCategories parsable} type. |
| For example, the following example can process the URL <l>"/urlWithParams?foo=foo&bar=[1,2,3]&baz=067e6162-3b6f-4ae2-a171-2470b63dff00"</l>... |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Example GET request with access to query parameters</jc> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/urlWithParams"</js>) |
| <jk>public</jk> String doGetWithParams(<ja>@Query</ja>(<js>"foo"</js>) String foo, <ja>@Query</ja>(<js>"bar"</js>) <jk>int</jk> bar, <ja>@Query</ja>(<js>"baz"</js>) UUID baz) <jk>throws</jk> Exception { |
| <jk>return</jk> <js>"GET /urlWithParams?foo="</js>+foo+<js>"&bar="</js>+bar+<js>"&baz="</js>+baz; |
| } |
| </p> |
| <ul class='seealso'> |
| <li class='jf'>{@link oajr.RestContext#REST_path} |
| <li class='ja'>{@link oaj.http.annotation.Path} |
| <li class='jc'>{@link oajr.RequestPath} |
| </ul> |