Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey 2 + Swagger returns empty list APIs

We are using spring 4.x and swagger-jersey2-jaxrs_2.10. Swagger doesn't list my APIs, it always returns the version details only.

pom.xml

<dependency>
    <groupId>com.wordnik</groupId>
    <artifactId>swagger-jersey2-jaxrs_2.10</artifactId>
    <version>1.3.13</version>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-server</artifactId>
    <version>2.23.2</version>
</dependency>

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet-core</artifactId>
    <version>2.23.2</version>
</dependency>

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>2.23.2</version>
</dependency>

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.23.2</version>
</dependency>

 <dependency>
     <groupId>org.glassfish.jersey.ext</groupId>
     <artifactId>jersey-spring3</artifactId>
     <version>2.23.2</version>
     <exclusions>
         <exclusion>
             <groupId>org.springframework</groupId>
             <artifactId>spring-beans</artifactId>
         </exclusion>
         <exclusion>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
         </exclusion>
         <exclusion>
             <groupId>org.springframework</groupId>
             <artifactId>spring-core</artifactId>
         </exclusion>
         <exclusion>
             <groupId>org.springframework</groupId>
             <artifactId>spring-web</artifactId>
         </exclusion>
         <exclusion>
              <groupId>org.springframework</groupId>
              <artifactId>spring-aop</artifactId>
         </exclusion>
     </exclusions>
</dependency>

web.xml

 <filter>
        <filter-name>SpringApplication</filter-name>
        <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>

        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>xxx.xxx.xxx.filter.JerseyApiSpringFilter</param-value>
        </init-param>

        <init-param>
            <param-name>jersey.config.servlet.filter.forwardOn404</param-name>
            <param-value>false</param-value>
        </init-param>

        <init-param>
            <param-name>jersey.config.servlet.filter.staticContentRegex</param-name>
            <param-value>/docs/.*</param-value>
        </init-param>
    </filter>

Resource class

@Path("/listApi")
@Component
@Scope("request")
@Api(value = "/listApi", description = "List API")
@Produces({"application/json"})
public class ListApiResource {

    @GET
    @Path("/")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "Retrieve all list of apps", response = listDto.class)
    public Response getAllApps (@QueryParam("appId") int appId) {

          // code
    }
}

ResourceConfig class

public class JerseyApiSpringFilter extends ResourceConfig {
        static {
    //        JaxrsApiReader.setFormatString("");
        }

        public JerseyApiSpringFilter() {

            packages("com.xxx.xxxx.xxxxxx.resources");
            register(RequestContextFilter.class);
            register(ApiListingResource.class);
            register(ApiListingResourceJSON.class);
            register(JerseyApiDeclarationProvider.class);
            register(JerseyResourceListingProvider.class);
            register(MultiPartFeature.class);
            register(JacksonFeature.class);
        }

My application basebath/api-docs returns

{
    "apiVersion": "1.0.0",
    "swaggerVersion": "1.2",
}
like image 926
SST Avatar asked Aug 19 '16 07:08

SST


2 Answers

Try to add this to your resource class (constructor):

    register(ApiListingResource.class);
    register(SwaggerSerializers.class);

    BeanConfig beanConfig = new BeanConfig();
    beanConfig.setVersion("1.0.0");
    beanConfig.setSchemes(new String[]{"http"});
    beanConfig.setBasePath("/api"); //or insert your base path (see main Jersey app class)
    beanConfig.setResourcePackage("com.xxx.where.your.endpoints");
    beanConfig.setScan(true);
    beanConfig.setPrettyPrint(true);
like image 90
kosbr Avatar answered Oct 12 '22 04:10

kosbr


I had the same problem and used sth like below.

I have a bean that contains a list of possible values generated at app start via config. Swagger should show the list, but this does not work.

@GET
@Path("info/types")
@PermitAll
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Possible bean types", notes = "List all available bean types",
        response = BeanTypesList.class, responseContainer = "List")
@ApiResponses(value = { @ApiResponse(code = 200, message = "List of all available bean types",
        response = BeanTypesList.class) })
@Timed
@ExceptionMetered
@CacheControl(maxAge = 6, maxAgeUnit = TimeUnit.HOURS)
public List<BeanType> getBeanTypes() throws JsonProcessingException {
    return new ArrayList<BeanType>(BeanType.values());
}

    public class SwaggerClassHelper {

    @ApiModel(value = "BeanTypesList", description = "Overview of possible bean types")
    public class BeanTypesList {

        @ApiModelProperty(value = "List of several possible bean types.", required = true)
        private List<BeanType> types;

        @JsonCreator
        public BeanTypesList(
                List<BeanType> types) {
            this.types = types;
        }

        public List<BeanType> getTypes() {
            return this.types;
        }

        @JsonIgnore
        @Override
        public String toString() {
            return ReflectionToStringBuilder.toString(this);
        }
    }
}

@ApiModel(value = "Bean type", description = "Represents the type of a bean.")
public final class BeanType {

    @JsonIgnore
    private static Set<String> names = new HashSet<String>();

    @JsonProperty("name")
    private String name;

    private BeanType(
            List<String> names) {
        synchronized (BeanType.names) {
            BeanType.names.addAll(names);
        }
    }

    private BeanType(
            String name) {
        this.name = name;
    }

    //... other methods
}

I know its not the wanted solution if you use swagger, but you can specify the input/output via the response fields!

like image 37
hiaclibe Avatar answered Oct 12 '22 03:10

hiaclibe