diff --git a/avaje-jex/pom.xml b/avaje-jex/pom.xml index e4139c48..cab9c672 100644 --- a/avaje-jex/pom.xml +++ b/avaje-jex/pom.xml @@ -48,6 +48,12 @@ true + + io.avaje + avaje-jsonb-generator + 2.3 + test + diff --git a/avaje-jex/src/main/java/io/avaje/jex/Context.java b/avaje-jex/src/main/java/io/avaje/jex/Context.java index 4b2f2ba9..cd91cad7 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/Context.java +++ b/avaje-jex/src/main/java/io/avaje/jex/Context.java @@ -4,6 +4,7 @@ import static java.util.Collections.emptyMap; import java.io.InputStream; +import java.io.OutputStream; import java.time.Duration; import java.time.ZonedDateTime; import java.util.Iterator; @@ -294,6 +295,15 @@ default String userAgent() { */ Context write(InputStream is); + /** + * Return the outputStream to write content. It is expected that + * the {@link #contentType(String)} has been set prior to obtaining + * and writing to the outputStream. + * + * @return The outputStream to write content to. + */ + OutputStream outputStream(); + /** * Render a template typically as html. * diff --git a/avaje-jex/src/main/java/io/avaje/jex/jdk/JdkContext.java b/avaje-jex/src/main/java/io/avaje/jex/jdk/JdkContext.java index cfb34839..c0ffe37d 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/jdk/JdkContext.java +++ b/avaje-jex/src/main/java/io/avaje/jex/jdk/JdkContext.java @@ -477,6 +477,7 @@ public String protocol() { return exchange.getProtocol(); } + @Override public OutputStream outputStream() { var out = mgr.createOutputStream(this); if (compressionConfig.compressionEnabled()) { diff --git a/avaje-jex/src/test/java/io/avaje/jex/jdk/HelloDto.java b/avaje-jex/src/test/java/io/avaje/jex/jdk/HelloDto.java index e8861f3f..a352e742 100644 --- a/avaje-jex/src/test/java/io/avaje/jex/jdk/HelloDto.java +++ b/avaje-jex/src/test/java/io/avaje/jex/jdk/HelloDto.java @@ -1,5 +1,8 @@ package io.avaje.jex.jdk; +import io.avaje.jsonb.Json; + +@Json public class HelloDto { public long id; diff --git a/avaje-jex/src/test/java/io/avaje/jex/jdk/JsonTest.java b/avaje-jex/src/test/java/io/avaje/jex/jdk/JsonTest.java index 1ab2dcab..a7fc591a 100644 --- a/avaje-jex/src/test/java/io/avaje/jex/jdk/JsonTest.java +++ b/avaje-jex/src/test/java/io/avaje/jex/jdk/JsonTest.java @@ -11,6 +11,8 @@ import java.util.concurrent.locks.LockSupport; import java.util.stream.Stream; +import io.avaje.jsonb.JsonType; +import io.avaje.jsonb.Jsonb; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; @@ -26,12 +28,19 @@ private static AutoCloseIterator createBeanIterator() { return new AutoCloseIterator<>(HELLO_BEANS.iterator()); } - static TestPair pair = init(); + static final TestPair pair = init(); + static final Jsonb jsonb = Jsonb.builder().build(); + static final JsonType jsonTypeHelloDto = jsonb.type(HelloDto.class); static TestPair init() { Jex app = Jex.create() .routing(routing -> routing - .get("/", ctx -> ctx.json(HelloDto.rob()).status(200)) + .get("/", ctx -> ctx.status(200).json(HelloDto.rob())) + .get("/usingOutputStream", ctx -> { + ctx.status(200).contentType("application/json"); + var result = HelloDto.rob(); + jsonTypeHelloDto.toJson(result, ctx.outputStream()); + }) .get("/iterate", ctx -> ctx.jsonStream(ITERATOR)) .get("/stream", ctx -> ctx.jsonStream(HELLO_BEANS.stream())) .post("/", ctx -> ctx.text("bean[" + ctx.bodyAsClass(HelloDto.class) + "]"))); @@ -58,9 +67,33 @@ void get() { .GET().asString(); final HttpHeaders headers = hres.headers(); - assertThat(headers.firstValue("Content-Type").get()).isEqualTo("application/json"); + assertThat(headers.firstValue("Content-Type").orElseThrow()).isEqualTo("application/json"); } + @Test + void usingOutputStream() { + + var bean = pair.request().path("usingOutputStream") + .GET() + .bean(HelloDto.class); + + assertThat(bean.id).isEqualTo(42); + assertThat(bean.name).isEqualTo("rob"); + + final HttpResponse hres = pair.request() + .GET().asString(); + + final HttpHeaders headers = hres.headers(); + assertThat(headers.firstValue("Content-Type").orElseThrow()).isEqualTo("application/json"); + + bean = pair.request().path("usingOutputStream") + .GET() + .bean(HelloDto.class); + assertThat(bean.id).isEqualTo(42); + assertThat(bean.name).isEqualTo("rob"); + } + + @Test void stream_viaIterator() { final Stream beanStream = pair.request()