增加文件上传功能

This commit is contained in:
暮光:城中城
2018-12-26 22:34:20 +08:00
parent b7c72cf38b
commit 09d077cb07
9 changed files with 219 additions and 105 deletions

View File

@@ -82,21 +82,31 @@
<version>${springfox.swagger.version}</version>
</dependency>
<!-- 在线文档解析页面 -->
<dependency>
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-swagger</artifactId>
<version>${zyplayer.doc.swagger.version}</version>
</dependency>
<!--zyplayer-doc-core-->
<dependency>
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-core</artifactId>
<version>${zyplayer.doc.core.version}</version>
</dependency>
<!--zyplayer-doc-db-->
<dependency>
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-db</artifactId>
<version>${zyplayer.doc.db.version}</version>
</dependency>
<!--zyplayer-doc-swagger-->
<dependency>
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-swagger</artifactId>
<version>${zyplayer.doc.swagger.version}</version>
</dependency>
<!--swagger-bootstrap-ui-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger.bootstrap.ui.version}</version>
</dependency>
<!--springfox-swagger-ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
@@ -118,12 +128,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-db</artifactId>
<version>${zyplayer.doc.db.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>

View File

@@ -34,16 +34,11 @@ public class Application extends SpringBootServletInitializer {
String hostAddress = InetAddress.getLocalHost().getHostAddress();
String serverPort = env.getProperty("server.port");
String urlCtx = hostAddress + ":" + serverPort + "/" + contextPath;
// 三个UI的名字长度惊人的一致肯定是知道我有强迫症
logger.info("\n----------------------------------------------------------\n\t" +
"\t\t地址列表\n\t" +
"zyplayer-doc-swaggerhttp://{}document.html\n\t" +
"swagger-bootstrap-uihttp://{}doc.html\n\t" +
"springfox-swagger-uihttp://{}swagger-ui.html\n\t" +
"数据库文档管理地址http://{}doc-db.html\n\t" +
"管理地址http://{}statics/manage/home.html\n" +
"----------------------------------------------------------",
urlCtx, urlCtx, urlCtx, urlCtx, urlCtx
urlCtx
);
}
}

View File

@@ -74,6 +74,11 @@
<artifactId>zyplayer-doc-core</artifactId>
<version>${zyplayer.doc.core.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
</dependencies>
<licenses>

View File

@@ -52,14 +52,13 @@ public class MgDocumentController {
*/
@ResponseBody
@PostMapping(value = "/resourcesList")
public ResponseJson<Set<SwaggerResourcesInfoVo>> resourcesList() {
public ResponseJson<List<SwaggerResourcesInfoVo>> resourcesList() {
String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST);
Set<SwaggerResourcesInfoVo> resourcesSet = new HashSet<>();
List<SwaggerResourcesInfoVo> resourcesList = new LinkedList<>();
if (StringUtils.isNotBlank(swaggerResourcesStr)) {
List<SwaggerResourcesInfoVo> resourcesList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class);
resourcesSet.addAll(resourcesList);
resourcesList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class);
}
return DocResponseJson.ok(resourcesSet);
return DocResponseJson.ok(resourcesList);
}
/**

View File

@@ -1,60 +1,56 @@
package com.zyplayer.doc.swagger.controller;
import java.net.HttpCookie;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.zyplayer.doc.core.json.DocResponseJson;
import com.zyplayer.doc.swagger.controller.param.HttpRequestParam;
import com.zyplayer.doc.swagger.controller.vo.HttpCookieVo;
import com.zyplayer.doc.swagger.controller.vo.HttpHeaderVo;
import com.zyplayer.doc.swagger.controller.vo.HttpRequestVo;
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 DocResponseJson<HttpRequestVo> post(HttpRequestParam param) {
HttpRequest request = param.createRequest();
HttpResponse response = request.execute();
HttpRequestVo httpRequestVo = new HttpRequestVo();
httpRequestVo.setData(response.body());
httpRequestVo.setStatus(response.getStatus());
List<HttpCookie> cookies = response.getCookies();
if (cookies != null && cookies.size() > 0) {
List<HttpCookieVo> cookie = cookies.stream().map(val -> {
return new HttpCookieVo(val.getName(), val.getValue());
}).collect(Collectors.toList());
httpRequestVo.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);
}
httpRequestVo.setHeader(header);
}
return DocResponseJson.ok(httpRequestVo);
}
}
package com.zyplayer.doc.swagger.controller;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.zyplayer.doc.core.json.DocResponseJson;
import com.zyplayer.doc.swagger.controller.param.HttpRequestParam;
import com.zyplayer.doc.swagger.controller.vo.HttpCookieVo;
import com.zyplayer.doc.swagger.controller.vo.HttpHeaderVo;
import com.zyplayer.doc.swagger.controller.vo.HttpRequestVo;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.HttpCookie;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
/**
* 后台代理网络请求的控制器
*
* @author 暮光:城中城
* @since 2018年8月21日
*/
@RestController
@RequestMapping("/swagger-mg-ui/http")
public class MgHttpRequestController {
@PostMapping(value = "/request")
public DocResponseJson<HttpRequestVo> post(HttpRequestParam param) {
HttpRequest request = param.createRequest();
HttpResponse response = request.execute();
HttpRequestVo httpRequestVo = new HttpRequestVo();
httpRequestVo.setData(response.body());
httpRequestVo.setStatus(response.getStatus());
List<HttpCookie> cookies = response.getCookies();
if (cookies != null && cookies.size() > 0) {
List<HttpCookieVo> cookie = cookies.stream().map(val -> new HttpCookieVo(val.getName(), val.getValue())).collect(Collectors.toList());
httpRequestVo.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);
}
httpRequestVo.setHeader(header);
}
return DocResponseJson.ok(httpRequestVo);
}
}

View File

@@ -1,8 +1,15 @@
package com.zyplayer.doc.swagger.controller.param;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.BytesResource;
import cn.hutool.core.io.resource.MultiFileResource;
import org.apache.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
@@ -10,6 +17,7 @@ import com.alibaba.fastjson.TypeReference;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.Method;
import org.springframework.web.multipart.MultipartFile;
/**
* 请求参数对象
@@ -23,6 +31,8 @@ public class HttpRequestParam {
private String header;
private String form;
private String body;
private String[] fileNames;
private MultipartFile[] files;
public String getUrl() {
return url;
@@ -84,6 +94,28 @@ public class HttpRequestParam {
if (formMap != null) {
request.form(formMap);
}
// 拼文件
if (this.getFiles() != null && this.getFiles().length > 0) {
Map<String, MultiFileResource> bytesResourceMap = new HashMap<>();
for (int i = 0; i < this.getFiles().length; i++) {
try {
String fileName = this.getFileNames()[i].replace("[", "").replace("]", "");
MultipartFile file = this.getFiles()[i];
BytesResource bytesResource = new BytesResource(file.getBytes(), file.getOriginalFilename());
MultiFileResource multiFileResource = bytesResourceMap.get(fileName);
if (multiFileResource == null) {
multiFileResource = new MultiFileResource();
}
multiFileResource.add(bytesResource);
bytesResourceMap.put(fileName, multiFileResource);
} catch (Exception e) {
e.printStackTrace();
}
}
for (Map.Entry<String, MultiFileResource> entry : bytesResourceMap.entrySet()) {
request.form(entry.getKey(), entry.getValue());
}
}
if (StringUtils.isNotBlank(body) && request.getMethod() != Method.GET) {
request.body(body);
}
@@ -192,5 +224,20 @@ public class HttpRequestParam {
public void setMethod(String method) {
this.method = method;
}
public MultipartFile[] getFiles() {
return files;
}
public void setFiles(MultipartFile[] files) {
this.files = files;
}
public String[] getFileNames() {
return fileNames;
}
public void setFileNames(String[] fileNames) {
this.fileNames = fileNames;
}
}

View File

@@ -197,7 +197,7 @@ function ajaxTemp(url, dataSentType, dataReceiveType, paramsStr, successFunction
}
},
beforeSend : function() {
},
complete : function(msg) {
if(typeof completeFunction == "function") {
@@ -212,6 +212,36 @@ function ajaxTemp(url, dataSentType, dataReceiveType, paramsStr, successFunction
});
}
function postWithFile(url, paramsStr, successFunction, errorFunction, completeFunction, id) {
$.ajax({
url: url, // 后台处理程序
sync: false,
type: "POST", // 数据发送方式
dataType: "JSON", // 接受数据格式
data: eval(paramsStr),
processData: false,
contentType: false,
success: function (msg) {
if (typeof successFunction == "function") {
successFunction(msg, id);
}
},
beforeSend: function () {
},
complete: function (msg) {
if (typeof completeFunction == "function") {
completeFunction(msg, id);
}
},
error: function (msg) {
if (typeof errorFunction == "function") {
errorFunction(msg, id);
}
}
});
}
/**
* 获取cookie
* @param name

View File

@@ -45,17 +45,19 @@ $(document).ready(function(){
var paramFormSend = {};
var paramBodySend = $("[name=paramBody]").val();
var formToUrl = $("[name=formToUrl]").prop('checked') ? 1 : 0;
var paramSendToServer = {};
// 组装空的表单对象
var formDataToServer = new FormData();
requestHeaderForm = serializeArrayToObj(requestHeaderForm);
requestParamForm = serializeArrayToObj(requestParamForm);
storeRequestParam.formToUrl = formToUrl;
paramSendToServer.formToUrl = formToUrl;
formDataToServer.append("formToUrl", formToUrl);
if (isNotEmpty(paramBodySend)) {
try {
paramBodySend = JSON.stringify(JSON.parse(paramBodySend));
} catch (e) {}
storeRequestParam.body = paramBodySend;
paramSendToServer.body = paramBodySend;
formDataToServer.append("body", paramBodySend);
// 替换path参数
Object.keys(requestParamForm).forEach(function (key) {
postUrl = postUrl.replace("{" + key + "}", requestParamForm[key]);
@@ -74,13 +76,14 @@ $(document).ready(function(){
postUrl = postUrl.replace("{" + key + "}", value);
}
});
storeRequestParam.form = paramFormSend;
// 表单参数是否拼在url上
if(formToUrl == 1) {
postUrl += "?" + reqParamStr;
paramFormSend = "";
} else {
paramSendToServer.form = JSON.stringify(paramFormSend);
formDataToServer.append("form", JSON.stringify(paramFormSend));
}
// 显示加载中图标
$(".send-request .icon").removeClass("hide");
@@ -92,13 +95,23 @@ $(document).ready(function(){
}
});
storeRequestParam.header = paramHeaderSend;
paramSendToServer.header = JSON.stringify(paramHeaderSend);
paramSendToServer.url = postUrl;
paramSendToServer.method = options;
//console.log(paramBodySend);
var beforeSendTime = new Date().getTime();
// 拼装文件
var fileInput = $('#requestParamForm').find(".file-input");
for (var i = 0; i < fileInput.length; i++) {
var fileName = $(fileInput[i]).parents("tr").find("[name=paramName]").val();
for (var j = 0; j < fileInput[i].files.length; j++) {
formDataToServer.append('files', fileInput[i].files[j]);
formDataToServer.append('fileNames', fileName);
}
}
formDataToServer.append("header", JSON.stringify(paramHeaderSend));
formDataToServer.append("url", postUrl);
formDataToServer.append("method", options);
// debugger;
// 模拟请求开始
ajaxTemp("swagger-mg-ui/http/request", "post", "json", paramSendToServer, function(result){
postWithFile("swagger-mg-ui/http/request", formDataToServer, function(result){
var afterSendTime = new Date().getTime();
//console.log(result);
var requestObj = result.data;
@@ -361,6 +374,7 @@ function createOnlineDebugRequestParamFun(pRequestObj, requestParamObj, url) {
|| (tempParam.paramIn == "path")
|| (tempParam.paramIn == "body")
|| (tempParam.paramIn == "form")
|| (tempParam.paramIn == "formData")
|| isNotEmpty(tempParam.paramIn);
if (paramInForm && !onlyUseLastForm) {
//console.log(tempParam);
@@ -374,10 +388,21 @@ function createOnlineDebugRequestParamFun(pRequestObj, requestParamObj, url) {
formVal = getAutoFillValue(tempParam.paramType, key);
}
if(formValueCount > 0) {
$("#tabParamTypeForm table tbody").append(getParamTableTr(key, formVal, "", tempParam.paramDesc));
$("#tabParamTypeForm table tbody").append(getParamTableTr(key, formVal, "", tempParam.paramDesc, tempParam.paramType));
} else {
// 文件的input特殊处理
if(tempParam.paramType == 'file'){
$("#tabParamTypeForm table tbody .base input[name=paramValue]")
.attr("type", "file").attr("multiple", "multiple")
.addClass("file-input")
.val(formVal);
} else {
$("#tabParamTypeForm table tbody .base input[name=paramValue]")
.attr("type", "text")
.removeClass("file-input")
.val(formVal);
}
$("#tabParamTypeForm table tbody .base input[name=paramName]").val(key);
$("#tabParamTypeForm table tbody .base input[name=paramValue]").val(formVal);
$("#tabParamTypeForm table tbody .base input[name=paramValue]").attr("placeholder", getNotEmptyStr(tempParam.paramDesc));
}
$("#tabParamBody .nav li").eq(0).find("a").click();
@@ -462,8 +487,8 @@ function serializeArrayToObj(formArr) {
for (var i = 0; i < formArr.length; i++) {
if (formArr[i].name == "paramName" && i < formArr.length) {
var key = formArr[i].value;
var value = formArr[i+1].value;
if(isNotEmpty(key)) {
var value = formArr[i + 1].value;
if (isNotEmpty(key) && formArr[i + 1].name != "paramName") {
paramObj[key] = value;
}
}
@@ -503,7 +528,7 @@ function bulkEditToTable(tableId, bulkEdit) {
* @param valuePl
* @returns
*/
function getParamTableTr(name, value, namePl, valuePl) {
function getParamTableTr(name, value, namePl, valuePl, paramType) {
name = getNotEmptyStr(name);
namePl = getNotEmptyStr(namePl);
value = getNotEmptyStr(value);
@@ -514,12 +539,18 @@ function getParamTableTr(name, value, namePl, valuePl) {
namePl = (typeof namePl === 'string') ? namePl.replace(regExp, "&quot;") : namePl;
value = (typeof value === 'string') ? value.replace(regExp, "&quot;") : value;
valuePl = (typeof valuePl === 'string') ? valuePl.replace(regExp, "&quot;") : valuePl;
var resultStr =
'<tr class="new">'
+'<td><input type="text" class="form-control" name="paramName" value="'+name+'" placeholder="'+namePl+'"></td>'
+'<td><input type="text" class="form-control" name="paramValue" value="'+value+'" placeholder="'+valuePl+'"></td>'
+'<td><i class="icon-times"></i></td>'
+'</tr>';
var resultStr =
'<tr class="new">'
+'<td><input type="text" class="form-control" name="paramName" value="'+name+'" placeholder="'+namePl+'"></td>';
// 文件的input特殊处理
if(paramType == 'file') {
resultStr += '<td><input type="file" multiple class="form-control file-input" name="paramValue" value="'+value+'" placeholder="'+valuePl+'"></td>';
} else {
resultStr += '<td><input type="text" class="form-control" name="paramValue" value="'+value+'" placeholder="'+valuePl+'"></td>'
}
resultStr += '<td><i class="icon-times"></i></td>'
+'</tr>';
return resultStr;
}

View File

@@ -375,8 +375,15 @@ $("#apiPathTree").on("click", ".show-doc", function(){
var paramIn = getNotEmptyStr(tempParameters.in);
var example = getNotEmptyStr(tempParameters.example, tempParameters.default);
if(isNotEmpty(tempParameters.items)) {
htmlStr = paramName + "[0]";
htmlStrExample = paramName + "[0]";
if(tempParameters.items.$ref == '#/definitions/MultipartFile') {
htmlStr = paramName;
htmlStrExample = paramName;
paramType = 'file';
addRequestParamObj(requestParamObj, paramName, paramType, paramIn, required, paramDesc, example);
} else {
htmlStr = paramName + "[0]";
htmlStrExample = paramName + "[0]";
}
} else if(isNotEmpty(tempParameters.schema)) {
if("array" == tempParameters.schema.type) {
var responsesObj = definitionsDataMap.get(tempParameters.schema.items.$ref);