Add comprehensive Javadoc documentation to server components, including annotations, request/response handling, routing, and WebSocket support.

This commit is contained in:
CodingPhoenixx
2026-05-29 08:50:05 +02:00
parent f00a1098b4
commit 5d6e8622bf
33 changed files with 1938 additions and 53 deletions
@@ -9,22 +9,57 @@ import tools.jackson.databind.JsonNode;
import java.util.*;
/**
* A convenience wrapper around a Netty {@link FullHttpRequest} that exposes the parts of an
* HTTP request handlers typically need: path parameters, query parameters, headers and the
* request body (raw, as a parsed JSON tree, or deserialized into a type).
*
* <p>Query parameters and the parsed JSON body are computed lazily and cached, so repeated
* accessors do not re-parse the request. A single {@code Request} instance is not intended to
* be shared across threads.</p>
*/
public final class Request {
private final FullHttpRequest raw;
private final Map<String, String> pathParams;
private Map<String, List<String>> queryParams;
private JsonNode jsonCache;
/** The underlying Netty request this wrapper delegates to. */
private final FullHttpRequest raw;
/** Path parameters captured by the router while matching, keyed by name. */
private final Map<String, String> pathParams;
/** Lazily decoded query-string parameters; {@code null} until first accessed. */
private Map<String, List<String>> queryParams;
/** Lazily parsed JSON body; {@code null} until {@link #json()} is first called. */
private JsonNode jsonCache;
/**
* Creates a request wrapper.
*
* @param raw the underlying Netty request
* @param pathParams the path parameters captured during routing, keyed by name
*/
public Request(FullHttpRequest raw, Map<String, String> pathParams) {
this.raw = raw;
this.pathParams = pathParams;
}
/**
* Returns the value of a path parameter captured during routing.
*
* @param name the parameter name as declared in the route (without braces)
* @return the captured value, or {@code null} if no such parameter was matched
*/
public String pathParam(String name) {
return pathParams.get(name);
}
/**
* Returns the first value of a query-string parameter, decoding the query string on first
* access.
*
* @param name the query parameter name
* @return the first value, or {@code null} if the parameter is absent or has no value
*/
public String queryParam(String name) {
if (queryParams == null) {
queryParams = new QueryStringDecoder(raw.uri()).parameters();
@@ -33,6 +68,13 @@ public final class Request {
return values == null || values.isEmpty() ? null : values.getFirst();
}
/**
* Returns all values of a query-string parameter, decoding the query string on first
* access.
*
* @param name the query parameter name
* @return the (possibly empty) list of values for the parameter; never {@code null}
*/
public List<String> queryParams(String name) {
if (queryParams == null) {
queryParams = new QueryStringDecoder(raw.uri()).parameters();
@@ -40,14 +82,32 @@ public final class Request {
return queryParams.getOrDefault(name, List.of());
}
/**
* Returns the value of a request header.
*
* @param name the (case-insensitive) header name
* @return the header value, or {@code null} if not present
*/
public String header(String name) {
return raw.headers().get(name);
}
/**
* Returns the request body decoded as a UTF-8 string.
*
* @return the body as text (empty if there is no body)
*/
public String body() {
return raw.content().toString(CharsetUtil.UTF_8);
}
/**
* Parses the request body as a JSON tree, caching the result for subsequent calls. An
* empty body resolves to a JSON {@code null} node rather than an error.
*
* @return the parsed JSON tree
* @throws BadRequestException if the body is not valid JSON
*/
public JsonNode json() {
if (jsonCache == null) {
try {
@@ -65,6 +125,17 @@ public final class Request {
return jsonCache;
}
/**
* Deserializes the request body directly into an instance of the given type.
*
* <p>Unlike {@link #json()}, the result is not cached and the body is read fresh on each
* call.</p>
*
* @param type the target type to deserialize into
* @param <T> the target type
* @return the deserialized value
* @throws BadRequestException if the body cannot be deserialized into {@code type}
*/
public <T> T jsonAs(Class<T> type) {
try {
byte[] bytes = new byte[raw.content().readableBytes()];
@@ -76,11 +147,21 @@ public final class Request {
}
}
/**
* Returns the request's HTTP method.
*
* @return the HTTP method
*/
public HttpMethod method() {
return raw.method();
}
/**
* Returns the request's path, with any query string stripped off.
*
* @return the decoded request path
*/
public String path() {
return new QueryStringDecoder(raw.uri()).path();
}
}
}