Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.

Commit 25e9d7e

Browse files
committed
ApiTool does not handle Upload correctly on mvc routes fix jooby-project#958
1 parent c79c54f commit 25e9d7e

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

modules/jooby-apitool/src/main/java/org/jooby/internal/apitool/SwaggerBuilder.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,11 @@
208208
import com.google.common.base.Splitter;
209209
import com.google.common.base.Strings;
210210
import com.google.common.collect.ImmutableList;
211+
import com.google.inject.TypeLiteral;
212+
import io.swagger.converter.ModelConverter;
213+
import io.swagger.converter.ModelConverterContext;
211214
import io.swagger.converter.ModelConverters;
215+
import io.swagger.jackson.AbstractModelConverter;
212216
import io.swagger.models.Model;
213217
import io.swagger.models.Operation;
214218
import io.swagger.models.Path;
@@ -224,14 +228,18 @@
224228
import io.swagger.models.parameters.QueryParameter;
225229
import io.swagger.models.parameters.SerializableParameter;
226230
import io.swagger.models.properties.ArrayProperty;
231+
import io.swagger.models.properties.FileProperty;
227232
import io.swagger.models.properties.Property;
228233
import io.swagger.models.properties.PropertyBuilder;
229234
import io.swagger.models.properties.PropertyBuilder.PropertyId;
235+
import io.swagger.util.Json;
230236
import org.jooby.MediaType;
237+
import org.jooby.Upload;
231238
import org.jooby.apitool.RouteMethod;
232239
import org.jooby.apitool.RouteParameter;
233240
import org.jooby.apitool.RouteResponse;
234241

242+
import java.lang.annotation.Annotation;
235243
import java.lang.reflect.Type;
236244
import java.util.EnumMap;
237245
import java.util.Iterator;
@@ -255,6 +263,25 @@ public class SwaggerBuilder {
255263
};
256264
private Function<RouteMethod, String> tagger = TAG_PROVIDER;
257265

266+
static {
267+
/** Convert Upload to Swagger FileProperty: */
268+
ModelConverters.getInstance().addConverter(new AbstractModelConverter(Json.mapper()) {
269+
@Override public Property resolveProperty(Type type, ModelConverterContext context,
270+
Annotation[] annotations, Iterator<ModelConverter> chain) {
271+
TypeLiteral<?> typeLiteral = TypeLiteral.get(type);
272+
String typeName = typeLiteral.getType().getTypeName();
273+
if (typeName.equals("java.util.List<org.jooby.Upload>") ||
274+
typeName.equals("java.util.Set<org.jooby.Upload>")) {
275+
return new ArrayProperty(new FileProperty());
276+
}
277+
if (typeName.equals(Upload.class.getName())) {
278+
return new FileProperty();
279+
}
280+
return super.resolveProperty(type, context, annotations, chain);
281+
}
282+
});
283+
}
284+
258285
public SwaggerBuilder() {
259286
}
260287

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package issues;
2+
3+
import com.google.inject.util.Types;
4+
import io.swagger.models.HttpMethod;
5+
import io.swagger.models.Swagger;
6+
import io.swagger.models.parameters.FormParameter;
7+
import org.jooby.Upload;
8+
import org.jooby.apitool.RouteMethod;
9+
import org.jooby.apitool.RouteParameter;
10+
import org.jooby.apitool.RouteResponse;
11+
import org.jooby.internal.apitool.SwaggerBuilder;
12+
import static org.junit.Assert.assertEquals;
13+
import org.junit.Test;
14+
15+
import java.lang.reflect.Type;
16+
import java.util.Arrays;
17+
18+
public class Issue958 {
19+
20+
@Test
21+
public void shouldCreateSwaggerFile() throws Exception {
22+
Swagger swagger = new SwaggerBuilder()
23+
.build(null, Arrays.asList(route(fileParam("myfile", Upload.class))));
24+
FormParameter parameter = (FormParameter) swagger
25+
.getPath("/file")
26+
.getOperationMap()
27+
.get(HttpMethod.POST)
28+
.getParameters()
29+
.get(0);
30+
assertEquals("formData", parameter.getIn());
31+
assertEquals("myfile", parameter.getName());
32+
assertEquals("file", parameter.getType());
33+
}
34+
35+
@Test
36+
public void shouldCreateSwaggerFiles() throws Exception {
37+
Swagger swagger = new SwaggerBuilder()
38+
.build(null, Arrays.asList(route(fileParam("files", Types.listOf(Upload.class)))));
39+
FormParameter parameter = (FormParameter) swagger
40+
.getPath("/file")
41+
.getOperationMap()
42+
.get(HttpMethod.POST)
43+
.getParameters()
44+
.get(0);
45+
assertEquals("formData", parameter.getIn());
46+
assertEquals("files", parameter.getName());
47+
assertEquals("array", parameter.getType());
48+
assertEquals("file", parameter.getItems().getType());
49+
}
50+
51+
@Test
52+
public void shouldCreateSwaggerFileSet() throws Exception {
53+
Swagger swagger = new SwaggerBuilder()
54+
.build(null, Arrays.asList(route(fileParam("fset", Types.setOf(Upload.class)))));
55+
FormParameter parameter = (FormParameter) swagger
56+
.getPath("/file")
57+
.getOperationMap()
58+
.get(HttpMethod.POST)
59+
.getParameters()
60+
.get(0);
61+
assertEquals("formData", parameter.getIn());
62+
assertEquals("fset", parameter.getName());
63+
assertEquals("array", parameter.getType());
64+
assertEquals("file", parameter.getItems().getType());
65+
}
66+
67+
private RouteMethod route(RouteParameter... params) {
68+
RouteMethod method = new RouteMethod("POST", "/file", new RouteResponse(String.class));
69+
method.parameters(Arrays.asList(params));
70+
return method;
71+
}
72+
73+
private RouteParameter fileParam(String name, Type type) {
74+
RouteParameter param = new RouteParameter(name, RouteParameter.Kind.FILE, type, null);
75+
return param;
76+
}
77+
}

0 commit comments

Comments
 (0)