weeks of bullshit
This commit is contained in:
@@ -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
-16
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user