EzyHTTP Request Arguments
Updated at 1783179779000EzyHTTP 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 |
| 1 | Path variable | @PathVariable | Reads a value from the URI template, for example /authors/{authorId}. |
| 2 | Request parameter | @RequestParam | Reads a query string or form parameter. |
| 3 | Request header | @RequestHeader | Reads a request header. |
| 4 | Request cookie | @RequestCookie | Reads a cookie value. |
| 5 | Request body | @RequestBody | Deserializes the request body by content type. |
| 6 | Request argument map | @RequestArgument | Reads a named value stored in the current request context. |
| 7 | Request context | RequestArguments | Gives direct access to the full request context. |
| 8 | Custom argument | Custom annotation / key | Injects 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/json | Read JSON from the input stream and map it to the declared Java type. |
application/x-www-form-urlencoded | Read request parameters and convert them to the declared Java type. |
multipart/form-data | Use form-style conversion from request parameters. |
text/plain, text/html | Use 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 types | int, long, boolean, Integer, Long, Boolean |
| String | String |
| Enum | Matches enum name, with uppercase fallback. |
| Array | long[], String[] |
| Collection | List<Long>, Set<String> |
| Date/time | Date, Instant, LocalDate, LocalTime, LocalDateTime |
| Number objects | BigInteger, 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 context | RequestArguments |
| You want to manually search several request locations by name | RequestArguments.getRequestValue(...) |
| Value is prepared by an interceptor or framework component | Custom argument |
Next
You can also take a look at EzyHTTP response types to see how controller return values are converted back to HTTP responses.