EzyHTTP Request Arguments

Updated at 1783179779000
EzyHTTP lets a controller method receive data from an HTTP request directly through method arguments. Instead of reading HttpServletRequest manually, you can declare what your API needs: path variables, query/form parameters, headers, cookies, request body, or values prepared by interceptors.
Behind the scenes, EzyHTTP creates a request context for each matched route, collects request parameters, headers, cookies and path variables, then converts them to the Java types declared in your controller method.
flowchart LR
    A[HTTP request] --> B[Match route]
    B --> C[Create RequestArguments]
    C --> D[Run interceptors]
    D --> E[Resolve controller method arguments]
    E --> F[Call controller method]
    F --> G[Serialize response]

Supported argument sources

# Source Annotation / Type Description
1Path variable@PathVariableReads a value from the URI template, for example /authors/{authorId}.
2Request parameter@RequestParamReads a query string or form parameter.
3Request header@RequestHeaderReads a request header.
4Request cookie@RequestCookieReads a cookie value.
5Request body@RequestBodyDeserializes the request body by content type.
6Request argument map@RequestArgumentReads a named value stored in the current request context.
7Request contextRequestArgumentsGives direct access to the full request context.
8Custom argumentCustom annotation / keyInjects a value stored in the request context, commonly by an interceptor.

Named and indexed lookup

For @RequestParam, @RequestHeader and @RequestCookie, EzyHTTP chooses the lookup key in this order:
value -> name -> argument index
So these two declarations are equivalent:
@RequestParam("limit") int limit
@RequestParam(name = "limit") int limit
If both value and name are empty, EzyHTTP reads by index among parameters of the same annotation type.
For @PathVariable, the lookup key is simpler:
value -> path variable index
@RequestArgument always requires an explicit value because it reads from the request context argument map by name.

Path variables

Use @PathVariable when a value is part of the route itself.
@Api
@Controller("/api/v1/authors")
public class AuthorController {

    @DoGet("/{authorId}")
    public AuthorResponse getAuthor(
        @PathVariable("authorId") long authorId
    ) {
        // implementation
    }
}
When the client calls:
GET /api/v1/authors/10
EzyHTTP extracts authorId = 10 from the URI and converts it to long.
If the annotation value is omitted, EzyHTTP resolves the path variable by its position among @PathVariable parameters:
@DoGet("/{authorId}")
public AuthorResponse getAuthor(@PathVariable long authorId) {
    // implementation
}

Request parameters

Use @RequestParam for query string parameters or form parameters collected from the servlet request.
@DoGet("/books")
public List<BookResponse> getBooks(
    @RequestParam("keyword") String keyword,
    @RequestParam(name = "limit", defaultValue = "20") int limit
) {
    // implementation
}
Example request:
GET /books?keyword=java&limit=10
EzyHTTP maps keyword to "java" and limit to 10.
If a request parameter has multiple values, EzyHTTP joins them with commas before converting:
GET /books?ids=1&ids=2&ids=3
can be read as:
@DoGet("/books")
public List<BookResponse> getBooks(
    @RequestParam("ids") List<Long> ids
) {
    // ids = [1, 2, 3]
}
The same comma-separated conversion also works for arrays and sets.

Request headers

Use @RequestHeader to read a header value.
@DoGet("/profile")
public ProfileResponse getProfile(
    @RequestHeader("Authorization") String authorization,
    @RequestHeader(name = "X-Client-Version", defaultValue = "unknown") String clientVersion
) {
    // implementation
}
When defaultValue is provided, EzyHTTP uses it if the header is absent. Without a default value, a missing object type becomes null; a missing primitive receives its Java primitive default after conversion, for example 0 for int and false for boolean.

Request cookies

Use @RequestCookie to read a cookie value.
@DoGet("/me")
public UserResponse getMe(
    @RequestCookie("access_token") String accessToken
) {
    // implementation
}
@RequestCookie also supports name and defaultValue:
@DoGet("/locale")
public LocaleResponse getLocale(
    @RequestCookie(name = "lang", defaultValue = "en") String language
) {
    // implementation
}
If multiple cookies with the same name exist, EzyHTTP keeps the first useful non-empty value for that name.

Request body

Use @RequestBody when the input should be deserialized from the request body.
@DoPost("/books")
public BookResponse addBook(
    @RequestBody AddBookRequest request
) {
    // implementation
}
The body converter is selected by Content-Type.
Content type Default behavior
application/jsonRead JSON from the input stream and map it to the declared Java type.
application/x-www-form-urlencodedRead request parameters and convert them to the declared Java type.
multipart/form-dataUse form-style conversion from request parameters.
text/plain, text/htmlUse text conversion.
If the request does not contain a content type, EzyHTTP treats it as a bad request for @RequestBody.

RequestArgument

@RequestArgument reads a value from the current request context argument map. This is most often used with interceptors: an interceptor authenticates or prepares data, stores it into RequestArguments, and the controller receives it as a normal method argument.
@Interceptor
public class AuthenticationInterceptor implements RequestInterceptor {

    @Override
    public boolean preHandle(
        RequestArguments arguments,
        Method handler
    ) throws Exception {
        arguments.setArgument("currentUserId", 100L);
        return true;
    }
}
The controller can receive the value with the same key:
@DoGet("/me")
public UserResponse getMe(
    @RequestArgument("currentUserId") long currentUserId
) {
    // implementation
}
Use @RequestArgument for values that are prepared inside the server during request processing. If the value comes directly from the HTTP message, prefer the more specific annotation such as @RequestParam, @RequestHeader, @RequestCookie, or @PathVariable.

RequestArguments

You can inject RequestArguments directly when the controller needs lower-level access.
@DoPost("/files/{fileName}")
public UploadResponse upload(
    RequestArguments arguments,
    @PathVariable("fileName") String fileName
) throws Exception {
    String contentType = arguments.getContentType();
    InputStream inputStream = arguments.getInputStream();
    // implementation
}
RequestArguments exposes:
Method Purpose
getMethod()Returns the HTTP method.
getRequest()Returns the underlying servlet request.
getResponse()Returns the underlying servlet response.
getParameter(...)Reads request parameters by name or index.
getHeader(...)Reads headers by name or index.
getCookieValue(...)Reads cookie values by name or index.
getPathVariable(...)Reads path variables by name or index.
getRequestValue(...)Reads a value by name across parameters, headers, cookies, path variables, request attributes and the argument map.
setArgument(...) / getArgument(...)Stores and reads custom values for the current request.
getRedirectionAttribute(...)Reads attributes carried through a redirect.
When you call getRequestValue(name) manually, EzyHTTP checks sources in this order:
flowchart TD
    A[Name] --> B[Request parameter]
    B --> C[Header]
    C --> D[Cookie]
    D --> E[Path variable]
    E --> F[Servlet request attribute]
    F --> G[Argument map]
getRequestValueAnyway(...) adds a small naming fallback: it tries the original name, then a lowercase version, then a first-letter-uppercase version.

Custom arguments

If a controller parameter has no built-in annotation and is not RequestArguments, EzyHTTP reads it from the request context argument map.
This is useful when an interceptor or another framework component prepares a value before the controller is called.
@Interceptor
public class PermissionInterceptor implements RequestInterceptor {

    @Override
    public boolean preHandle(
        RequestArguments arguments,
        Method handler
    ) throws Exception {
        long userId = authenticationService.verifyAccessToken(arguments);
        arguments.setArgument(UserId.class.getName() + ".class", userId);
        return true;
    }
}
Then the controller can receive the value through a custom parameter annotation. For an annotated parameter, EzyHTTP uses the annotation class name plus .class as the argument key:
@DoPost("/users/save")
public Object saveUser(
    @UserId long userId
) {
    // implementation
}
For an unannotated parameter, EzyHTTP uses the parameter type name plus .class as the key.
Use custom arguments for request-scoped values that are not part of the HTTP message itself, such as authenticated user id, permission data, tenant id, or tracing metadata.

Type conversion

Values from path variables, parameters, headers and cookies start as strings. EzyHTTP converts them to the declared Java type before calling the controller method.
Supported conversions include:
Target type Examples
Primitive and wrapper typesint, long, boolean, Integer, Long, Boolean
StringString
EnumMatches enum name, with uppercase fallback.
Arraylong[], String[]
CollectionList<Long>, Set<String>
Date/timeDate, Instant, LocalDate, LocalTime, LocalDateTime
Number objectsBigInteger, BigDecimal
For arrays and collections, the input is split by comma:
ids=1,2,3
can become:
@RequestParam("ids") List<Long> ids
If conversion fails, EzyHTTP raises a request value deserialization error. The default error handling maps these errors to a bad request response.

Choosing the right annotation

Use the most specific annotation when possible:
Need Use
Value is part of the URI@PathVariable
Value comes from query string or submitted form fields@RequestParam
Value comes from an HTTP header@RequestHeader
Value comes from a cookie@RequestCookie
Value comes from JSON, form body, multipart body, or text body@RequestBody
Value is stored in the current request context under a named key@RequestArgument
You need low-level access to the request contextRequestArguments
You want to manually search several request locations by nameRequestArguments.getRequestValue(...)
Value is prepared by an interceptor or framework componentCustom argument

Next

You can also take a look at EzyHTTP response types to see how controller return values are converted back to HTTP responses.

Table Of Contents