功能开发,加入了昨晚失眠到2点想到的功能,文档大一统指日可待~
This commit is contained in:
@@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 文档控制器
|
||||
@@ -71,13 +72,13 @@ public class MgDocumentController {
|
||||
@PostMapping(value = "/docs")
|
||||
public void docs(HttpServletRequest request, HttpServletResponse response) {
|
||||
boolean needRestorage = true;
|
||||
String choiseDocList = request.getParameter("choiseDocList");
|
||||
String choiceDocList = request.getParameter("choiseDocList");
|
||||
// 转成set,防止重复
|
||||
Set<SwaggerResourcesInfoVo> resourcesSet = new HashSet<>();
|
||||
List<SwaggerResourcesInfoVo> resourcesSet = new LinkedList<>();
|
||||
Set<String> swaggerDocsDeleteSet = new HashSet<>();
|
||||
if (StringUtils.isNotBlank(choiseDocList)) {
|
||||
if (StringUtils.isNotBlank(choiceDocList)) {
|
||||
needRestorage = false;// 选择的则不再存入
|
||||
for (String url : choiseDocList.split(",")) {
|
||||
for (String url : choiceDocList.split(",")) {
|
||||
resourcesSet.add(new SwaggerResourcesInfoVo(url));
|
||||
}
|
||||
} else {
|
||||
@@ -142,6 +143,7 @@ public class MgDocumentController {
|
||||
if (resourceList == null || resourceList.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
resourcesInfoVo.setResourceList(resourceList);
|
||||
resourcesUrl = resourcesUrl.substring(0, resourcesUrl.lastIndexOf("/") + 1);
|
||||
for (SwaggerResource resource : resourceList) {
|
||||
String location = resource.getLocation();
|
||||
@@ -181,6 +183,8 @@ public class MgDocumentController {
|
||||
}
|
||||
}
|
||||
if (needRestorage) {
|
||||
AtomicInteger idIndex = new AtomicInteger(1);
|
||||
resourcesSet.forEach(val -> val.setId(idIndex.getAndIncrement()));
|
||||
storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesSet));
|
||||
}
|
||||
// 用默认的json解析要内存溢出,解析不了JSONObject、、就只有这样写了~
|
||||
@@ -205,10 +209,9 @@ public class MgDocumentController {
|
||||
swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList);
|
||||
}
|
||||
// 转成set,防止重复
|
||||
Set<SwaggerResourcesInfoVo> resourcesSet = new HashSet<>();
|
||||
List<SwaggerResourcesInfoVo> resourcesList = null;
|
||||
if (StringUtils.isNotBlank(swaggerResourcesStr)) {
|
||||
List<SwaggerResourcesInfoVo> resourcesList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class);
|
||||
resourcesSet.addAll(resourcesList);
|
||||
resourcesList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class);
|
||||
}
|
||||
try {
|
||||
String resourcesStr = HttpRequest.get(resourcesUrl).timeout(3000).execute().body();
|
||||
@@ -233,7 +236,9 @@ public class MgDocumentController {
|
||||
location = resourcesDomain + location;
|
||||
swaggerDocsDeleteSet.remove(location);
|
||||
}
|
||||
resourcesSet.add(new SwaggerResourcesInfoVo(resourcesUrl));
|
||||
resourcesList.add(new SwaggerResourcesInfoVo(resourcesUrl, resourceList));
|
||||
AtomicInteger idIndex = new AtomicInteger(1);
|
||||
resourcesList.forEach(val -> val.setId(idIndex.getAndIncrement()));
|
||||
} catch (Exception e) {
|
||||
// 暂不想支持直接添加地址
|
||||
// try {
|
||||
@@ -254,7 +259,7 @@ public class MgDocumentController {
|
||||
return DocResponseJson.warn("该地址查找文档失败");
|
||||
// }
|
||||
}
|
||||
storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesSet));
|
||||
storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesList));
|
||||
storageService.put(StorageKeys.SWAGGER_DOCS_DELETE_LIST, JSON.toJSONString(swaggerDocsDeleteSet));
|
||||
return DocResponseJson.ok();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.zyplayer.doc.swagger.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.zyplayer.doc.swagger.controller.vo.SwaggerResourcesInfoVo;
|
||||
import com.zyplayer.doc.swagger.framework.constant.Consts;
|
||||
import com.zyplayer.doc.swagger.framework.constant.StorageKeys;
|
||||
import com.zyplayer.doc.swagger.framework.service.MgStorageService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.swagger.web.ApiKeyVehicle;
|
||||
import springfox.documentation.swagger.web.SecurityConfiguration;
|
||||
import springfox.documentation.swagger.web.SwaggerResource;
|
||||
import springfox.documentation.swagger.web.UiConfiguration;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 承接了所有的ApiResourceController的接口
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年12月16日
|
||||
*/
|
||||
@RestController
|
||||
public class ZyplayerSwaggerController {
|
||||
|
||||
@Autowired
|
||||
private MgStorageService storageService;
|
||||
|
||||
@RequestMapping("/swagger-resources")
|
||||
public List<SwaggerResource> swaggerResources() {
|
||||
String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST);
|
||||
List<SwaggerResourcesInfoVo> resourcesInfoVoList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class);
|
||||
if (resourcesInfoVoList == null || resourcesInfoVoList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<SwaggerResource> resourceList = new LinkedList<>();
|
||||
resourcesInfoVoList.forEach(resource -> {
|
||||
resource.getResourceList().forEach(val -> {
|
||||
String location = val.getLocation();
|
||||
val.setLocation(Consts.ZYPLAYER_PROXY + resource.getId() + location);
|
||||
});
|
||||
resourceList.addAll(resource.getResourceList());
|
||||
});
|
||||
return resourceList;
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping(value = "/swagger-resources/configuration/security")
|
||||
public ResponseEntity<SecurityConfiguration> securityConfiguration() {
|
||||
SecurityConfiguration securityConfiguration = new SecurityConfiguration(null, null, null, null, null, ApiKeyVehicle.HEADER, "api_key", ",");
|
||||
return new ResponseEntity<>(securityConfiguration, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping(value = "/swagger-resources/configuration/ui")
|
||||
public ResponseEntity<UiConfiguration> uiConfiguration() {
|
||||
UiConfiguration uiConfiguration = new UiConfiguration(null);
|
||||
return new ResponseEntity<>(uiConfiguration, HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,197 +1,196 @@
|
||||
package com.zyplayer.doc.swagger.controller.param;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.Method;
|
||||
|
||||
/**
|
||||
* 请求参数对象
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
public class HttpRequestParam {
|
||||
private String url;
|
||||
private String method;
|
||||
private String header;
|
||||
private String form;
|
||||
private String body;
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
public void setHeader(String header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public String getForm() {
|
||||
return form;
|
||||
}
|
||||
|
||||
public void setForm(String form) {
|
||||
this.form = form;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public Map<String, String> getHeaderMap() {
|
||||
if (StringUtils.isBlank(header)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> headerMap = JSON.parseObject(header, new TypeReference<HashMap<String, String>>() {
|
||||
});
|
||||
return headerMap;
|
||||
}
|
||||
|
||||
public Map<String, Object> getFormMap() {
|
||||
if (StringUtils.isBlank(form)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> formMap = JSON.parseObject(form, new TypeReference<HashMap<String, Object>>() {});
|
||||
return formMap;
|
||||
}
|
||||
|
||||
public void createHttpRequest(HttpRequest request) {
|
||||
Map<String, String> headerMap = this.getHeaderMap();
|
||||
if (headerMap != null) {
|
||||
request.addHeaders(headerMap);
|
||||
if (headerMap.containsKey("Content-Type")) {
|
||||
request.contentType(headerMap.get("Content-Type"));
|
||||
}
|
||||
}
|
||||
Map<String, Object> formMap = this.getFormMap();
|
||||
if (formMap != null) {
|
||||
request.form(formMap);
|
||||
}
|
||||
if (StringUtils.isNotBlank(body) && request.getMethod() != Method.GET) {
|
||||
request.body(body);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest createRequest() {
|
||||
if("get".equalsIgnoreCase(this.method)) return get();
|
||||
if("post".equalsIgnoreCase(this.method)) return post();
|
||||
if("head".equalsIgnoreCase(this.method)) return head();
|
||||
if("options".equalsIgnoreCase(this.method)) return options();
|
||||
if("put".equalsIgnoreCase(this.method)) return put();
|
||||
if("patch".equalsIgnoreCase(this.method)) return patch();
|
||||
if("delete".equalsIgnoreCase(this.method)) return delete();
|
||||
if("trace".equalsIgnoreCase(this.method)) return trace();
|
||||
return get();
|
||||
}
|
||||
|
||||
/**
|
||||
* POST请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest post() {
|
||||
HttpRequest request = HttpRequest.post(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest get() {
|
||||
HttpRequest request = HttpRequest.get(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* HEAD请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest head() {
|
||||
HttpRequest request = HttpRequest.head(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* OPTIONS请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest options() {
|
||||
HttpRequest request = HttpRequest.options(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest put() {
|
||||
HttpRequest request = HttpRequest.put(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* PATCH请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest patch() {
|
||||
HttpRequest request = HttpRequest.patch(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest delete() {
|
||||
HttpRequest request = HttpRequest.delete(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* TRACE请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest trace() {
|
||||
HttpRequest request = HttpRequest.trace(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
}
|
||||
package com.zyplayer.doc.swagger.controller.param;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.Method;
|
||||
|
||||
/**
|
||||
* 请求参数对象
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
public class HttpRequestParam {
|
||||
private String url;
|
||||
private String method;
|
||||
private String header;
|
||||
private String form;
|
||||
private String body;
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
public void setHeader(String header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public String getForm() {
|
||||
return form;
|
||||
}
|
||||
|
||||
public void setForm(String form) {
|
||||
this.form = form;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public Map<String, String> getHeaderMap() {
|
||||
if (StringUtils.isBlank(header)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> headerMap = JSON.parseObject(header, new TypeReference<HashMap<String, String>>() {});
|
||||
return headerMap;
|
||||
}
|
||||
|
||||
public Map<String, Object> getFormMap() {
|
||||
if (StringUtils.isBlank(form)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> formMap = JSON.parseObject(form, new TypeReference<HashMap<String, Object>>() {});
|
||||
return formMap;
|
||||
}
|
||||
|
||||
public void createHttpRequest(HttpRequest request) {
|
||||
Map<String, String> headerMap = this.getHeaderMap();
|
||||
if (headerMap != null) {
|
||||
request.addHeaders(headerMap);
|
||||
if (headerMap.containsKey("Content-Type")) {
|
||||
request.contentType(headerMap.get("Content-Type"));
|
||||
}
|
||||
}
|
||||
Map<String, Object> formMap = this.getFormMap();
|
||||
if (formMap != null) {
|
||||
request.form(formMap);
|
||||
}
|
||||
if (StringUtils.isNotBlank(body) && request.getMethod() != Method.GET) {
|
||||
request.body(body);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest createRequest() {
|
||||
if("get".equalsIgnoreCase(this.method)) return get();
|
||||
if("post".equalsIgnoreCase(this.method)) return post();
|
||||
if("head".equalsIgnoreCase(this.method)) return head();
|
||||
if("options".equalsIgnoreCase(this.method)) return options();
|
||||
if("put".equalsIgnoreCase(this.method)) return put();
|
||||
if("patch".equalsIgnoreCase(this.method)) return patch();
|
||||
if("delete".equalsIgnoreCase(this.method)) return delete();
|
||||
if("trace".equalsIgnoreCase(this.method)) return trace();
|
||||
return get();
|
||||
}
|
||||
|
||||
/**
|
||||
* POST请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest post() {
|
||||
HttpRequest request = HttpRequest.post(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest get() {
|
||||
HttpRequest request = HttpRequest.get(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* HEAD请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest head() {
|
||||
HttpRequest request = HttpRequest.head(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* OPTIONS请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest options() {
|
||||
HttpRequest request = HttpRequest.options(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest put() {
|
||||
HttpRequest request = HttpRequest.put(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* PATCH请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest patch() {
|
||||
HttpRequest request = HttpRequest.patch(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest delete() {
|
||||
HttpRequest request = HttpRequest.delete(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* TRACE请求
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public HttpRequest trace() {
|
||||
HttpRequest request = HttpRequest.trace(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,50 +2,82 @@ package com.zyplayer.doc.swagger.controller.vo;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.zyplayer.doc.swagger.framework.constant.StorageKeys;
|
||||
import springfox.documentation.swagger.web.SwaggerResource;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class SwaggerResourcesInfoVo {
|
||||
public class SwaggerResourcesInfoVo implements Serializable {
|
||||
private Integer id;
|
||||
private String url;
|
||||
private String storageKey;
|
||||
private List<SwaggerResource> resourceList;
|
||||
private Date creationTime;
|
||||
private Date lastSync;
|
||||
|
||||
public SwaggerResourcesInfoVo(String url){
|
||||
|
||||
public SwaggerResourcesInfoVo() {
|
||||
|
||||
}
|
||||
|
||||
public SwaggerResourcesInfoVo(String url) {
|
||||
this.url = url;
|
||||
this.storageKey = StorageKeys.SWAGGER_OFFLINE_DOC_START + RandomUtil.simpleUUID();
|
||||
this.creationTime = new Date();
|
||||
}
|
||||
|
||||
|
||||
public SwaggerResourcesInfoVo(String url, List<SwaggerResource> resourceList) {
|
||||
this.url = url;
|
||||
this.resourceList = resourceList;
|
||||
this.storageKey = StorageKeys.SWAGGER_OFFLINE_DOC_START + RandomUtil.simpleUUID();
|
||||
this.creationTime = new Date();
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
public String getStorageKey() {
|
||||
return storageKey;
|
||||
}
|
||||
|
||||
|
||||
public void setStorageKey(String storageKey) {
|
||||
this.storageKey = storageKey;
|
||||
}
|
||||
|
||||
|
||||
public Date getCreationTime() {
|
||||
return creationTime;
|
||||
}
|
||||
|
||||
|
||||
public void setCreationTime(Date creationTime) {
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
|
||||
public Date getLastSync() {
|
||||
return lastSync;
|
||||
}
|
||||
|
||||
|
||||
public void setLastSync(Date lastSync) {
|
||||
this.lastSync = lastSync;
|
||||
}
|
||||
|
||||
public List<SwaggerResource> getResourceList() {
|
||||
return resourceList;
|
||||
}
|
||||
|
||||
public void setResourceList(List<SwaggerResource> resourceList) {
|
||||
this.resourceList = resourceList;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
package com.zyplayer.doc.swagger.framework.configuration;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@Target(value = { java.lang.annotation.ElementType.TYPE })
|
||||
@Documented
|
||||
@Import({ SwaggerCommonConfiguration.class, SpringContextUtil.class })
|
||||
public @interface EnableSwaggerMgUi {
|
||||
|
||||
/**
|
||||
* 是否自动把自身的swagger-resources加进来
|
||||
* @return 配置
|
||||
*/
|
||||
boolean selfDoc() default true;
|
||||
|
||||
/**
|
||||
* 启动后第一次访问没有数据情况下需要加载进来的swagger-resources地址
|
||||
* @return swagger-resources地址
|
||||
*/
|
||||
String[] defaultResources() default {};
|
||||
}
|
||||
package com.zyplayer.doc.swagger.framework.configuration;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.zyplayer.doc.swagger.framework.filter.ZyplayerProxyFilter;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@Target(value = {java.lang.annotation.ElementType.TYPE})
|
||||
@Documented
|
||||
@Import({SwaggerCommonConfiguration.class, SpringContextUtil.class, ZyplayerProxyFilter.class})
|
||||
public @interface EnableSwaggerMgUi {
|
||||
|
||||
/**
|
||||
* 是否自动把自身的swagger-resources加进来
|
||||
*
|
||||
* @return 配置
|
||||
*/
|
||||
boolean selfDoc() default true;
|
||||
|
||||
/**
|
||||
* 启动后第一次访问没有数据情况下需要加载进来的swagger-resources地址
|
||||
*
|
||||
* @return swagger-resources地址
|
||||
*/
|
||||
String[] defaultResources() default {};
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
package com.zyplayer.doc.swagger.framework.configuration;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
//@EnableAutoConfiguration
|
||||
@ComponentScan(basePackages = {
|
||||
"com.zyplayer.doc.swagger.controller",
|
||||
"com.zyplayer.doc.swagger.framework.service",
|
||||
})
|
||||
public class SwaggerCommonConfiguration {
|
||||
|
||||
// 不再默认开启拦截
|
||||
// @Autowired
|
||||
// private MgUiTestFilter mgUiTestFilter;
|
||||
//
|
||||
// @Bean
|
||||
// public FilterRegistrationBean mockTestFilter() {
|
||||
// FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
// registration.setFilter(mgUiTestFilter);
|
||||
// registration.addUrlPatterns("/*");
|
||||
// registration.setName("mgUiTestFilter");
|
||||
// registration.setOrder(2);
|
||||
// return registration;
|
||||
// }
|
||||
}
|
||||
package com.zyplayer.doc.swagger.framework.configuration;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
//@EnableAutoConfiguration
|
||||
@ComponentScan(basePackages = {
|
||||
"com.zyplayer.doc.swagger.controller",
|
||||
"com.zyplayer.doc.swagger.framework.service",
|
||||
})
|
||||
public class SwaggerCommonConfiguration {
|
||||
|
||||
// 不再默认开启拦截
|
||||
// @Autowired
|
||||
// private ZyplayerApiTestFilter mgUiTestFilter;
|
||||
//
|
||||
// @Bean
|
||||
// public FilterRegistrationBean mockTestFilter() {
|
||||
// FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
// registration.setFilter(mgUiTestFilter);
|
||||
// registration.addUrlPatterns("/*");
|
||||
// registration.setName("mgUiTestFilter");
|
||||
// registration.setOrder(2);
|
||||
// return registration;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.zyplayer.doc.swagger.framework.constant;
|
||||
|
||||
public class Consts {
|
||||
|
||||
public static final String ZYPLAYER_PROXY = "/zyplayer-proxy/";
|
||||
public static final String V2_API_DOCS = "/v2/api-docs";
|
||||
public static final String SWAGGER_RESOURCES = "/swagger-resources";
|
||||
}
|
||||
@@ -19,8 +19,8 @@ import com.zyplayer.doc.swagger.framework.service.MgStorageService;
|
||||
* 有需要此拦截器的请自行拷贝至自身项目,需要使过滤器生效,文档不再开启@Component<br>
|
||||
* 判断是否是模拟请求,功能需求:<br>
|
||||
* 很多时候后端定义好了接口,但还未实现,这时前端已经需要数据调试了,这时就需要用到这个过滤器了!<br>
|
||||
* 在页面上先配置好模拟返回的数据,然后在url上加入参数:mgUiTestFlag=1<br>
|
||||
* 例:http://192.168.0.249:8082/openApi/case/info?mgUiTestFlag=1<br>
|
||||
* 在页面上先配置好模拟返回的数据,然后在url上加入参数:zyplayerApiTest=1<br>
|
||||
* 例:http://192.168.0.249:8082/openApi/case/info?zyplayerApiTest=1<br>
|
||||
* 本过滤器就直接返回了之前配置的模拟数据,而不用等到后端必须把接口实现之后才能调试,或者在前端写一大段测试数据。<br>
|
||||
* <p>
|
||||
* 例:笔者的公司后端人较少,一个需求需要10个接口,需求分析完后首先就把接口、参数、返回值定义好,然后一个个的去实现。
|
||||
@@ -28,7 +28,7 @@ import com.zyplayer.doc.swagger.framework.service.MgStorageService;
|
||||
* 而不是一味的催后台,把各种锅丢给后端,然后玩自己的去了,浪费各环节等待时间。
|
||||
*/
|
||||
//@Component
|
||||
public class MgUiTestFilter implements Filter {
|
||||
public class ZyplayerApiTestFilter implements Filter {
|
||||
|
||||
@Autowired
|
||||
private MgStorageService mgStorageService;
|
||||
@@ -41,7 +41,7 @@ public class MgUiTestFilter implements Filter {
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
// 需要使用模拟值返回的标记
|
||||
String mockTestFlag = request.getParameter("mgUiTestFlag");
|
||||
String mockTestFlag = request.getParameter("zyplayerApiTest");
|
||||
if (!"1".equals(mockTestFlag)) {
|
||||
// 未开启直接跳过
|
||||
chain.doFilter(request, response);
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.zyplayer.doc.swagger.framework.filter;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.zyplayer.doc.swagger.controller.param.HttpRequestParam;
|
||||
import com.zyplayer.doc.swagger.controller.vo.SwaggerResourcesInfoVo;
|
||||
import com.zyplayer.doc.swagger.framework.constant.Consts;
|
||||
import com.zyplayer.doc.swagger.framework.constant.StorageKeys;
|
||||
import com.zyplayer.doc.swagger.framework.service.MgStorageService;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpCookie;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 请求代理过滤器
|
||||
* 使得所有的swagger-ui都可以查看所有的文档,目标是:文档大一统~
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年12月16日
|
||||
*/
|
||||
@Component
|
||||
public class ZyplayerProxyFilter implements Filter {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ZyplayerProxyFilter.class);
|
||||
|
||||
@Autowired
|
||||
private MgStorageService mgStorageService;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// String requestUrl = "http://192.168.0.249:8082/zyplayer-doc-manage/zyplayer-proxy/1/v2/api-docs";
|
||||
// int proxyIndex = requestUrl.indexOf(Consts.ZYPLAYER_PROXY);
|
||||
// if (proxyIndex < 0) {
|
||||
// return;
|
||||
// }
|
||||
// String requestUrlEnd = requestUrl.substring(proxyIndex + Consts.ZYPLAYER_PROXY.length());
|
||||
// int idIndex = requestUrlEnd.indexOf("/");
|
||||
// String idStr = requestUrlEnd.substring(0, idIndex);
|
||||
|
||||
String resource = "{\"swagger\":\"2.0\",\"host\":\"127.0.0.1:8999\",\"basePath\":\"/\",\"tags\":";
|
||||
resource = resource.replaceFirst("\"basePath\":\".*?\"", "\"basePath\":\"/xxxxx\"");
|
||||
System.out.println(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse servletResponse = (HttpServletResponse) response;
|
||||
String method = httpServletRequest.getMethod();
|
||||
String requestUrl = httpServletRequest.getRequestURL().toString();
|
||||
String bodyStr = IOUtils.toString(httpServletRequest.getInputStream(), "utf-8");
|
||||
|
||||
int proxyIndex = requestUrl.indexOf(Consts.ZYPLAYER_PROXY);
|
||||
if (proxyIndex < 0) {
|
||||
// 不是拦截接口直接跳过
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
long startTime = System.currentTimeMillis();
|
||||
String requestUrlEnd = requestUrl.substring(proxyIndex + Consts.ZYPLAYER_PROXY.length());
|
||||
int idIndex = requestUrlEnd.indexOf("/");
|
||||
String proxyUrlEnd = requestUrlEnd.substring(idIndex);
|
||||
String idStr = requestUrlEnd.substring(0, idIndex);
|
||||
Integer docId = Integer.valueOf(idStr);
|
||||
|
||||
String swaggerResourcesStr = mgStorageService.get(StorageKeys.SWAGGER_RESOURCES_LIST);
|
||||
List<SwaggerResourcesInfoVo> resourcesInfoVoList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class);
|
||||
if (resourcesInfoVoList == null || resourcesInfoVoList.isEmpty()) {
|
||||
this.send(startTime, requestUrl, servletResponse, "文档为空,请刷新重试");
|
||||
return;
|
||||
}
|
||||
// 找到真正被代理的对象
|
||||
String proxyUrl = null;
|
||||
for (SwaggerResourcesInfoVo swaggerResourcesInfoVo : resourcesInfoVoList) {
|
||||
if (Objects.equals(swaggerResourcesInfoVo.getId(), docId)) {
|
||||
proxyUrl = swaggerResourcesInfoVo.getUrl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (StringUtils.isBlank(proxyUrl)) {
|
||||
this.send(startTime, requestUrl, servletResponse, "未找到对应文档,请刷新重试");
|
||||
return;
|
||||
}
|
||||
// 组装URL
|
||||
proxyUrl = proxyUrl.replace(Consts.SWAGGER_RESOURCES, proxyUrlEnd);
|
||||
HttpRequestParam param = new HttpRequestParam();
|
||||
param.setUrl(proxyUrl);
|
||||
param.setMethod(method);
|
||||
HttpRequest httpRequest = param.createRequest();
|
||||
// 组装参数
|
||||
Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
|
||||
if (parameterMap != null && parameterMap.size() > 0) {
|
||||
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||
httpRequest.form(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
// 请求体
|
||||
if (StringUtils.isNotBlank(bodyStr)) {
|
||||
httpRequest.body(bodyStr);
|
||||
}
|
||||
// header
|
||||
Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
|
||||
if (headerNames != null) {
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String element = headerNames.nextElement();
|
||||
httpRequest.header(element, httpServletRequest.getHeader(element));
|
||||
}
|
||||
}
|
||||
// cookies
|
||||
Cookie[] cookies = httpServletRequest.getCookies();
|
||||
if (cookies != null && cookies.length > 0) {
|
||||
List<HttpCookie> httpCookieList = new LinkedList<>();
|
||||
for (int i = 0; i < cookies.length; i++) {
|
||||
HttpCookie httpCookie = new HttpCookie(cookies[i].getName(), cookies[i].getValue());
|
||||
httpCookieList.add(httpCookie);
|
||||
}
|
||||
httpRequest.cookie(httpCookieList.toArray(new HttpCookie[]{}));
|
||||
}
|
||||
String resultStr = httpRequest.execute().body();
|
||||
if (proxyUrl.indexOf(Consts.V2_API_DOCS) >= 0) {
|
||||
// "basePath":"/" 替换成 "basePath":"/zyplayer-doc-manage/zyplayer-proxy/2/",使其走代理接口
|
||||
ServletContext servletContext = httpServletRequest.getServletContext();
|
||||
Object ctx = servletContext.getAttribute("ctx");
|
||||
ctx = (ctx + Consts.ZYPLAYER_PROXY + idStr).replaceAll("//", "/");
|
||||
resultStr = resultStr.replaceFirst("\"basePath\":\".*?\"", "\"basePath\":\"" + ctx + "\"");
|
||||
// 替换host为当前项目的
|
||||
String requestUrlHost = requestUrl.substring(0, proxyIndex + Consts.ZYPLAYER_PROXY.length());
|
||||
requestUrlHost = requestUrlHost.replace("http://", "");
|
||||
requestUrlHost = requestUrlHost.substring(0, requestUrlHost.indexOf("/"));
|
||||
resultStr = resultStr.replaceFirst("\"host\":\".*?\"", "\"host\":\"" + requestUrlHost + "\"");
|
||||
}
|
||||
this.send(startTime, proxyUrl, servletResponse, resultStr);
|
||||
}
|
||||
|
||||
public void send(Long startTime, String requestUrl, HttpServletResponse response, String result) throws IOException {
|
||||
response.setStatus(200);
|
||||
// response.setContentType("application/json");
|
||||
response.addHeader("Access-Control-Allow-Origin", "*");
|
||||
response.setContentType("text/html");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setHeader("Cache-Control", "no-cache, must-revalidate");
|
||||
response.getWriter().write(result);
|
||||
Long totalTime = System.currentTimeMillis() - startTime;
|
||||
logger.error("代理请求结束,总耗时:{}ms,URI:{}", totalTime, requestUrl);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user