2017-08-23 23 views
10

tôi sử dụng vênh vang cung cấp tư liệu điểm cuối của một API resteasy, và tôi phục vụ swagger.json mô tả cách sử dụng một servlet với một phương pháp như thế này:phục vụ swagger.json từ lớp tài nguyên

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);  
} 

và tôi có thể truy cập vào swagger.json tại localhost:8080/api/swagger.json. Tuy nhiên, cộng tác viên của tôi muốn tránh servlets thêm khác so với servlet resteasy, và tôi tự hỏi, nếu tôi có thể phục vụ vênh vang tạo json từ một phương pháp từ một lớp tài nguyên, một cái gì đó như thế này:

@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); 
} 

và sau đó truy cập con dao găm tạo ra json qua localhost:8080/api/myswagger. Điều này có thể không?

Trả lời

4

thể và khá đơn giản

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(); 
     } 
    } 

} 

Cho 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

Điều này hoạt động rất tốt, cảm ơn bạn! Tôi quản lý để phục vụ json vênh vang từ một điểm cuối bằng cách chỉ trả về đối tượng 'Swagger'! – user1981275

+0

Tôi thích cả hai câu trả lời của Hugues M. và egorlitvinenko và cả hai giải pháp đều hoạt động tốt. Tôi sẽ chấp nhận giải pháp của egorlitvinenko bởi vì giải pháp của anh ấy thực sự là những gì tôi yêu cầu. – user1981275

1

Giả sử bạn có quyền truy cập vào tệp json từ ứng dụng java của mình, bạn chỉ có thể đọc trong tệp json và trả về giá trị trả về String của phương thức của bạn.

Như một ví dụ siêu đơn giản:

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

Bạn sẽ phải tìm ra cách để tìm con đường của tập tin trong ứng dụng của bạn.

2

Vì vậy, bạn đã cố gắng nâng cấp lên ứng dụng của bạn bằng cách sử dụng automatic scanning and registration.

Khi sử dụng tính năng quét tự động, lõi dao găm không thể tự động phát hiện tài nguyên. Để giải quyết vấn đề đó, bạn phải nói với lõi lếch mà các gói cần quét. Giải pháp được đề xuất là sử dụng phương thức BeanConfig (rất có thể là Servlet).

Vì vậy, bạn đã làm điều đó, nhưng bây giờ bạn muốn giống nhau mà không cần một servlet riêng biệt.

Bạn có lẽ không nên cố gắng tự hooking vênh vênh vào từng tài nguyên & nhà cung cấp ứng dụng của bạn. Bạn chỉ cần chú thích chúng với @Api (Tôi giả sử bạn đã làm điều đó), và sau đó, vì bạn sử dụng RESTEasy, bạn có thể di chuyển BeanConfig của mình sang số đang chờ sẵn có Application hoặc tùy chỉnh, trong mọi trường hợp sẽ được thực hiện chăm sóc bởi servlet an toàn hiện tại của bạn. Xem 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; 
    } 
} 

Các nguồn của bạn & các nhà cung cấp phải luôn sạch sẽ mã Swagger ngoại trừ chú thích. Ví dụ, đây là một dịch vụ âm vang đơn giản:

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(); 
    } 
} 

Sau đó tham quan http://localhost:8080/api/swagger.json để có được những chuỗi JSON (cùng với .yaml).

Tôi đã đẩy an example to GitHub, nó rất đơn giản và tùy thuộc vào ứng dụng hiện tại của bạn có thể bạn sẽ cần thêm một chút chi tiết, nhưng nó có thể giúp bạn bắt đầu.

+0

Cám ơn câu trả lời của bạn, ví dụ github của bạn và gợi ý để giữ chỉ chú thích trong các lớp tài nguyên! Tôi đã thêm chữ 'beanconfig' vào lớp con 'Application' của tôi và điều này dường như hoạt động tốt! Nếu bạn không quan tâm, tôi có thêm hai câu hỏi (ý kiến ​​tiếp theo) – user1981275

+0

Trong lớp con 'getClasses'' Application', bạn chỉ định rõ ràng các lớp tài nguyên. Điều này có cần thiết không? Nó hoạt động tốt cho tôi nếu tôi chỉ 'trả lại null' ... – user1981275

+0

Câu hỏi thứ hai của tôi là một câu hỏi noob (mới đối với Java và các công cụ web) ... Tôi muốn chơi xung quanh với ví dụ SwagEasy, nhưng tôi không biết làm thế nào để triển khai (tôi đang sử dụng wildfly). Khi tôi sao chép 'swageasy.war' vào thư mục' standalone/deployments/'của wildfly, tôi không thể tìm thấy tài nguyên tại' localhost: 8080/swageasy'. Tôi cũng đã thử 'wildfly-maven-plugin' và không thành công. Tôi đang thiếu gì? – user1981275

Các vấn đề liên quan