2017-08-23 154 views
10

我用招搖用於記錄一個RestEasy的API的端點,以及我所服務使用servlet的swagger.json描述用這樣的方法:服務swagger.json從資源類

public void init(ServletConfig config) throws ServletException 
{ 
    super.init(config); 
    BeanConfig beanConfig = new BeanConfig(); 
    beanConfig.setHost("localhost:8080");  
    beanConfig.setBasePath("/api"); 
    beanConfig.setResourcePackage("my.rest.resources"); 
    beanConfig.setScan(true);  
} 

,我可以訪問swagger.jsonlocalhost:8080/api/swagger.json。 然而,我的合作者想避免比RestEasy的servlet的其他額外的servlet,我不知道我是否能服務於招搖從資源類生成的方法JSON,這樣的事情:

@GET 
@Path("/myswagger") 
@Produces("application/json") 
public String myswagger(@Context UriInfo uriInfo) 
{ 
    Swagger swagger = new Swagger(); 
    // Do something to retrieve the Swagger Json as a string 
    // ... 
    return(swaggerJsonString); 
} 

,然後訪問swagger通過localhost:8080/api/myswagger生成json。這可能嗎?

回答

4

可能的和非常簡單的

import com.fasterxml.jackson.core.JsonProcessingException; 
import io.swagger.annotations.*; 
import io.swagger.jaxrs.Reader; 
import io.swagger.models.Swagger; 
import io.swagger.util.Json; 

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 
import java.net.HttpURLConnection; 
import java.util.HashSet; 
import java.util.Set; 


@SwaggerDefinition(
     info = @Info(
       title = "title", 
       version = "0.2", 
       description = "description", 
       termsOfService = "termsOfService", 
       contact = @Contact(
         name = "contact", 
         url = "http://contact.org", 
         email = "[email protected]" 
       ), 
       license = @License(
         name = "Apache2", 
         url = "http://license.org/license" 
       ) 
     ), 
     host = "host.org", 
     basePath = "", 
     schemes = SwaggerDefinition.Scheme.HTTPS 
) 
public class SwaggerMain { 

    @Path("/a") 
    @Api(value = "/a", description = "aaa") 
    public class A { 

     @GET 
     @Path("/getA") 
     @Produces(MediaType.APPLICATION_JSON) 
     @ApiOperation(value = "Method for A.") 
     @ApiResponses(value = { 
       @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), 
       @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized"), 
       @ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = "Not found"), 
       @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal server problems") 
     }) 
     public String getA() { 
      return "Hello, A"; 
     } 

    } 

    @Path("/b") 
    @Api(value = "/b", description = "bbb") 
    public class B { 
     @GET 
     @Path("/getA") 
     @Produces(MediaType.APPLICATION_JSON) 
     @ApiOperation(value = "Method for B.") 
     @ApiResponses(value = { 
       @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), 
       @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized"), 
       @ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = "Not found"), 
       @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal server problems") 
     }) 
     public String getA() { 
      return "Hello, B"; 
     } 
    } 

    public static void main(String[] args) { 
     Set<Class<?>> classes = new HashSet<Class<?>>(); 
     classes.add(SwaggerMain.class); 
     classes.add(A.class); 
     classes.add(B.class); 
     Swagger swagger = new Reader(new Swagger()).read(classes); 
     try { 
      System.out.println(Json.mapper().writeValueAsString(swagger));; 
     } catch (JsonProcessingException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

給出JSON:

{ 
    "swagger": "2.0", 
    "info": { 
    "description": "description", 
    "version": "0.2", 
    "title": "title", 
    "termsOfService": "termsOfService", 
    "contact": { 
     "name": "contact", 
     "url": "http://contact.org", 
     "email": "[email protected]" 
    }, 
    "license": { 
     "name": "Apache2", 
     "url": "http://license.org/license" 
    } 
    }, 
    "host": "host.org", 
    "tags": [ 
    { 
     "name": "a" 
    }, 
    { 
     "name": "b" 
    } 
    ], 
    "schemes": [ 
    "https" 
    ], 
    "paths": { 
    "https://stackoverflow.com/a/getA": { 
     "get": { 
     "tags": [ 
      "a" 
     ], 
     "summary": "Method for A.", 
     "description": "", 
     "operationId": "getA", 
     "produces": [ 
      "application/json" 
     ], 
     "parameters": [], 
     "responses": { 
      "200": { 
      "description": "OK" 
      }, 
      "401": { 
      "description": "Unauthorized" 
      }, 
      "404": { 
      "description": "Not found" 
      }, 
      "500": { 
      "description": "Internal server problems" 
      } 
     } 
     } 
    }, 
    "/b/getA": { 
     "get": { 
     "tags": [ 
      "b" 
     ], 
     "summary": "Method for B.", 
     "description": "", 
     "operationId": "getA", 
     "produces": [ 
      "application/json" 
     ], 
     "parameters": [], 
     "responses": { 
      "200": { 
      "description": "OK" 
      }, 
      "401": { 
      "description": "Unauthorized" 
      }, 
      "404": { 
      "description": "Not found" 
      }, 
      "500": { 
      "description": "Internal server problems" 
      } 
     } 
     } 
    } 
    } 
} 
+0

這工作得很好,謝謝!我通過返回'Swagger'對象來設法服務於端點的swagger json! – user1981275

+0

我喜歡Hugues M.和egorlitvinenko的答案,兩種解決方案都能正常工作。我會接受egorlitvinenko的解決方案,因爲他的解決方案實際上就是我所要求的。 – user1981275

1

假設您可以從您的Java應用程序訪問json文件,那麼您應該只能讀取json文件並將其作爲方法的字符串返回值返回。

作爲一個超級簡單的例子:

String swaggerJsonString = new String(Files.readAllBytes(Paths.get("swagger.json"))); 

你必須弄清楚如何找到該文件在您的應用程序的路徑。

2

因此,您嘗試使用automatic scanning and registration將swagger連接到您的resteasy應用程序。

使用自動掃描時,swagger-core無法自動檢測資源。要解決這個問題,你必須告訴swagger-core掃描哪些軟件包。建議的解決方案是使用BeanConfig方法(很可能是作爲Servlet)。

所以你做到了這一點,但現在你想要的不需要單獨的servlet。

您應該不會嘗試手動將swagger掛接到您的應用程序的每個資源提供商&。你應該用@Api(我假設你已經這麼做了)註釋它們,然後,因爲你使用RESTEasy,所以你可以將你的BeanConfig移動到你現有的resteasy Application或者自定義的那個,在任何情況下都會被採用由您現有的resteasy servlet來維護。請參閱using a custom Application subclass

import io.swagger.jaxrs.config.BeanConfig; 
import javax.ws.rs.core.Application; 
import java.util.HashSet; 
import java.util.Set; 

public class MyApplication extends Application { 

    public MyApplication() { 
     BeanConfig beanConfig = new BeanConfig(); 
     beanConfig.setVersion("1.0"); 
     beanConfig.setSchemes(new String[] { "http" }); 
     beanConfig.setTitle("My API"); // <- mandatory 
     beanConfig.setHost("localhost:8080");  
     beanConfig.setBasePath("/api"); 
     beanConfig.setResourcePackage("my.rest.resources"); 
     beanConfig.setScan(true); 
    } 

    @Override 
    public Set<Class<?>> getClasses() { 
     Set<Class<?>> set = new HashSet<Class<?>>(); 
     set.add(MyRestResourceFoo.class); // Add your own application's resources and providers 
     set.add(io.swagger.jaxrs.listing.ApiListingResource.class); 
     set.add(io.swagger.jaxrs.listing.SwaggerSerializers.class); 
     return set; 
    } 
} 

你的資源&商應保持乾淨的代碼揚鞭除了註釋。例如,下面是一個簡單的echo服務:

import io.swagger.annotations.Api; 
import io.swagger.annotations.ApiOperation; 

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.core.Response; 

@Api 
@Path("/echo") 
public class EchoRestService { 

    @ApiOperation(value = "Echoes message back") 
    @GET 
    @Path("/{param}") 
    public Response printMessage(@PathParam("param") String msg) { 
     String result = "Echoing: " + msg; 
     return Response.status(200).entity(result).build(); 
    } 
} 

接着參觀http://localhost:8080/api/swagger.json得到JSON字符串(與.yaml相同)。

我推an example to GitHub,這是非常簡單的,並根據您現有的應用程序,你可能會需要更多的細節,但它可以幫助您開始。

+0

謝謝您的回答,您的GitHub例子,只保留註解中的資源類的提示!我將swagger'beanconfig'添加到我的'Application'子類中,這似乎工作正常!如果你不介意的話,我有兩個問題(下一個評論) – user1981275

+0

在''getClasses'子Application',您明確指定的資源類。這甚至是必要的嗎?它工作正常的我,如果我只是'返回null' ... – user1981275

+0

我的第二個問題是有點小白問題(新到Java和Web的東西)......我想玩的SwagEasy例如,但我不知道如何部署(我正在使用wildfly)。 8080/swageasy':當我複製'swageasy.war'到wildfly的'獨立/部署/'目錄,我不能在本地主機'找資源。我也嘗試過'wildfly-maven-plugin',但沒有成功。我錯過了什麼? – user1981275