项目导入初始化
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
package com.mg.swagger.controller;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.mg.swagger.framework.configuration.EnableSwaggerMgUi;
|
||||
import com.mg.swagger.framework.configuration.SpringContextUtil;
|
||||
import com.mg.swagger.framework.constant.StorageKeys;
|
||||
import com.mg.swagger.framework.constant.Toast;
|
||||
import com.mg.swagger.framework.json.MgUiResponseJson;
|
||||
import com.mg.swagger.framework.json.ResponseJson;
|
||||
import com.mg.swagger.framework.service.MgStorageService;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import springfox.documentation.swagger.web.SwaggerResource;
|
||||
|
||||
/**
|
||||
* 文档控制器
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/swagger-mg-ui/document")
|
||||
public class MgDocumentController {
|
||||
|
||||
@Autowired(required = false)
|
||||
private MgStorageService storageService;
|
||||
|
||||
/**
|
||||
* 获取所有的文档地址
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
@ResponseBody
|
||||
@PostMapping(value = "/resourcesList")
|
||||
public ResponseJson resourcesList() {
|
||||
if (storageService == null) {
|
||||
return MgUiResponseJson.warn(Toast.AUTOWIRED_ERROR);
|
||||
}
|
||||
String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST);
|
||||
Set<String> resourcesSet = new HashSet<>();
|
||||
if (StringUtils.isNotBlank(swaggerResourcesStr)) {
|
||||
List<String> resourcesList = JSON.parseArray(swaggerResourcesStr, String.class);
|
||||
resourcesSet.addAll(resourcesList);
|
||||
}
|
||||
return MgUiResponseJson.ok(resourcesSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的文档
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
@ResponseBody
|
||||
@PostMapping(value = "/docs")
|
||||
public void docs(HttpServletRequest request, HttpServletResponse response) {
|
||||
if (storageService == null) {
|
||||
MgUiResponseJson.warn(Toast.AUTOWIRED_ERROR).send(response);
|
||||
return;
|
||||
}
|
||||
boolean needRestorage = true;
|
||||
String choiseDocList = request.getParameter("choiseDocList");
|
||||
// 转成set,防止重复
|
||||
Set<String> resourcesSet = new HashSet<>();
|
||||
Set<String> swaggerDocsDeleteSet = new HashSet<>();
|
||||
if (StringUtils.isNotBlank(choiseDocList)) {
|
||||
needRestorage = false;// 选择的则不再存入
|
||||
resourcesSet.addAll(Arrays.asList(choiseDocList.split(",")));
|
||||
} else {
|
||||
String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST);
|
||||
String swaggerDocsDeleteStr = storageService.get(StorageKeys.SWAGGER_DOCS_DELETE_LIST);
|
||||
if (StringUtils.isNotBlank(swaggerResourcesStr)) {
|
||||
List<String> resourcesList = JSON.parseArray(swaggerResourcesStr, String.class);
|
||||
resourcesSet.addAll(resourcesList);
|
||||
} else {
|
||||
// 默认加上自身的文档
|
||||
String serverPath = "http://" + request.getServerName() // 服务器地址
|
||||
+ ":" + request.getServerPort() // 端口号
|
||||
+ request.getContextPath();
|
||||
// 是否加入自身的文档
|
||||
Object object = SpringContextUtil.getBeanWithAnnotation(EnableSwaggerMgUi.class);
|
||||
EnableSwaggerMgUi swaggerMgUi = object.getClass().getAnnotation(EnableSwaggerMgUi.class);
|
||||
if (swaggerMgUi == null) {
|
||||
// 直接通过superclass去找
|
||||
Class<?> superclass = object.getClass().getSuperclass();
|
||||
if (superclass != null) {
|
||||
swaggerMgUi = superclass.getAnnotation(EnableSwaggerMgUi.class);
|
||||
}
|
||||
}
|
||||
if (swaggerMgUi == null) {
|
||||
// 再通过AopUtils去找
|
||||
Class<?> targetClass = AopUtils.getTargetClass(object);
|
||||
if (targetClass != null) {
|
||||
swaggerMgUi = targetClass.getAnnotation(EnableSwaggerMgUi.class);
|
||||
}
|
||||
}
|
||||
if (swaggerMgUi == null) {
|
||||
resourcesSet.add(serverPath + "/swagger-resources");
|
||||
} else {
|
||||
boolean selfDoc = swaggerMgUi.selfDoc();
|
||||
if (selfDoc) {
|
||||
resourcesSet.add(serverPath + "/swagger-resources");
|
||||
} else {
|
||||
// 启动后第一次访问没有数据情况下需要加载进来的swagger-resources地址
|
||||
String[] defaultResources = swaggerMgUi.defaultResources();
|
||||
if (defaultResources != null && defaultResources.length > 0) {
|
||||
resourcesSet.addAll(Arrays.asList(defaultResources));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(swaggerDocsDeleteStr)) {
|
||||
List<String> swaggerDocsDeleteList = JSON.parseArray(swaggerDocsDeleteStr, String.class);
|
||||
swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList);
|
||||
}
|
||||
}
|
||||
List<Map<String, Object>> swaggerResourceList = new LinkedList<>();
|
||||
List<String> swaggerResourceStrList = new LinkedList<>();
|
||||
for (String resourcesUrl : resourcesSet) {
|
||||
List<SwaggerResource> resourceList = null;
|
||||
try {
|
||||
String resourcesStr = HttpRequest.get(resourcesUrl).timeout(3000).execute().body();
|
||||
resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (resourceList == null || resourceList.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
resourcesUrl = resourcesUrl.substring(0, resourcesUrl.lastIndexOf("/") + 1);
|
||||
for (SwaggerResource resource : resourceList) {
|
||||
String location = resource.getLocation();
|
||||
// 最后一个斜杠在resourcesUrl中已经加上,替换掉后面的防止两根斜杠
|
||||
location = location.startsWith("/") ? location.replaceFirst("/", "") : location;
|
||||
if (location.indexOf("?") >= 0) {
|
||||
try {
|
||||
String encode = URLEncoder.encode(resource.getName(), "utf-8");
|
||||
location = location.substring(0, location.lastIndexOf("?")) + "?group=" + encode;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
location = resourcesUrl + location;
|
||||
// 已删除的则不处理
|
||||
if (swaggerDocsDeleteSet.contains(location)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
String resourceStr = HttpRequest.get(location).timeout(3000).execute().body();
|
||||
Map<String, Object> jsonObject = JSON.parseObject(resourceStr, new TypeReference<HashMap<String, Object>>(){});
|
||||
if (jsonObject == null || jsonObject.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
jsonObject.put("fullUrl", location);
|
||||
swaggerResourceList.add(jsonObject);
|
||||
// 本来想转对象之后赋值,但是在此转成JSON字符串之后格式就不是之前的了,所有不能转。。。
|
||||
// 直接字符串拼接,坑真多~
|
||||
resourceStr = resourceStr.substring(1);
|
||||
resourceStr = "{\"fullUrl\":\"" + location + "\","
|
||||
+ "\"domainUrl\":\"" + resourcesUrl + "\","
|
||||
+ resourceStr;
|
||||
swaggerResourceStrList.add(resourceStr);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needRestorage) {
|
||||
storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesSet));
|
||||
}
|
||||
// 用默认的json解析要内存溢出,解析不了JSONObject、、就只有这样写了~
|
||||
MgUiResponseJson.ok(swaggerResourceStrList).send(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加/swagger-resources地址
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
* @param resourcesUrl
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/addSwaggerResources")
|
||||
public ResponseJson addSwaggerResources(String resourcesUrl) {
|
||||
if (storageService == null) {
|
||||
return MgUiResponseJson.warn(Toast.AUTOWIRED_ERROR);
|
||||
}
|
||||
String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST);
|
||||
String swaggerDocsDeleteStr = storageService.get(StorageKeys.SWAGGER_DOCS_DELETE_LIST);
|
||||
Set<String> swaggerDocsDeleteSet = new HashSet<>();
|
||||
if (StringUtils.isNotBlank(swaggerDocsDeleteStr)) {
|
||||
List<String> swaggerDocsDeleteList = JSON.parseArray(swaggerDocsDeleteStr, String.class);
|
||||
swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList);
|
||||
}
|
||||
// 转成set,防止重复
|
||||
Set<String> resourcesSet = new HashSet<>();
|
||||
if (StringUtils.isNotBlank(swaggerResourcesStr)) {
|
||||
List<String> resourcesList = JSON.parseArray(swaggerResourcesStr, String.class);
|
||||
resourcesSet.addAll(resourcesList);
|
||||
}
|
||||
try {
|
||||
String resourcesStr = HttpRequest.get(resourcesUrl).timeout(3000).execute().body();
|
||||
List<SwaggerResource> resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class);
|
||||
if (resourceList == null || resourceList.isEmpty()) {
|
||||
return MgUiResponseJson.warn("改地址未找到文档");
|
||||
}
|
||||
// 重新加入的时候把之前的已删除的回恢复
|
||||
String resourcesDomain = resourcesUrl.substring(0, resourcesUrl.lastIndexOf("/") + 1);
|
||||
for (SwaggerResource swaggerResource : resourceList) {
|
||||
String location = swaggerResource.getLocation();
|
||||
// 最后一个斜杠在resourcesUrl中已经加上,替换掉后面的防止两根斜杠
|
||||
location = location.startsWith("/") ? location.replaceFirst("/", "") : location;
|
||||
if (location.indexOf("?") >= 0) {
|
||||
try {
|
||||
String encode = URLEncoder.encode(swaggerResource.getName(), "utf-8");
|
||||
location = location.substring(0, location.lastIndexOf("?")) + "?group=" + encode;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
location = resourcesDomain + location;
|
||||
swaggerDocsDeleteSet.remove(location);
|
||||
}
|
||||
resourcesSet.add(resourcesUrl);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return MgUiResponseJson.warn("改地址查找文档失败");
|
||||
}
|
||||
storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesSet));
|
||||
storageService.put(StorageKeys.SWAGGER_DOCS_DELETE_LIST, JSON.toJSONString(swaggerDocsDeleteSet));
|
||||
return MgUiResponseJson.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除/v2/api-docs
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
* @param docUrl
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/deleteSwaggerDoc")
|
||||
public ResponseJson deleteSwaggerDoc(String docUrl) {
|
||||
if (storageService == null) {
|
||||
return MgUiResponseJson.warn(Toast.AUTOWIRED_ERROR);
|
||||
}
|
||||
String swaggerDocsDeleteStr = storageService.get(StorageKeys.SWAGGER_DOCS_DELETE_LIST);
|
||||
Set<String> swaggerDocsDeleteSet = new HashSet<>();
|
||||
if (StringUtils.isNotBlank(swaggerDocsDeleteStr)) {
|
||||
List<String> swaggerDocsDeleteList = JSON.parseArray(swaggerDocsDeleteStr, String.class);
|
||||
swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList);
|
||||
}
|
||||
swaggerDocsDeleteSet.add(docUrl);
|
||||
storageService.put(StorageKeys.SWAGGER_DOCS_DELETE_LIST, JSON.toJSONString(swaggerDocsDeleteSet));
|
||||
return MgUiResponseJson.ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.mg.swagger.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.mg.swagger.controller.param.HttpRequestParam;
|
||||
import com.mg.swagger.framework.json.MgUiResponseJson;
|
||||
import com.mg.swagger.framework.json.ResponseJson;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
|
||||
/**
|
||||
* 后台代理网络请求的控制器
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/swagger-mg-ui/http")
|
||||
public class MgHttpRequestController {
|
||||
|
||||
@PostMapping(value = "/request")
|
||||
public ResponseJson post(HttpRequestParam param) {
|
||||
HttpRequest request = param.createRequest();
|
||||
HttpResponse execute = request.execute();
|
||||
return MgUiResponseJson.ok(execute);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.mg.swagger.controller;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.mg.swagger.framework.constant.Toast;
|
||||
import com.mg.swagger.framework.json.MgUiResponseJson;
|
||||
import com.mg.swagger.framework.service.MgStorageService;
|
||||
|
||||
/**
|
||||
* 后台存储服务控制器
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/swagger-mg-ui/storage")
|
||||
public class MgStorageController {
|
||||
|
||||
@Autowired(required = false)
|
||||
private MgStorageService storageService;
|
||||
|
||||
@PostMapping(value = "/checkConfig")
|
||||
public MgUiResponseJson checkConfig() {
|
||||
// 本接口能访问当而且实现了MgStorageService才算配置好了
|
||||
if (storageService == null) {
|
||||
return MgUiResponseJson.error("服务不可用");
|
||||
}
|
||||
return MgUiResponseJson.ok();
|
||||
}
|
||||
|
||||
@PostMapping(value = "/data")
|
||||
public MgUiResponseJson setData(String key, String value) {
|
||||
if (storageService == null) {
|
||||
return MgUiResponseJson.warn(Toast.AUTOWIRED_ERROR);
|
||||
}
|
||||
if (key == null || value == null) {
|
||||
return MgUiResponseJson.warn("参数名或值不能为空");
|
||||
}
|
||||
storageService.put(key, value);
|
||||
return MgUiResponseJson.ok();
|
||||
}
|
||||
|
||||
@GetMapping(value = "/data")
|
||||
public MgUiResponseJson getData(String key) {
|
||||
if (storageService == null) {
|
||||
return MgUiResponseJson.warn(Toast.AUTOWIRED_ERROR);
|
||||
}
|
||||
if (key == null) {
|
||||
return MgUiResponseJson.warn("参数名不能为空");
|
||||
}
|
||||
String value = storageService.get(key);
|
||||
value = (value == null) ? "" : value;
|
||||
return MgUiResponseJson.ok(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package com.mg.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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装请求
|
||||
*/
|
||||
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请求
|
||||
*/
|
||||
public HttpRequest post() {
|
||||
HttpRequest request = HttpRequest.post(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET请求
|
||||
*/
|
||||
public HttpRequest get() {
|
||||
HttpRequest request = HttpRequest.get(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* HEAD请求
|
||||
*/
|
||||
public HttpRequest head() {
|
||||
HttpRequest request = HttpRequest.head(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* OPTIONS请求
|
||||
*/
|
||||
public HttpRequest options() {
|
||||
HttpRequest request = HttpRequest.options(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT请求
|
||||
*/
|
||||
public HttpRequest put() {
|
||||
HttpRequest request = HttpRequest.put(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* PATCH请求
|
||||
*/
|
||||
public HttpRequest patch() {
|
||||
HttpRequest request = HttpRequest.patch(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE请求
|
||||
*/
|
||||
public HttpRequest delete() {
|
||||
HttpRequest request = HttpRequest.delete(this.getUrl());
|
||||
this.createHttpRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* TRACE请求
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mg.swagger.controller.vo;
|
||||
|
||||
/**
|
||||
* cookie返回值对象
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
public class HttpCookieVo {
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mg.swagger.controller.vo;
|
||||
|
||||
/**
|
||||
* header返回值对象
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
public class HttpHeaderVo {
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mg.swagger.framework.configuration;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import com.mg.swagger.framework.filter.MgUiTestFilter;
|
||||
|
||||
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@Target(value = { java.lang.annotation.ElementType.TYPE })
|
||||
@Documented
|
||||
@Import({ SwaggerCommonConfiguration.class, MgUiTestFilter.class, SpringContextUtil.class })
|
||||
public @interface EnableSwaggerMgUi {
|
||||
|
||||
/**
|
||||
* 是否自动把自身的swagger-resources加进来
|
||||
* @return
|
||||
*/
|
||||
boolean selfDoc() default true;
|
||||
|
||||
/**
|
||||
* 启动后第一次访问没有数据情况下需要加载进来的swagger-resources地址
|
||||
* @return
|
||||
*/
|
||||
String[] defaultResources() default {};
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.mg.swagger.framework.configuration;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* context工具类
|
||||
*/
|
||||
@Component
|
||||
public class SpringContextUtil implements ApplicationContextAware {
|
||||
|
||||
public static ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
context = applicationContext;
|
||||
}
|
||||
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public static <T> T getBean(Class<T> clz) {
|
||||
return context.getBean(clz);
|
||||
}
|
||||
|
||||
public static Object getBean(String string) {
|
||||
return getApplicationContext().getBean(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类
|
||||
* @param cacheName
|
||||
* @return
|
||||
*/
|
||||
public static Object getBeanWithAnnotation(Class<? extends Annotation> annotationType) {
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> beansWithAnnotation = context.getBeansWithAnnotation(annotationType);
|
||||
if(beansWithAnnotation != null && beansWithAnnotation.size() > 0) {
|
||||
for (Object element : beansWithAnnotation.values()) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.mg.swagger.framework.configuration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
import com.mg.swagger.framework.filter.MgUiTestFilter;
|
||||
|
||||
//@EnableAutoConfiguration
|
||||
@ComponentScan(basePackages = {
|
||||
"com.mg.swagger.controller",
|
||||
"com.mg.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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.mg.swagger.framework.constant;
|
||||
|
||||
/**
|
||||
* 存储数据的KEY常量类
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
public class StorageKeys {
|
||||
// 所有文档地址
|
||||
public static final String SWAGGER_RESOURCES_LIST = "swagger-resources-list";
|
||||
// 已删除的文档
|
||||
public static final String SWAGGER_DOCS_DELETE_LIST = "swagger-docs-delete-list";
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mg.swagger.framework.constant;
|
||||
|
||||
/**
|
||||
* 提示语常量类
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
public class Toast {
|
||||
public static final String AUTOWIRED_ERROR = "暂未配置MgStorageService的实现类";
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.mg.swagger.framework.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.mg.swagger.framework.service.MgStorageService;
|
||||
|
||||
/**
|
||||
* 判断是否是模拟请求,功能需求:<br>
|
||||
* 很多时候后端定义好了接口,但还未实现,这时前端已经需要数据调试了,这时就需要用到这个过滤器了!<br>
|
||||
* 在页面上先配置好模拟返回的数据,然后在url上加入参数:mgUiTestFlag=1<br>
|
||||
* 例:http://192.168.0.249:8082/openApi/case/info?mgUiTestFlag=1<br>
|
||||
* 本过滤器就直接返回了之前配置的模拟数据,而不用等到后端必须把接口实现之后才能调试,或者在前端写一大段测试数据。<br>
|
||||
*
|
||||
* 例:笔者的公司后端人较少,一个需求需要10个接口,需求分析完后首先就把接口、参数、返回值定义好,然后一个个的去实现。
|
||||
* 也许需要10天才能写完,但前端两天就写好了,急需数据看效果,这时就让他们自己去设置模拟值,加上参数自己测试好。
|
||||
* 而不是一味的催后台,把各种锅丢给后端,然后玩自己的去了,浪费各环节等待时间。
|
||||
*/
|
||||
@Component
|
||||
public class MgUiTestFilter implements Filter {
|
||||
|
||||
@Autowired(required = false)
|
||||
private MgStorageService mgStorageService;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
String mockTestFlag = request.getParameter("mgUiTestFlag");
|
||||
if (!"1".equals(mockTestFlag)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
// 如果是模拟请求则直接返回模拟值
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
String requestUrl = httpServletRequest.getRequestURI();
|
||||
String cacheResult = mgStorageService.get("p-simulation-response-" + requestUrl);
|
||||
if (cacheResult != null) {
|
||||
responseWrite(cacheResult, (HttpServletResponse) response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
private static void responseWrite(String params, HttpServletResponse response) 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(params);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
package com.mg.swagger.framework.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpCookie;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializeConfig;
|
||||
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
|
||||
import com.mg.swagger.controller.vo.HttpCookieVo;
|
||||
import com.mg.swagger.controller.vo.HttpHeaderVo;
|
||||
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* MgUi返回数据格式
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
public class MgUiResponseJson implements ResponseJson {
|
||||
private static SerializeConfig mapping = new SerializeConfig();
|
||||
static {
|
||||
mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
@ApiModelProperty(value = "状态码")
|
||||
private Integer errCode;
|
||||
@ApiModelProperty(value = "返回值说明")
|
||||
private String errMsg;
|
||||
@ApiModelProperty(value = "返回数据")
|
||||
private Object data;
|
||||
@ApiModelProperty(value = "代理请求返回的cookie")
|
||||
private List<HttpCookieVo> cookie;
|
||||
@ApiModelProperty(value = "代理请求返回的header")
|
||||
private List<HttpHeaderVo> header;
|
||||
@ApiModelProperty(value = "代理请求返回的status")
|
||||
private Integer status;
|
||||
|
||||
public MgUiResponseJson() {
|
||||
this.errCode = 200;
|
||||
}
|
||||
|
||||
public MgUiResponseJson(Object data) {
|
||||
this.setData(data);
|
||||
this.errCode = 200;
|
||||
}
|
||||
|
||||
public MgUiResponseJson(int errCode, String errMsg) {
|
||||
super();
|
||||
this.errCode = errCode;
|
||||
this.errMsg = errMsg;
|
||||
}
|
||||
|
||||
public MgUiResponseJson(int errCode, String errMsg, Object data) {
|
||||
super();
|
||||
this.setData(data);
|
||||
this.errCode = errCode;
|
||||
this.errMsg = errMsg;
|
||||
}
|
||||
|
||||
public MgUiResponseJson(Integer errCode) {
|
||||
super();
|
||||
this.errCode = errCode;
|
||||
}
|
||||
|
||||
public Integer getErrCode() {
|
||||
return errCode;
|
||||
}
|
||||
|
||||
public void setErrCode(Integer errCode) {
|
||||
this.errCode = errCode;
|
||||
}
|
||||
|
||||
public String getErrMsg() {
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
public void setErrMsg(String errMsg) {
|
||||
this.errMsg = errMsg;
|
||||
}
|
||||
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Object data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提示语
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月7日
|
||||
* @return
|
||||
*/
|
||||
public static MgUiResponseJson warn(String errMsg) {
|
||||
return new MgUiResponseJson(300, errMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 错误
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月7日
|
||||
* @return
|
||||
*/
|
||||
public static MgUiResponseJson error(String errMsg) {
|
||||
return new MgUiResponseJson(500, errMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功的返回方法
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月7日
|
||||
* @return
|
||||
*/
|
||||
public static MgUiResponseJson ok() {
|
||||
return new MgUiResponseJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功的返回方法
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月7日
|
||||
* @return
|
||||
*/
|
||||
public static MgUiResponseJson ok(Object data) {
|
||||
if (data == null) {
|
||||
return MgUiResponseJson.ok();
|
||||
}
|
||||
MgUiResponseJson responseJson = new MgUiResponseJson();
|
||||
if (data instanceof HttpResponse) {
|
||||
HttpResponse response = (HttpResponse) data;
|
||||
responseJson.setData(response.body());
|
||||
responseJson.setStatus(response.getStatus());
|
||||
List<HttpCookie> cookies = response.getCookies();
|
||||
if (cookies != null && cookies.size() > 0) {
|
||||
List<HttpCookieVo> cookie = new ArrayList<>(cookies.size());
|
||||
for (HttpCookie httpCookie : cookies) {
|
||||
HttpCookieVo vo = new HttpCookieVo();
|
||||
vo.setName(httpCookie.getName());
|
||||
vo.setValue(httpCookie.getValue());
|
||||
cookie.add(vo);
|
||||
}
|
||||
responseJson.setCookie(cookie);
|
||||
}
|
||||
Map<String, List<String>> headers = response.headers();
|
||||
if (headers != null && headers.size() > 0) {
|
||||
List<HttpHeaderVo> header = new ArrayList<>(headers.size());
|
||||
for (Entry<String, List<String>> httpHeader : headers.entrySet()) {
|
||||
HttpHeaderVo vo = new HttpHeaderVo();
|
||||
vo.setName(httpHeader.getKey());
|
||||
vo.setValue(String.join(";", httpHeader.getValue()));
|
||||
header.add(vo);
|
||||
}
|
||||
responseJson.setHeader(header);
|
||||
}
|
||||
} else {
|
||||
responseJson.setData(data);
|
||||
}
|
||||
return responseJson;
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
return JSON.toJSONString(this, mapping);
|
||||
}
|
||||
|
||||
public void send(HttpServletResponse response) {
|
||||
try {
|
||||
response.setStatus(200);
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setHeader("Cache-Control", "no-cache, must-revalidate");
|
||||
response.getWriter().write(toJson());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DefaultResponseJson [errCode=" + errCode + ", errMsg=" + errMsg + ", data=" + data + "]";
|
||||
}
|
||||
|
||||
public List<HttpCookieVo> getCookie() {
|
||||
return cookie;
|
||||
}
|
||||
|
||||
public void setCookie(List<HttpCookieVo> cookie) {
|
||||
this.cookie = cookie;
|
||||
}
|
||||
|
||||
public List<HttpHeaderVo> getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
public void setHeader(List<HttpHeaderVo> header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mg.swagger.framework.json;
|
||||
|
||||
/**
|
||||
* json视图
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月21日
|
||||
*/
|
||||
public interface ResponseJson {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mg.swagger.framework.service;
|
||||
|
||||
/**
|
||||
* 实现此类才能使用服务器端的存贮功能
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月19日
|
||||
*/
|
||||
public interface MgStorageService {
|
||||
|
||||
/**
|
||||
* 获取存储的值
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月19日
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
String get(String key);
|
||||
|
||||
/**
|
||||
* 存储数据
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月19日
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void put(String key, String value);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user