All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.rest.annotation.RestMethod Maven / Gradle / Ivy

There is a newer version: 9.0.1
Show newest version
// ***************************************************************************************************************************
// * 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.annotation;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

import java.lang.annotation.*;

import org.apache.juneau.*;
import org.apache.juneau.encoders.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.remoteable.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.serializer.*;

/**
 * Identifies a REST Java method on a {@link RestServlet} implementation class.
 * 

* Refer to org.apache.juneau.rest doc for information on using this class. */ @Documented @Target(METHOD) @Retention(RUNTIME) @Inherited public @interface RestMethod { /** * REST method name. * *

* Typically "GET", "PUT", "POST", "DELETE", or "OPTIONS". * *

* Method names are case-insensitive (always folded to upper-case). * *

* Note that you can use {@link org.apache.juneau.http.HttpMethodName} for constant values. * *

* Besides the standard HTTP method names, the following can also be specified: *

    *
  • * "*" * - Denotes any method. *
    Use this if you want to capture any HTTP methods in a single Java method. *
    The {@link Method @Method} annotation and/or {@link RestRequest#getMethod()} method can be used to * distinguish the actual HTTP method name. *
  • * "" * - Auto-detect. *
    The method name is determined based on the Java method name. *
    For example, if the method is doPost(...), then the method name is automatically detected * as "POST". *
    Otherwise, defaults to "GET". *
  • * "PROXY" * - Remote-proxy interface. *
    This denotes a Java method that returns an object (usually an interface, often annotated with the * {@link Remoteable @Remoteable} annotation) to be used as a remote proxy using * RestClient.getRemoteableProxy(Class<T> interfaceClass, String url). *
    This allows you to construct client-side interface proxies using REST as a transport medium. *
    Conceptually, this is simply a fancy POST against the url "/{path}/{javaMethodName}" * where the arguments are marshalled from the client to the server as an HTTP body containing an array of * objects, passed to the method as arguments, and then the resulting object is marshalled back to the client. *
  • * Anything else * - Overloaded non-HTTP-standard names that are passed in through a &method=methodName URL * parameter. *
*/ String name() default ""; /** * Optional path pattern for the specified method. * *

* Appending "/*" to the end of the path pattern will make it match any remainder too. *
Not appending "/*" to the end of the pattern will cause a 404 (Not found) error to occur if the exact * pattern is not found. * *

* The path can contain variables that get resolved to {@link Path @Path} parameters: *

* // Example 1 * @RestMethod(name=GET, path="/myurl/{foo}/{bar}/{baz}/*") * * // Example 2 * @RestMethod(name=GET, path="/myurl/{0}/{1}/{2}/*") *

* *

* Refer to {@link Path @Path} on how path variables get resolved. */ String path() default "/*"; /** * URL path pattern priority. * *

* To force path patterns to be checked before other path patterns, use a higher priority number. * *

* By default, it's 0, which means it will use an internal heuristic to determine a best match. */ int priority() default 0; /** * Method guards. * *

* Associates one or more {@link RestGuard RestGuards} with a method call. * These guards get called immediately before execution of the REST method. * *

* Typically, guards will be used for permissions checking on the user making the request, but it can also be used * for other purposes like pre-call validation of a request. */ Class[] guards() default {}; /** * Method response converters. * *

* Associates one or more {@link RestConverter RestConverters} with a method call. * These converters get called immediately after execution of the REST method in the same order specified in the * annotation. * *

* Can be used for performing post-processing on the response object before serialization. * *

* Default converters are available in the org.apache.juneau.rest.converters package. */ Class[] converters() default {}; /** * Method matchers. * *

* Associates one more more {@link RestMatcher RestMatchers} with this method. * *

* Matchers are used to allow multiple Java methods to handle requests assigned to the same URL path pattern, but * differing based on some request attribute, such as a specific header value. * *

* See {@link RestMatcher} for details. */ Class[] matchers() default {}; /** * Overrides the list of serializers assigned at the method level. * *

* Use this annotation when the list of serializers assigned to a method differs from the list of serializers * assigned at the servlet level. * *

* To append to the list of serializers assigned at the servlet level, use * serializersInherit=SERIALIZERS. * *

* public class MyResource extends RestServlet { * * @RestMethod( * name=GET, * path="/foo", * serializers=MySpecialSerializer.class, * serializersInherit=SERIALIZERS * ) * public Object doGetWithSpecialAcceptType() { * // Handle request for special Accept type * } * } *

*/ Class[] serializers() default {}; /** * Used in conjunction with {@link #serializers()} to identify what class-level settings are inherited by the method * serializer group. * *

* Possible values: *

    *
  • {@link Inherit#SERIALIZERS} - Inherit class-level serializers. *
  • {@link Inherit#PROPERTIES} - Inherit class-level properties. *
  • {@link Inherit#TRANSFORMS} - Inherit class-level transforms. *
* *

* For example, to inherit all serializers, properties, and transforms from the servlet class: *

* @RestMethod( * path="/foo", * serializers=MySpecialSerializer.class, * serializersInherit={SERIALIZERS,PROPERTIES,TRANSFORMS} * ) *

*/ Inherit[] serializersInherit() default {}; /** * Overrides the list of parsers assigned at the method level. * *

* Use this annotation when the list of parsers assigned to a method differs from the list of parsers assigned at * the servlet level. * *

* To append to the list of serializers assigned at the servlet level, use * serializersInherit=SERIALIZERS. * *

* public class MyResource extends RestServlet { * * @RestMethod( * name=PUT, * path="/foo", * parsers=MySpecialParser.class, * parsersInherit=PARSERS * ) * public Object doGetWithSpecialAcceptType() { * // Handle request for special Accept type * } * } *

*/ Class[] parsers() default {}; /** * Used in conjunction with {@link #parsers()} to identify what class-level settings are inherited by the method * parser group. * *

* Possible values: *

    *
  • {@link Inherit#PARSERS} - Inherit class-level parsers. *
  • {@link Inherit#PROPERTIES} - Inherit class-level properties. *
  • {@link Inherit#TRANSFORMS} - Inherit class-level transforms. *
* *

* For example, to inherit all parsers, properties, and transforms from the servlet class: *

* @RestMethod( * path="/foo", * parsers=MySpecialParser.class, * parsersInherit={PARSERS,PROPERTIES,TRANSFORMS} * ) *

*/ Inherit[] parsersInherit() default {}; /** * Appends to the list of {@link Encoder encoders} specified on the servlet. * *

* Use this annotation when the list of encoders assigned to a method differs from the list of encoders assigned at * the servlet level. * *

* These can be used to enable various kinds of compression (e.g. "gzip") on requests and responses. * *

* public class MyResource extends RestServlet { * * @RestMethod( * name=PUT, * path="/foo", * encoders={GzipEncoder.class} * ) * public Object doGetWithSpecialEncoding() { * // Handle request with special encoding * } * } *

* *

* If you want to OVERRIDE the set of encoders specified by the servlet, combine this annotation with * @RestMethod(inheritEncoders=false). */ Class[] encoders() default {}; /** * Specifies whether the method should inherit encoders from the servlet. */ boolean inheritEncoders() default true; /** * Same as {@link RestResource#properties()}, except defines property values by default when this method is called. * *

* This is equivalent to simply calling res.addProperties() in the Java method, but is provided for * convenience. */ Property[] properties() default {}; /** * Shortcut for setting {@link #properties()} of simple boolean types. * *

* Setting a flag is equivalent to setting the same property to "true". */ String[] flags() default {}; /** * Appends the specified bean filters to all serializers and parsers used by this method. */ Class[] beanFilters() default {}; /** * Appends the specified POJO swaps to all serializers and parsers used by this method. */ Class[] pojoSwaps() default {}; /** * Shortcut for specifying the {@link BeanContext#BEAN_includeProperties} property on all serializers. * *

* The typical use case is when you're rendering summary and details views of the same bean in a resource and * you want to expose or hide specific properties depending on the level of detail you want. * *

* In the example below, our 'summary' view is a list of beans where we only want to show the ID property, * and our detail view is a single bean where we want to expose different fields: *

* // Our bean * public class MyBean { * * // Summary properties * @Html(link="servlet:/mybeans/{id}") * public String id; * * // Detail properties * public String a, b; * } * * // Only render "id" property. * @RestMethod(name=GET, path="/mybeans", bpi="MyBean: id") * public List<MyBean> getBeanSummary(); * * // Only render "a" and "b" properties. * @RestMethod(name=GET, path="/mybeans/{id}", bpi="MyBean: a,b") * public MyBean getBeanDetails(@Path String id); *

* *

* The format of each value is: "Key: comma-delimited-tokens". *
Keys can be fully-qualified or short class names or "*" to represent all classes. *
Values are comma-delimited lists of bean property names. *
Properties apply to specified class and all subclasses. * *

* Semicolons can be used as an additional separator for multiple values: *

* // Equivalent * bpi={"Bean1: foo","Bean2: bar,baz"} * bpi="Bean1: foo; Bean2: bar,baz" *

*/ String[] bpi() default {}; /** * Shortcut for specifying the {@link BeanContext#BEAN_excludeProperties} property on all serializers. * *

* Same as {@link #bpi()} except you specify a list of bean property names that you want to exclude from * serialization. * *

* In the example below, our 'summary' view is a list of beans where we want to exclude some properties: *

* // Our bean * public class MyBean { * * // Summary properties * @Html(link="servlet:/mybeans/{id}") * public String id; * * // Detail properties * public String a, b; * } * * // Don't show "a" and "b" properties. * @RestMethod(name=GET, path="/mybeans", bpx="MyBean: a,b") * public List<MyBean> getBeanSummary(); * * // Render all properties. * @RestMethod(name=GET, path="/mybeans/{id}") * public MyBean getBeanDetails(@Path String id); *

* *

* The format of each value is: "Key: comma-delimited-tokens". *
Keys can be fully-qualified or short class names or "*" to represent all classes. *
Values are comma-delimited lists of bean property names. *
Properties apply to specified class and all subclasses. * *

* Semicolons can be used as an additional separator for multiple values: *

* // Equivalent * bpx={"Bean1: foo","Bean2: bar,baz"} * bpx="Bean1: foo; Bean2: bar,baz" *

*/ String[] bpx() default {}; /** * Specifies default values for request headers. * *

* Strings are of the format "Header-Name: header-value". * *

* Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request. * *

* The most useful reason for this annotation is to provide a default Accept header when one is not * specified so that a particular default {@link Serializer} is picked. * *

* Only one header value can be specified per entry (i.e. it's not a delimited list of header entries). * *

* Header values specified at the method level override header values specified at the servlet level. * *

Example:
*

* // Assume "text/json" Accept value when Accept not specified * @RestMethod(name=GET, path="/*", defaultRequestHeaders={"Accept: text/json"}) * public String doGet() { * ... * } *

* *

* You can use either ':' or '=' as the key/value delimiter. * Key and value is trimmed of whitespace. */ String[] defaultRequestHeaders() default {}; /** * Specifies default values for query parameters. * *

* Strings are of the format "name=value". * *

* Affects values returned by {@link RestRequest#getQuery(String)} when the parameter is not present on the request. * *

Example:
*

* @RestMethod(name=GET, path="/*", defaultQuery={"foo=bar"}) * public String doGet(@Query("foo") String foo) { * ... * } *

* *

* You can use either ':' or '=' as the key/value delimiter. * Key and value is trimmed of whitespace. */ String[] defaultQuery() default {}; /** * Specifies default values for form-data parameters. * *

* Strings are of the format "name=value". * *

* Affects values returned by {@link RestRequest#getFormData(String)} when the parameter is not present on the * request. * *

Example:
*

* @RestMethod(name=POST, path="/*", defaultFormData={"foo=bar"}) * public String doGet(@FormData("foo") String foo) { * ... * } *

* *

* You can use either ':' or '=' as the key/value delimiter. * Key and value is trimmed of whitespace. */ String[] defaultFormData() default {}; /** * Optional summary for the exposed API. * *

* This summary is used in the following locations: *

    *
  • * The value returned by {@link RestRequest#getMethodSummary()}. *
  • * The "$R{methodSummary}" variable. *
  • * The summary of the method in the Swagger page. *
* *

* The default value pulls the description from the (className.?)[javaMethodName].summary entry in the * servlet resource bundle. (e.g. "MyClass.myMethod.summary = foo" or "myMethod.summary = foo"). * *

* This field can contain variables (e.g. "$L{my.localized.variable}"). *
See {@link RestContext#getVarResolver()} for the list of supported variables. * *

* Corresponds to the swagger field /paths/{path}/{method}/summary. */ String summary() default ""; /** * Optional description for the exposed API. * *

* This description is used in the following locations: *

    *
  • * The value returned by {@link RestRequest#getMethodDescription()}. *
  • * The "$R{methodDescription}" variable. *
  • * The description of the method in the Swagger page. *
* *

* The default value pulls the description from the (className.?)[javaMethodName].description entry in * the servlet resource bundle. (e.g. "MyClass.myMethod.description = foo" or * "myMethod.description = foo"). * *

* This field can contain variables (e.g. "$L{my.localized.variable}"). *
See {@link RestContext#getVarResolver()} for the list of supported variables. * *

* Corresponds to the swagger field /paths/{path}/{method}/description. */ String description() default ""; /** * Specifies whether this method can be called based on the client version. * *

* The client version is identified via the HTTP request header identified by * {@link RestResource#clientVersionHeader()} which by default is "X-Client-Version". * *

* This is a specialized kind of {@link RestMatcher} that allows you to invoke different Java methods for the same * method/path based on the client version. * *

* The format of the client version range is similar to that of OSGi versions. * *

* In the following example, the Java methods are mapped to the same HTTP method and URL "/foobar". *

* // Call this method if X-Client-Version is at least 2.0. * // Note that this also matches 2.0.1. * @RestMethod(name=GET, path="/foobar", clientVersion="2.0") * public Object method1() { * ... * } * * // Call this method if X-Client-Version is at least 1.1, but less than 2.0. * @RestMethod(name=GET, path="/foobar", clientVersion="[1.1,2.0)") * public Object method2() { * ... * } * * // Call this method if X-Client-Version is less than 1.1. * @RestMethod(name=GET, path="/foobar", clientVersion="[0,1.1)") * public Object method3() { * ... * } *

* *

* It's common to combine the client version with transforms that will convert new POJOs into older POJOs for * backwards compatibility. *

* // Call this method if X-Client-Version is at least 2.0. * @RestMethod(name=GET, path="/foobar", clientVersion="2.0") * public NewPojo newMethod() { * ... * } * * // Call this method if X-Client-Version is at least 1.1, but less than 2.0. * @RestMethod(name=GET, path="/foobar", clientVersion="[1.1,2.0)", transforms={NewToOldPojoSwap.class}) * public NewPojo oldMethod() { * return newMethod() * } * *

* Note that in the previous example, we're returning the exact same POJO, but using a transform to convert it into * an older form. * The old method could also just return back a completely different object. * The range can be any of the following: *

    *
  • "[0,1.0)" = Less than 1.0. 1.0 and 1.0.0 does not match. *
  • "[0,1.0]" = Less than or equal to 1.0. Note that 1.0.1 will match. *
  • "1.0" = At least 1.0. 1.0 and 2.0 will match. *
*/ String clientVersion() default ""; /** * Provides swagger-specific metadata on this method. */ MethodSwagger swagger() default @MethodSwagger; /** * Provides HTML-doc-specific metadata on this method. * *

* Information provided here overrides information provided in the servlet-level annotation. */ HtmlDoc htmldoc() default @HtmlDoc; /** * Default character encoding. * *

* The default character encoding for the request and response if not specified on the request. * *

    *
  • String value. *
  • Defaults to system property "juneau.defaultCharset", or "utf-8" if not specified. *
  • Can contain variables. *
  • Overrides the value at the class level via {@link RestResource#defaultCharset() @RestResource.defaultCharset()}. *
*/ String defaultCharset() default ""; /** * Expected format of request parameters. * * Possible values: *
    *
  • * "UON" - URL-Encoded Object Notation. *
    This notation allows for request parameters to contain arbitrarily complex POJOs. *
  • * "PLAIN" - Plain text. *
    This treats request parameters as plain text. *
    Only POJOs directly convertible from Strings can be represented in parameters when using this * mode. *
* *

* Note that the parameter value "(foo)" is interpreted as "(foo)" when using plain mode, but * "foo" when using UON mode. * *

* The format can also be specified per-parameter using the {@link FormData#format() @FormData.format()} and * {@link Query#format() @Query.format()} annotations. * *

    *
  • String value. *
  • Defaults to system property "juneau.paramFormat", or "UON" if not specified. *
  • Can contain variables. *
  • Overrides the value at the class level via {@link RestResource#paramFormat() @RestResource.paramFormat()}. *
*/ String paramFormat() default ""; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy