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"}]

效果图:




猜你喜欢

转载自blog.csdn.net/sjc106112/article/details/78643092