Skip to content

Commit 502affe

Browse files
retafrantuma
authored andcommitted
Support proper mapping of the byte array
1 parent 95c8253 commit 502affe

File tree

6 files changed

+198
-5
lines changed

6 files changed

+198
-5
lines changed

modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,20 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
309309
isPrimitive = true;
310310
}
311311
if (model == null) {
312-
PrimitiveType primitiveType = PrimitiveType.fromType(type);
313-
if (primitiveType != null) {
314-
model = PrimitiveType.fromType(type).createProperty();
315-
isPrimitive = true;
312+
if (resolvedSchemaAnnotation != null && StringUtils.isEmpty(resolvedSchemaAnnotation.type())) {
313+
PrimitiveType primitiveType = PrimitiveType.fromTypeAndFormat(type, resolvedSchemaAnnotation.format());
314+
if (primitiveType != null) {
315+
model = primitiveType.createProperty();
316+
isPrimitive = true;
317+
}
318+
}
319+
320+
if (model == null) {
321+
PrimitiveType primitiveType = PrimitiveType.fromType(type);
322+
if (primitiveType != null) {
323+
model = primitiveType.createProperty();
324+
isPrimitive = true;
325+
}
316326
}
317327
}
318328

@@ -629,7 +639,8 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
629639
propType = ((AnnotatedMethod)member).getParameterType(0);
630640
}
631641

632-
}
642+
}
643+
633644
String propSchemaName = null;
634645
io.swagger.v3.oas.annotations.media.Schema ctxSchema = AnnotationsUtils.getSchemaAnnotation(annotations);
635646
if (AnnotationsUtils.hasSchemaAnnotation(ctxSchema)) {

modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import org.apache.commons.lang3.StringUtils;
1616

1717
import java.lang.reflect.Type;
18+
import java.util.ArrayList;
19+
import java.util.Collection;
1820
import java.util.Collections;
1921
import java.util.HashMap;
2022
import java.util.Map;
@@ -149,6 +151,7 @@ public Schema createProperty() {
149151
};
150152

151153
private static final Map<Class<?>, PrimitiveType> KEY_CLASSES;
154+
private static final Map<Class<?>, Collection<PrimitiveType>> MULTI_KEY_CLASSES;
152155
private static final Map<Class<?>, PrimitiveType> BASE_CLASSES;
153156
/**
154157
* Adds support of a small number of "well-known" types, specifically for
@@ -244,6 +247,11 @@ public Schema createProperty() {
244247
addKeys(keyClasses, OBJECT, Object.class);
245248
KEY_CLASSES = Collections.unmodifiableMap(keyClasses);
246249

250+
final Map<Class<?>, Collection<PrimitiveType>> multiKeyClasses = new HashMap<>();
251+
addMultiKeys(multiKeyClasses, BYTE, byte[].class);
252+
addMultiKeys(multiKeyClasses, BINARY, byte[].class);
253+
MULTI_KEY_CLASSES = Collections.unmodifiableMap(multiKeyClasses);
254+
247255
final Map<Class<?>, PrimitiveType> baseClasses = new HashMap<>();
248256
addKeys(baseClasses, DATE_TIME, java.util.Date.class, java.util.Calendar.class);
249257
BASE_CLASSES = Collections.unmodifiableMap(baseClasses);
@@ -343,6 +351,20 @@ public static Set<String> nonSystemTypePackages() {
343351
return nonSystemTypePackages;
344352
}
345353

354+
public static PrimitiveType fromTypeAndFormat(Type type, String format) {
355+
final Class<?> raw = TypeFactory.defaultInstance().constructType(type).getRawClass();
356+
final Collection<PrimitiveType> keys = MULTI_KEY_CLASSES.get(raw);
357+
if (keys == null || keys.isEmpty() || StringUtils.isBlank(format)) {
358+
return fromType(type);
359+
} else {
360+
return keys
361+
.stream()
362+
.filter(t -> t.getCommonName().equalsIgnoreCase(format))
363+
.findAny()
364+
.orElse(null);
365+
}
366+
}
367+
346368
public static PrimitiveType fromType(Type type) {
347369
final Class<?> raw = TypeFactory.defaultInstance().constructType(type).getRawClass();
348370
final PrimitiveType key = KEY_CLASSES.get(raw);
@@ -351,6 +373,14 @@ public static PrimitiveType fromType(Type type) {
351373
return key;
352374
}
353375
}
376+
377+
final Collection<PrimitiveType> keys = MULTI_KEY_CLASSES.get(raw);
378+
if (keys != null && !keys.isEmpty()) {
379+
final PrimitiveType first = keys.iterator().next();
380+
if (!customExcludedClasses.contains(raw.getName())) {
381+
return first;
382+
}
383+
}
354384

355385
final PrimitiveType custom = customClasses.get(raw.getName());
356386
if (custom != null) {
@@ -424,6 +454,15 @@ private static <K> void addKeys(Map<K, PrimitiveType> map, PrimitiveType type, K
424454
}
425455
}
426456

457+
private static <K> void addMultiKeys(Map<K, Collection<PrimitiveType>> map, PrimitiveType type, K... keys) {
458+
for (K key : keys) {
459+
if (!map.containsKey(key)) {
460+
map.put(key, new ArrayList<>());
461+
}
462+
map.get(key).add(type);
463+
}
464+
}
465+
427466
private static class DateStub {
428467
private DateStub() {
429468
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.swagger.v3.jaxrs2;
2+
3+
import java.io.IOException;
4+
5+
import org.testng.annotations.Test;
6+
7+
import io.swagger.v3.jaxrs2.annotations.AbstractAnnotationTest;
8+
import io.swagger.v3.jaxrs2.resources.BinaryParameterResource;
9+
10+
public class BinaryParameterResourceTest extends AbstractAnnotationTest {
11+
@Test(description = "check binary model serialization") // tests issue #2466
12+
public void shouldSerializeBinaryParameter() throws IOException {
13+
compareAsYaml(BinaryParameterResource.class, getOpenAPIAsString("BinaryParameterResource.yaml"));
14+
}
15+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package io.swagger.v3.jaxrs2.resources;
2+
3+
import javax.ws.rs.Consumes;
4+
import javax.ws.rs.POST;
5+
import javax.ws.rs.Path;
6+
import javax.ws.rs.core.Context;
7+
import javax.ws.rs.core.MediaType;
8+
import javax.ws.rs.core.Response;
9+
import javax.ws.rs.core.UriInfo;
10+
11+
import io.swagger.v3.jaxrs2.resources.model.Item;
12+
import io.swagger.v3.oas.annotations.Operation;
13+
import io.swagger.v3.oas.annotations.Parameter;
14+
import io.swagger.v3.oas.annotations.headers.Header;
15+
import io.swagger.v3.oas.annotations.media.Content;
16+
import io.swagger.v3.oas.annotations.media.Schema;
17+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
18+
19+
@Path("/")
20+
public class BinaryParameterResource {
21+
@Consumes({ MediaType.APPLICATION_JSON })
22+
@Path("/binary")
23+
@POST
24+
@Operation(
25+
summary = "Create new item",
26+
description = "Post operation with entity in a body",
27+
responses = {
28+
@ApiResponse(
29+
content = @Content(
30+
schema = @Schema(implementation = Item.class),
31+
mediaType = MediaType.APPLICATION_JSON
32+
),
33+
headers = @Header(name = "Location"),
34+
responseCode = "201"
35+
)
36+
}
37+
)
38+
public Response createItem(@Context final UriInfo uriInfo, @Parameter(required = true) final Item item) {
39+
return Response
40+
.created(uriInfo.getBaseUriBuilder().path(item.getName()).build())
41+
.entity(item).build();
42+
}
43+
44+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.swagger.v3.jaxrs2.resources.model;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
public class Item {
6+
private String name;
7+
private String value;
8+
private byte[] bytes;
9+
@Schema(format = "binary")
10+
private byte[] binary;
11+
12+
public Item() {
13+
}
14+
15+
public void setBinary(byte[] binary) {
16+
this.binary = binary;
17+
}
18+
19+
public byte[] getBinary() {
20+
return binary;
21+
}
22+
23+
public void setName(String name) {
24+
this.name = name;
25+
}
26+
27+
public String getName() {
28+
return name;
29+
}
30+
31+
public void setValue(String value) {
32+
this.value = value;
33+
}
34+
35+
public String getValue() {
36+
return value;
37+
}
38+
39+
public void setBytes(byte[] bytes) {
40+
this.bytes = bytes;
41+
}
42+
43+
public byte[] getBytes() {
44+
return bytes;
45+
}
46+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
openapi: 3.0.1
2+
paths:
3+
/binary:
4+
post:
5+
summary: Create new item
6+
description: Post operation with entity in a body
7+
operationId: createItem
8+
requestBody:
9+
content:
10+
application/json:
11+
schema:
12+
$ref: '#/components/schemas/Item'
13+
required: true
14+
responses:
15+
"201":
16+
headers:
17+
Location:
18+
style: simple
19+
content:
20+
application/json:
21+
schema:
22+
$ref: '#/components/schemas/Item'
23+
components:
24+
schemas:
25+
Item:
26+
type: object
27+
properties:
28+
name:
29+
type: string
30+
value:
31+
type: string
32+
bytes:
33+
type: string
34+
format: byte
35+
binary:
36+
type: string
37+
format: binary
38+

0 commit comments

Comments
 (0)