weeks of bullshit

This commit is contained in:
Relism
2026-04-17 08:18:11 +02:00
parent b5d4481502
commit 9efbe38c0c
157 changed files with 5171 additions and 1273 deletions
+7 -5
View File
@@ -20,14 +20,16 @@ Jackson JSON integration for the Flash HTTP server.
</dependency>
```
Install before any extension that needs JSON (e.g. `flash-ext-openapi`, `flash-ext-oidc`):
```java
FlashApp.create(8080)
.install(new JacksonExtension())
// ... other extensions
.install(new OpenApiExtension("/openapi", "My API", "1.0.0"))
.start();
```
Install order is irrelevant — Flash's two-phase extension model ensures `ObjectMapper` is
resolved before any extension that calls `ctx.require(ObjectMapper.class)` needs it.
### Custom mapper
```java
@@ -56,7 +58,7 @@ public class CreateBlog extends JacksonHandler {
public Object handle(Request req, Response res) throws Exception {
CreateBlogRequest body = bodyAs(req, CreateBlogRequest.class);
Blog created = service.create(body);
res.setStatusCode(201);
res.status(201);
return json(res, created); // sets Content-Type: application/json
}
}
@@ -96,7 +98,7 @@ For lambda-style routes, use the `ObjectMapper` directly from the context:
ObjectMapper mapper = app.ctx().require(ObjectMapper.class);
app.get("/api/status", (req, res) -> {
res.setContentType(ContentType.JSON);
res.type(ContentType.JSON);
return mapper.writeValueAsString(Map.of("status", "ok"));
});
```
@@ -4,21 +4,19 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import dev.relism.extension.FlashContext;
import dev.relism.extension.FlashExtension;
import dev.relism.extension.FlashRegistrar;
/**
* Registers JSON support into the Flash extension layer.
*
* <p>Exposes a {@link Json} utility instance in the {@link FlashContext} under
* {@code Json.class}. Any handler or extension in the same scope can retrieve
* it via {@code require(Json.class)} inside {@code onInit()}.
* {@code Json.class}. Any handler or extension can retrieve it via {@code ctx.require(Json.class)}
* inside {@code onInit()} (class-based) or inside {@link FlashExtension#routes} (extensions).
*
* <p>The raw {@link ObjectMapper} is also registered under {@code ObjectMapper.class}
* for extensions that need direct mapper access (e.g. OpenAPI schema generation).
*
* <h3>Usage — composition (preferred)</h3>
* <pre>{@code
* // No mandatory base class. Works from any RequestHandler.
* public class MyHandler extends RequestHandler {
* private Json json;
*
@@ -33,16 +31,6 @@ import dev.relism.extension.FlashRegistrar;
* }
* }</pre>
*
* <h3>Usage — convenience base class</h3>
* <pre>{@code
* // JacksonHandler remains available as a thin opt-in wrapper.
* public class MyHandler extends JacksonHandler {
* public Object handle(Request req, Response res) throws Exception {
* return json(res, service.findAll());
* }
* }
* }</pre>
*
* <h3>Custom mapper</h3>
* <pre>{@code
* ObjectMapper mapper = JsonMapper.builder()
@@ -69,9 +57,9 @@ public class JacksonExtension implements FlashExtension {
}
@Override
public void install(FlashRegistrar app, FlashContext ctx) {
public void provide(FlashContext ctx) {
Json json = new Json(mapper);
ctx.provide(Json.class, json);
ctx.provide(ObjectMapper.class, mapper); // backward compat for extensions (OpenAPI, etc.)
ctx.provide(ObjectMapper.class, mapper);
}
}
@@ -91,16 +91,7 @@ public final class Json {
* <p>The returned string is used as the response body by the Flash runtime.
*/
public String write(Response res, Object obj) throws Exception {
res.setContentType(ContentType.JSON);
return mapper.writeValueAsString(obj);
}
/**
* Like {@link #write(Response, Object)} but also sets an explicit HTTP status code.
*/
public String write(Response res, int status, Object obj) throws Exception {
res.status(status);
res.setContentType(ContentType.JSON);
res.type(ContentType.JSON);
return mapper.writeValueAsString(obj);
}
@@ -109,7 +100,7 @@ public final class Json {
* restricting serialization to fields visible under {@code view}.
*/
public String writeView(Response res, Object obj, Class<?> view) throws Exception {
res.setContentType(ContentType.JSON);
res.type(ContentType.JSON);
return mapper.writerWithView(view).writeValueAsString(obj);
}