Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

byte[] operation responses / model properties modelled incorrectly #422

Open
beaumkr opened this issue Feb 2, 2017 · 3 comments
Open

byte[] operation responses / model properties modelled incorrectly #422

beaumkr opened this issue Feb 2, 2017 · 3 comments

Comments

@beaumkr
Copy link

beaumkr commented Feb 2, 2017

I ran into an issue that's well described in a known SpringFox bug:

springfox/springfox#1605

TL;DR; a byte[] is modelled in swagger file as an Array of byte[].
=> when using swagger codegen you'd end up with 'List<byte[]>' instead of simply 'byte[]'.

I fixed it by defining an additional ModelConverter that verifies if it's a byte[] and then returns a ByteArrayProperty:

`

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.ArrayType;
import com.fasterxml.jackson.databind.type.SimpleType;
import io.swagger.converter.ModelConverter;
import io.swagger.converter.ModelConverterContext;
import io.swagger.jackson.AbstractModelConverter;
import io.swagger.models.properties.ByteArrayProperty;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Iterator;

public class ByteArrayFixerModelConverter extends AbstractModelConverter implements ModelConverter {
public ByteArrayFixerModelConverter() {
super(Json.mapper());
}

public Property resolveProperty(Type type, ModelConverterContext context, Annotation[] annotations,
        Iterator<ModelConverter> chain) {
    if(isByteArray(type)) {
        //bypass the chain! It would convert the ByteArrayProperty to an Array of ByteArrayProperty (bug in ModelModifier I think)
        return new ByteArrayProperty();
    }
    Property property = null;
    if (chain.hasNext()) {
        property = (chain.next()).resolveProperty(type, context, annotations, chain);
    }

    return property;

}

private boolean isByteArray(Type type) {
    boolean ret = type instanceof Class && type == byte[].class;
    if(!ret && type instanceof ArrayType){
        ArrayType at = (ArrayType) type;
        JavaType contentType = at.getContentType();
        if(contentType instanceof SimpleType){
            SimpleType st = (SimpleType) contentType;
            ret = st.getRawClass() == byte.class;
        }
    }
    return ret;
}

}
`

and it helped returning my operation returns and my model properties having the correct format.

I guess this should be solved in the original Swagger ModelResolver/ModelConverter classes to handle this correctly but I'm not venturing in those :)

Maybe it would be a good idea to 'wrap' those modelresolvers or always include an extra modelresolver to fix this in the swagger maven plugin (which I like a lot!)

@Breina
Copy link

Breina commented Jan 17, 2020

It does this for Request bodies as well. Here is the fix for version 2.0.10:

package com.awesome.swagger;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.ArrayType;
import com.fasterxml.jackson.databind.type.SimpleType;
import io.swagger.v3.core.converter.AnnotatedType;
import io.swagger.v3.core.converter.ModelConverter;
import io.swagger.v3.core.converter.ModelConverterContext;
import io.swagger.v3.core.jackson.AbstractModelConverter;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.models.media.ByteArraySchema;
import io.swagger.v3.oas.models.media.Schema;

import java.lang.reflect.Type;
import java.util.Iterator;

public class ByteArrayFixerModelConverter extends AbstractModelConverter {

    public ByteArrayFixerModelConverter() {
        super(Json.mapper());
    }

    @Override
    public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
        if (isByteArray(type)) {
            //bypass the chain! It would convert the ByteArrayProperty to an Array of ByteArrayProperty (bug in ModelModifier I think)
            return new ByteArraySchema();
        }
        return chain.hasNext()
                ? chain.next().resolve(type, context, chain)
                : null;

    }

    private boolean isByteArray(AnnotatedType annotatedType) {
        Type type = annotatedType.getType();
        boolean ret = type instanceof Class && type == byte[].class;
        if (!ret && type instanceof ArrayType) {
            ArrayType at = (ArrayType) type;
            JavaType contentType = at.getContentType();
            if (contentType instanceof SimpleType) {
                SimpleType st = (SimpleType) contentType;
                ret = st.getRawClass() == byte.class;
            }
        }
        return ret;
    }

}
}

And don't forget to enable it in the maven configuration:

<plugin>
    <groupId>io.swagger.core.v3</groupId>
    <artifactId>swagger-maven-plugin</artifactId>
    <version>${swagger-version}</version>
    <configuration>
        <modelConverterClasses>com.awesome.swagger.ByteArrayFixerModelConverter</modelConverterClasses>
    </configuration>
</plugin>

@inb18
Copy link

inb18 commented Aug 9, 2022

Hi , I am also facing the same issue with
com.github.kongchen
swagger-maven-plugin
3.1.8

com.msb.rest.ByteArrayFixerModelConverter

@campidelli-wcq
Copy link

Same thing here, almost 7 years after 😆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants