Skip to main content

Java Method Parameters

Java methods can contain any of the following parameters in any order:

Parameters based on class types:Request objects:AsyncContext CookieList DispatcherType HttpPartParserSession HttpPartSerializerSession HttpServletRequest InputStream InputStreamParser Locale Messages Parser Principal Reader ReaderParser RequestAttributes RequestContent RequestFormParamList RequestHeaderList RequestPathParamList RequestQueryParamList ResourceBundle RestRequest ServletInputStream Swagger TimeZone UriContext UriResolver VarResolverSessionResponse objects:HttpServletResponse OutputStream RestResponse ServletOutputStream WriterSession objects:HttpSession RestSession UrlPath UrlPathMatch BeanStore RestOpSessionParsed request header values:Accept AcceptCharset AcceptEncoding AcceptLanguage AcceptRanges Authorization CacheControl ClientVersion Connection ContentDisposition ContentEncoding ContentLength ContentType Date Debug Expect Forwarded From Host IfMatch IfModifiedSince IfNoneMatch IfRange IfUnmodifiedSince MaxForwards NoTrace Origin Pragma ProxyAuthorization Range Referer TE Thrown Upgrade UserAgent WarningContext values:MarshallingContext Config EncoderSet FileFinder JsonSchemaGenerator Logger MethodExecStore ParserSet RestChildren RestContext RestContextStats RestOpContext RestOperations SerializerSet StaticFiles ThrownStoreAnnotated parameters:Attr Content Path FormData HasFormData Query HasQuery Header StatusCode Method Request Response

In Spring Boot environments, any available Spring Beans can also be passed in as parameters.

Example
@RestGet("/example1/{a1}/{a2}/{a3}/*")
public String doGetExample1(
RestRequest req,
RestResponse res,
@Method String method,
@Path("a1") String a1,
@Path("a2") int a2,
@Path("a3") UUID a3,
@Query("p1") int p1,
@Query("p2") String p2,
@Query("p3") UUID p3,
@HasQuery("p3") boolean hasP3,
@Path("/*") String remainder,
@Header("Accept-Language") String lang,
@Header("Accept") String accept,
@Header("DNT") int doNotTrack,
RequestAttributes attributes,
ResourceBundle nls
) {
// Do something with all of those
}

Additional parameter types can be defined via the annotation Rest.restOpArgs() or by supplying a named bean via @Bean.

Example
@Rest(
restOpArgs={ MyOpArg.class } // Option #1 - Via annotation
)
public class MyResource extends BasicRestResource {

}

@Attr and @Method​

Two annotations in org.apache.juneau.rest.server are specific to operation parameters.

@Attr retrieves a value from the request attributes map. Its name (or value) selects the attribute. A blank name on a Map, NameValuePairs or bean parameter is equivalent to "*" and returns all attributes as name/value pairs. A parser can be supplied to override the part parser used to convert the attribute value.

Example
@RestGet
public Person getPerson(@Attr("ETag") UUID etag) {...}

// Equivalent to:
@RestGet
public Person getPerson(RestRequest req) {
UUID etag = req.getAttributes().get(UUID.class, "ETag");
...
}

@Method supplies the HTTP method name as a String. It is mainly useful on operations declared with method="*", which match every HTTP method.

Example
@RestOp(method="*")
public void doAnything(RestRequest req, RestResponse res, @Method String method) {
// method is "GET", "POST", etc.
}

Parameter resolver matrix​

Each parameter of an operation method is matched to a RestOpArg resolver when the resource starts. Resolvers are tried in order and the first one that recognizes the parameter wins. A parameter that no resolver can handle causes an error at startup (Could not resolve parameter N on method ...).

The framework's default resolver list is shown below in the order in which it is consulted. Resolvers registered through @Rest(restOpArgs) are placed ahead of this list (child class entries first, then parent entries), so they can override the defaults. A @Bean method returning a RestOpArgList replaces the entire list.

#ResolverMatches a parameter that is...Resolved value
1AttributeArgannotated with @AttrRequest attribute (converted to the parameter type).
2AuthArgannotated with @Auth, or any Principal subtypeThe principal stored on the request by an upstream authentication guard (null if none).
3ContentArgannotated with @ContentThe request body, parsed to the parameter type.
4FormDataArgannotated with @FormDataForm-data parameter.
5HasFormDataArgannotated with @HasFormDataboolean: whether the form-data parameter is present.
6HasQueryArgannotated with @HasQueryboolean: whether the query parameter is present.
7HeaderArgannotated with @Header (and not a Holder), or a typed header class that has a static NAME field (e.g. Accept, Host)Request header.
8HttpServletRequestArgsAsyncContext, CookieList, DispatcherType, HttpServletRequest, PrincipalServlet request facets.
9HttpServletResponseArgsHttpServletResponseThe servlet response.
10HttpSessionArgsHttpSessionThe servlet session.
11InputStreamParserArgInputStreamParserThe parser matched to the request Content-Type, if it is an InputStreamParser.
12MethodArgannotated with @MethodThe HTTP method name.
13ParserArgParserThe parser matched to the request Content-Type.
14PathArgannotated with @PathPath variable.
15PathRemainderArgannotated with @PathRemainderThe path remainder (the /* portion).
16QueryArgannotated with @QueryQuery parameter.
17ReaderParserArgReaderParserThe parser matched to the request Content-Type, if it is a ReaderParser.
18RecordReaderArgsubtype of RecordReader (but not TokenReader)Record cursor over the request body (see Record Streaming).
19RecordWriterArgsubtype of RecordWriter (but not TokenWriter)Record writer for the response (see Record Streaming).
20RequestBeanArgannotated with @RequestA request bean.
21ResponseBeanArgannotated with @Response (must be a Holder)A Holder whose value becomes the response body. See Response Beans.
22ResponseHeaderArga Holder annotated with @HeaderA Holder whose value is set as a response header.
23ResponseCodeArgannotated with @StatusCode (must be Holder<Integer>)A Holder whose value sets the response status code.
24RestContextArgsMarshallingContext, Config, EncoderSet, Logger, MethodExecStore, RestChildren, RestContext, RestContextStats, RestOperations, StaticFiles, ThrownStoreResource-level objects.
25RestSessionArgsRestSession, UrlPath, UrlPathMatchPer-call session objects.
26RestOpContextArgsJsonSchemaGenerator, ParserSet, RestOpContext, SerializerSetOperation-level objects.
27RestOpSessionArgsRestOpSession, BeanStore (or WritableBeanStore)Per-operation-call session objects.
28RestRequestArgsRestRequest, RequestContent, RequestHeaderList, RequestQueryParamList, RequestFormParamList, RequestPathParamList, RequestAttributes, InputStream, ServletInputStream, Reader, Locale, TimeZone, ResourceBundle, Messages, Swagger, UriContext, UriResolver, VarResolverSession, HttpPartParserSession, HttpPartSerializerSessionRequest-level objects.
29RestResponseArgsRestResponse, OutputStream, ServletOutputStream, WriterResponse-level objects.
30SseBroadcasterArgSseBroadcasterThe shared broadcaster bean (created on first use). See Server-Sent Events.
31SseSubscriptionArgSseSubscriptionA new subscription on the shared broadcaster.
32TokenReaderArgsubtype of TokenReaderToken cursor over the request body (see Token Streaming).
33TokenWriterArgsubtype of TokenWriterToken writer for the response.
34DefaultArganything else (fallback)A bean of the parameter type looked up in the resource bean store (by qualifier, if any).

Notes:

  • Where a resolver is listed by parameter type (for example Parser or Locale), the parameter type must match exactly; a ReaderParser parameter is therefore handled by ReaderParserArg, not ParserArg. The exceptions are AuthArg (any Principal subtype), RecordReaderArg, RecordWriterArg, TokenReaderArg and TokenWriterArg (subtypes).
  • Because AuthArg precedes HttpServletRequestArgs, a bare Principal parameter is resolved from the authenticated principal stored on the request by the guard chain, rather than from HttpServletRequest.getUserPrincipal().
  • @Header on a Holder parameter sets a response header; @Header on any other type reads a request header.
  • Because DefaultArg is the final fallback, any bean registered in the resource bean store (including Spring beans in Spring Boot environments) can be declared as an operation parameter.

Writing a custom resolver​

A resolver implements RestOpArg and exposes a static create(...) (or getInstance(...)) factory. The factory may declare a ParameterInfo parameter (and other injectable beans) and must return null if the resolver does not apply to the given parameter. RestOpArg.resolve(RestOpSession) is then called for each request to produce the value.

// A simple value type populated from a request header.
public record CallerId(String value) {}

public class CallerIdArg implements RestOpArg {

public static CallerIdArg create(ParameterInfo paramInfo) {
if (paramInfo.isType(CallerId.class))
return new CallerIdArg();
return null;
}

protected CallerIdArg() {}

@Override
public Object resolve(RestOpSession opSession) throws Exception {
return new CallerId(opSession.getRequest().getHeaders().getFirst("X-Caller-Id").asString().orElse("anonymous"));
}
}

Register it with @Rest(restOpArgs=CallerIdArg.class), after which any operation can declare a CallerId parameter.