Skip to content

Commit 865e4aa

Browse files
committed
Support for Jax-RS style "StreamingOutput"
This commit only implements for the JEX server option.
1 parent 1fcbcdf commit 865e4aa

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.avaje.http.api;
2+
3+
import java.io.IOException;
4+
import java.io.OutputStream;
5+
6+
/**
7+
* An avaje {@link Controller} endpoint is able to use an instance of this interface
8+
* as a return type.
9+
*
10+
* <pre>{@code
11+
* @Post("some_endpoint")
12+
* @Produces("application/octet-stream")
13+
* public StreamingOutput thumbnail(
14+
* InputStream inputStream,
15+
* @QueryParam(Constants.KEY_SIZE) @Min(1) @Max(Constants.MAX_SIZE) Integer size
16+
* ) throws IOException {
17+
* return (os) -> os.write(new byte[] { 0x01, 0x02, 0x03 });
18+
* }
19+
* }</pre>
20+
*/
21+
22+
public interface StreamingOutput {
23+
void write(OutputStream outputStream) throws IOException;
24+
}

http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ enum ResponseMode {
107107
Jstachio,
108108
Templating,
109109
InputStream,
110+
StreamingOutput,
110111
Other
111112
}
112113

@@ -117,6 +118,9 @@ ResponseMode responseMode() {
117118
if (isInputStream(method.returnType())) {
118119
return ResponseMode.InputStream;
119120
}
121+
if (isStreamingOutput(method.returnType())) {
122+
return ResponseMode.StreamingOutput;
123+
}
120124
if (producesJson()) {
121125
return ResponseMode.Json;
122126
}
@@ -136,6 +140,10 @@ private boolean isInputStream(TypeMirror type) {
136140
return isAssignable2Interface(type.toString(), "java.io.InputStream");
137141
}
138142

143+
private boolean isStreamingOutput(TypeMirror type) {
144+
return isAssignable2Interface(type.toString(), "io.avaje.http.api.StreamingOutput");
145+
}
146+
139147
private boolean producesJson() {
140148
return !"byte[]".equals(method.returnType().toString())
141149
&& !useJstachio
@@ -294,11 +302,17 @@ private void writeContextReturn(ResponseMode responseMode, String resultVariable
294302
case Json -> writeJsonReturn(produces, indent);
295303
case Text -> writer.append("ctx.text(%s);", resultVariable);
296304
case Templating -> writer.append("ctx.html(%s);", resultVariable);
305+
case StreamingOutput -> writeStreamingOutputReturn(produces, resultVariable, indent);
297306
default -> writer.append("ctx.contentType(\"%s\").write(%s);", produces, resultVariable);
298307
}
299308
writer.eol();
300309
}
301310

311+
private void writeStreamingOutputReturn(String produces, String resultVariable, String indent) {
312+
writer.append("ctx.contentType(\"%s\");", produces).eol();
313+
writer.append(indent).append("%s.write(ctx.outputStream());", resultVariable);
314+
}
315+
302316
private void writeJsonReturn(String produces, String indent) {
303317
var uType = UType.parse(method.returnType());
304318
boolean streaming = useJsonB && streamingContent(uType);

0 commit comments

Comments
 (0)