Skip to content

Commit e43210d

Browse files
authored
Merge pull request #236 from avaje/feature/rawJsonString
Nima - When returning JSON as String assume the string is raw json
2 parents 9f7baea + 2cbcb2a commit e43210d

File tree

6 files changed

+148
-19
lines changed

6 files changed

+148
-19
lines changed

http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ void writeHandler(boolean requestScoped) {
4848
if (bodyType != null) {
4949
if ("InputStream".equals(bodyType)) {
5050
writer.append(" var %s = req.content().inputStream();", method.bodyName()).eol();
51+
} else if ("String".equals(bodyType)) {
52+
writer.append(" var %s = req.content().as(String.class);", method.bodyName()).eol();
5153
} else if (useJsonB) {
5254
final String fieldName = fieldNameOfBody();
5355
writer.append(" var %s = %sJsonType.fromJson(req.content().inputStream());", method.bodyName(), fieldName).eol();
@@ -113,8 +115,12 @@ void writeHandler(boolean requestScoped) {
113115
final var uType = UType.parse(method.returnType());
114116
writer.append(" result.transferTo(res.outputStream());", uType.shortName()).eol();
115117
} else if (producesJson()) {
116-
final var uType = UType.parse(method.returnType());
117-
writer.append(" %sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol();
118+
if (returnTypeString()) {
119+
writer.append(" res.send(result); // send raw JSON").eol();
120+
} else {
121+
final var uType = UType.parse(method.returnType());
122+
writer.append(" %sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol();
123+
}
118124
} else {
119125
writer.append(" res.send(result);").eol();
120126
}
@@ -159,6 +165,10 @@ private boolean producesJson() {
159165
&& (method.produces() == null || method.produces().toLowerCase().contains("json"));
160166
}
161167

168+
private boolean returnTypeString() {
169+
return "java.lang.String".equals(method.returnType().toString());
170+
}
171+
162172
private boolean missingServerResponse(List<MethodParam> params) {
163173
return method.isVoid() && params.stream().noneMatch(p -> "ServerResponse".equals(p.shortType()));
164174
}

http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.avaje.http.generator.helidon.nima;
22

33
import static io.avaje.http.generator.core.ProcessingContext.diAnnotation;
4+
import static io.avaje.http.generator.core.ProcessingContext.isAssignable2Interface;
45

56
import java.io.IOException;
67
import java.util.List;
@@ -106,8 +107,10 @@ private void writeClassStart() {
106107
}
107108

108109
for (final UType type : jsonTypes.values()) {
109-
final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", ");
110-
writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol();
110+
if (!isInputStream(type.full())) {
111+
final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", ");
112+
writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol();
113+
}
111114
}
112115
writer.eol();
113116

@@ -133,9 +136,15 @@ private void writeClassStart() {
133136

134137
if (useJsonB) {
135138
for (final UType type : jsonTypes.values()) {
136-
JsonBUtil.writeJsonbType(type, writer);
139+
if (!isInputStream(type.full())) {
140+
JsonBUtil.writeJsonbType(type, writer);
141+
}
137142
}
138143
}
139144
writer.append(" }").eol().eol();
140145
}
146+
147+
private boolean isInputStream(String type) {
148+
return isAssignable2Interface(type.toString(), "java.io.InputStream");
149+
}
141150
}

tests/test-nima-jsonb/pom.xml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<maven.compiler.source>20</maven.compiler.source>
1515
<maven.compiler.target>20</maven.compiler.target>
1616
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17+
<surefire.useModulePath>false</surefire.useModulePath>
1718
</properties>
1819

1920

@@ -31,7 +32,7 @@
3132
<dependency>
3233
<groupId>io.avaje</groupId>
3334
<artifactId>avaje-jsonb</artifactId>
34-
<version>1.4</version>
35+
<version>1.6-RC6</version>
3536
</dependency>
3637
<dependency>
3738
<groupId>io.avaje</groupId>
@@ -48,6 +49,11 @@
4849
<artifactId>helidon-nima-http-media-jsonb</artifactId>
4950
<version>${nima.version}</version>
5051
</dependency>
52+
<dependency>
53+
<groupId>io.avaje</groupId>
54+
<artifactId>avaje-http-client</artifactId>
55+
<version>${project.version}</version>
56+
</dependency>
5157
<dependency>
5258
<groupId>io.avaje</groupId>
5359
<artifactId>avaje-http-nima-generator</artifactId>
@@ -69,6 +75,7 @@
6975
<artifactId>maven-compiler-plugin</artifactId>
7076
<version>3.10.1</version>
7177
<configuration>
78+
<enablePreview>true</enablePreview>
7279
<release>20</release>
7380
<annotationProcessorPaths>
7481
<path>
@@ -84,17 +91,25 @@
8491
<path>
8592
<groupId>io.avaje</groupId>
8693
<artifactId>avaje-jsonb-generator</artifactId>
87-
<version>1.4</version>
94+
<version>1.6-RC6</version>
8895
</path>
8996
</annotationProcessorPaths>
9097
<source>19</source>
9198
<target>19</target>
9299
</configuration>
93100
</plugin>
101+
<plugin>
102+
<groupId>org.apache.maven.plugins</groupId>
103+
<artifactId>maven-surefire-plugin</artifactId>
104+
<version>3.0.0</version>
105+
<configuration>
106+
<argLine>--enable-preview</argLine>
107+
</configuration>
108+
</plugin>
94109
<plugin>
95110
<groupId>io.repaint.maven</groupId>
96111
<artifactId>tiles-maven-plugin</artifactId>
97-
<version>2.22</version>
112+
<version>2.34</version>
98113
<extensions>true</extensions>
99114
<configuration>
100115
<tiles>

tests/test-nima-jsonb/src/main/java/org/example/TestController.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,18 @@
44
import java.util.List;
55
import java.util.Set;
66

7-
import io.avaje.http.api.BodyString;
8-
import io.avaje.http.api.Controller;
9-
import io.avaje.http.api.Default;
10-
import io.avaje.http.api.Form;
11-
import io.avaje.http.api.FormParam;
12-
import io.avaje.http.api.Get;
13-
import io.avaje.http.api.InstrumentServerContext;
14-
import io.avaje.http.api.Path;
15-
import io.avaje.http.api.Post;
16-
import io.avaje.http.api.QueryParam;
7+
import io.avaje.http.api.*;
178

18-
@Path("test/")
9+
@Path("test")
1910
@Controller
2011
public class TestController {
2112

13+
@Produces("text/plain")
14+
@Get
15+
String hello() {
16+
return "hi";
17+
}
18+
2219
@Get("/paramMulti")
2320
String paramMulti(Set<String> strings) {
2421
return strings.toString();
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.example;
2+
3+
import io.avaje.http.client.HttpClient;
4+
import org.junit.jupiter.api.AfterAll;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.net.http.HttpResponse;
8+
9+
import static org.assertj.core.api.Assertions.as;
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
class TestControllerTest {
13+
14+
private static TestPair pair = new TestPair();
15+
private static HttpClient client = pair.client();
16+
17+
@AfterAll
18+
static void end() {
19+
pair.stop();
20+
}
21+
22+
@Test
23+
void hello() {
24+
HttpResponse<String> res = client.request()
25+
.GET()
26+
.asString();
27+
28+
assertThat(res.statusCode()).isEqualTo(200);
29+
assertThat(res.body()).isEqualTo("Hello world - index");
30+
}
31+
32+
@Test
33+
void strBody() {
34+
HttpResponse<String> res = client.request()
35+
.path("test/strBody")
36+
.body("{\"key\":42}")
37+
.POST()
38+
.asString();
39+
40+
assertThat(res.statusCode()).isEqualTo(200);
41+
assertThat(res.body()).isEqualTo("{\"key\":42}");
42+
assertThat(res.headers().firstValue("Content-Type")).isPresent().get().isEqualTo("application/json");
43+
assertThat(res.headers().firstValue("Content-Length")).isPresent();
44+
}
45+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.example;
2+
3+
import io.avaje.http.api.context.ThreadLocalRequestContextResolver;
4+
import io.avaje.http.client.HttpClient;
5+
import io.avaje.http.hibernate.validator.BeanValidator;
6+
import io.avaje.jsonb.Jsonb;
7+
import io.helidon.nima.webserver.WebServer;
8+
import io.helidon.nima.webserver.http.HttpRouting;
9+
10+
public class TestPair {
11+
12+
WebServer webServer;
13+
HttpClient httpClient;
14+
int port;
15+
16+
public TestPair() {
17+
this.webServer = WebServer.builder()
18+
.routing(routing().build())
19+
.build();
20+
21+
webServer.start();
22+
this.port = webServer.port();
23+
24+
this.httpClient = HttpClient.builder()
25+
.baseUrl("http://localhost:" + port)
26+
.build();
27+
}
28+
29+
public HttpClient client() {
30+
return httpClient;
31+
}
32+
33+
void stop() {
34+
webServer.stop();
35+
}
36+
37+
private static HttpRouting.Builder routing() {
38+
HttpRouting.Builder routing = HttpRouting.builder();
39+
40+
var beanValidator = new BeanValidator();
41+
Jsonb jsonb = Jsonb.builder().build();
42+
43+
var hc = new HelloController();
44+
var hello = new HelloController$Route(hc, beanValidator, jsonb);
45+
hello.routing(routing);
46+
47+
var cr = new ThreadLocalRequestContextResolver();
48+
var tc = new TestController();
49+
TestController$Route tcr = new TestController$Route(tc, jsonb, cr);
50+
tcr.routing(routing);
51+
return routing;
52+
}
53+
}

0 commit comments

Comments
 (0)