1. 程式人生 > >swagger2 離線文件 文件中心搭建 json swagger 自動生成api文件

swagger2 離線文件 文件中心搭建 json swagger 自動生成api文件

最近找了一個自動生成api文件的工具swagger,相對swaggerEdit就不說了。個人比較懶,還是自動生成來的便捷,尤其是老專案,新專案在初期可能會維護,但是到了後期就很難保證了。所以,那些需要一些特殊配置說明的文件工具就不提了。

這篇文章主要是在swagger2 swagger UI的基礎上結合nginx解決跨域來實現統一的api文件中心,至於如何搭建swagger2請自行百度。

使用swagger2生成離線文件比較麻煩,尤其是非springcloud專案(具體實現方式,請自行百度)。本文另闢蹊徑,通過修改swagger部分js指令碼檔案、提供統一的資源載入路徑、使用nginx反向代理解決swagger測試跨域問題,來搭建一個統一的api文件中心繫統。

首先說一下swagger的jar包:

其他自行百度,主要說一下swagger的請求流程:

swaggerUI的靜態檔案:

springfox-swagger-ui-2.6.1.jar  解壓縮開啟後在META-INF\resources下面就可以看到我們訪問的html頁以及靜態檔案。

                        swagger2的幾個資源服務controller:

swagger-resources//configuration/security

swagger-resources/configuration/ui:控制頁面展示效果

swagger-resources/:比較重要,這個也是我們要覆蓋重寫的主要協議

  所在jar包:springfox-swagger-common-2.6.1.jar

controller類路徑: springfox.documentation.swagger.web.ApiResourceController

                         最重要的程式碼路徑,生成api文件的服務:

jar包:springfox-swagger2-2.6.1.jar

controller類路徑:springfox.documentation.swagger2.web.Swagger2Controller

我們要搭建中心api文件,或者離線文件,那就需要更改js檔案,把資源路徑修改為統一的服務路徑或者靜態json(訪問/v2/api-docs可以獲取介面描述json)檔案。

貼程式碼:重寫swagger-resources服務和提供統一的api-docs文件(swagger-resources提供的location就是生成介面描述頁面資料的來源訪問路徑):

@RequestMapping("my")
@RestController
public class SwaggerController {
	
	private static Logger logger = LoggerFactory.getLogger(SwaggerController.class);
	
	private static Map<String,SwaggerResource> resourceMap = new HashMap<String,SwaggerResource>();

	public static void getDocJson(){
		String filename = "apidoc.json";
		Type type =new TypeToken<Map<String,SwaggerResource>>(){}.getType();  
		resourceMap = new Gson().fromJson(
				new InputStreamReader(SwaggerController.class.getClassLoader().getResourceAsStream(filename),Charset.forName("UTF-8")),type);
	}
	static{
		getDocJson();
	}

	@RequestMapping("/swagger-resources")
	public ResponseEntity<List<SwaggerResource>> swaggerResources() {
		getDocJson();
		List<SwaggerResource> swaggerResources = new ArrayList<SwaggerResource>();
		if(resourceMap!=null&&resourceMap.size()>0){
			for (String key : resourceMap.keySet()) {
				SwaggerResource resource = resourceMap.get(key);
				swaggerResources.add(resource);
				if(StringUtils.isBlank(resource.getLocation())){
					resource.setLocation("/my/apidoc/"+key);
				}
			}
		}
		/*SwaggerResource resource = new SwaggerResource();
		resource.setName("default");
		resource.setLocation("/v2/api-docs");
		resource.setSwaggerVersion("2.0");
		swaggerResources.add(resource);
		
		resource = new SwaggerResource();
		resource.setName("本地檔案");
		resource.setLocation("/apidoc/Goods_0.0.1.json");
		resource.setSwaggerVersion("0.0.1");
		swaggerResources.add(resource);
		
		resource = new SwaggerResource();
		resource.setName("遠端測試");
		resource.setLocation("http://127.0.0.1/Goods_0.0.1.json");
		resource.setSwaggerVersion("0.0.1");
		swaggerResources.add(resource);*/
		
	    return new ResponseEntity<List<SwaggerResource>>(swaggerResources, HttpStatus.OK);
	  }
	  
	  @RequestMapping("/apidoc/{id}")
	  public String findJsonDocs1(@PathVariable("id")String id) {
		  SwaggerResource resource = resourceMap.get(id);
		  String swagger = "";
		  if(StringUtils.isNotBlank(resource.getPath())){
			  RestTemplate template = new RestTemplate();
			  ResponseEntity<String> body = template.exchange(resource.getPath(), HttpMethod.GET, null, String.class);
			  try {
				return new String(body.getBody().getBytes("iso8859-1"),"utf-8");
			} catch (UnsupportedEncodingException e) {
				logger.error("遠端獲取資料轉碼異常(findJsonDocs1):",  e);
			}
		  }else if(StringUtils.isNotBlank(resource.getFileName())){
			  try {
				InputStreamReader in = new InputStreamReader(SwaggerController.class.getClassLoader().getResourceAsStream(resource.getFileName()),Charset.forName("UTF-8"));
				BufferedReader reader = new BufferedReader(in);
				String tmp = null;
				StringBuilder sb = new StringBuilder();
				while((tmp = reader.readLine()) != null){
					sb.append(tmp);
				}
				swagger = sb.toString();
			} catch (IOException e) {
				logger.error("讀取檔案異常(findJsonDocs1):",  e);
			}
	        return swagger;
		  }
		  return JSONObject.toJSONString( new Swagger());
	  }
}

提供的配置檔案:apidoc.json

{
  "1":{"name":"default","location":"/v2/api-docs","swaggerVersion":"2.0","host":"http://localhost:8080/","path":"","fileName":""},
  "2":{"name":"本地檔案","location":"","swaggerVersion":"2.0","host":"http://localhost:8080","path":"","fileName":"Goods_0.0.1.json"},
  "3":{"name":"遠端檔案","location":"","swaggerVersion":"2.0","host":"http://127.0.0.1","path":"http://127.0.0.1/Goods_0.0.1.json","fileName":""}
}
其中,path表示遠端http協議路徑,fileName表示本地資原始檔路徑。

對應的Bean實體類:

public class SwaggerResource extends springfox.documentation.swagger.web.SwaggerResource{

	/**
	 * 域名埠
	 */
	private String host;
	
	/**
	 * 遠端資源路徑
	 */
	private String path;
	
	/**
	 * 本地資源
	 */
	private String fileName;

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	
	
}

貼一下改寫的js檔案:springfox.js:

  function initializeBaseUrl() {
    var relativeLocation = springfox.baseUrl();

    $('#input_baseUrl').hide();

    $.getJSON(relativeLocation + "/my/swagger-resources", function(data) {

      var $urlDropdown = $('#select_baseUrl');
      $urlDropdown.empty();
      $.each(data, function(i, resource) {
        var option = $('<option></option>')
            .attr("value", maybePrefix(resource.location, relativeLocation))
            .text(resource.name + " (" + resource.location + ")");
        $urlDropdown.append(option);
      });
      $urlDropdown.change();
    });

  }
這是springfox.js的最後一個函式(initializeBaseUrl),如果是搭建中心的api文件系統,更改/swagger-resources路徑為我們自定義的服務路徑/my/swagger-resources即可。

如果是搭建離線的文件,講這部分程式碼改寫成訪問靜態資原始檔就可以了。

/swagger-resources資料格式:

[{"name":"default","location":"/v2/api-docs","swaggerVersion":"2.0"}]

效果圖: