mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-12 07:02:14 +08:00
沙箱环境支持下载
This commit is contained in:
@@ -13,6 +13,7 @@ import okhttp3.OkHttpClient;
|
|||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@@ -51,14 +52,17 @@ public class HttpTool {
|
|||||||
|
|
||||||
protected void initHttpClient(HttpToolConfig httpToolConfig) {
|
protected void initHttpClient(HttpToolConfig httpToolConfig) {
|
||||||
httpClient = new OkHttpClient.Builder()
|
httpClient = new OkHttpClient.Builder()
|
||||||
.connectTimeout(httpToolConfig.connectTimeoutSeconds, TimeUnit.SECONDS) // 设置链接超时时间,默认10秒
|
// 设置链接超时时间,默认10秒
|
||||||
|
.connectTimeout(httpToolConfig.connectTimeoutSeconds, TimeUnit.SECONDS)
|
||||||
.readTimeout(httpToolConfig.readTimeoutSeconds, TimeUnit.SECONDS)
|
.readTimeout(httpToolConfig.readTimeoutSeconds, TimeUnit.SECONDS)
|
||||||
.writeTimeout(httpToolConfig.writeTimeoutSeconds, TimeUnit.SECONDS)
|
.writeTimeout(httpToolConfig.writeTimeoutSeconds, TimeUnit.SECONDS)
|
||||||
.cookieJar(new CookieJar() {
|
.cookieJar(new CookieJar() {
|
||||||
|
@Override
|
||||||
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
|
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
|
||||||
cookieStore.put(httpUrl.host(), list);
|
cookieStore.put(httpUrl.host(), list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<Cookie> loadForRequest(HttpUrl httpUrl) {
|
public List<Cookie> loadForRequest(HttpUrl httpUrl) {
|
||||||
List<Cookie> cookies = cookieStore.get(httpUrl.host());
|
List<Cookie> cookies = cookieStore.get(httpUrl.host());
|
||||||
return cookies != null ? cookies : new ArrayList<Cookie>();
|
return cookies != null ? cookies : new ArrayList<Cookie>();
|
||||||
@@ -204,22 +208,24 @@ public class HttpTool {
|
|||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public String requestFile(String url, Map<String, String> form, Map<String, String> header, List<UploadFile> files)
|
public String requestFile(String url, Map<String, ?> form, Map<String, String> header, List<UploadFile> files)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// 创建MultipartBody.Builder,用于添加请求的数据
|
// 创建MultipartBody.Builder,用于添加请求的数据
|
||||||
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
|
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
|
||||||
bodyBuilder.setType(MultipartBody.FORM);
|
bodyBuilder.setType(MultipartBody.FORM);
|
||||||
|
|
||||||
for (UploadFile uploadFile : files) {
|
for (UploadFile uploadFile : files) {
|
||||||
bodyBuilder.addFormDataPart(uploadFile.getName(), // 请求的名字
|
// 请求的名字
|
||||||
uploadFile.getFileName(), // 文件的文字,服务器端用来解析的
|
bodyBuilder.addFormDataPart(uploadFile.getName(),
|
||||||
RequestBody.create(null, uploadFile.getFileData()) // 创建RequestBody,把上传的文件放入
|
// 文件的文字,服务器端用来解析的
|
||||||
|
uploadFile.getFileName(),
|
||||||
|
// 创建RequestBody,把上传的文件放入
|
||||||
|
RequestBody.create(null, uploadFile.getFileData())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Map.Entry<String, String>> entrySet = form.entrySet();
|
for (Map.Entry<String, ?> entry : form.entrySet()) {
|
||||||
for (Map.Entry<String, String> entry : entrySet) {
|
bodyBuilder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue()));
|
||||||
bodyBuilder.addFormDataPart(entry.getKey(), entry.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestBody requestBody = bodyBuilder.build();
|
RequestBody requestBody = bodyBuilder.build();
|
||||||
@@ -238,6 +244,51 @@ public class HttpTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求数据
|
||||||
|
*
|
||||||
|
* @param url 请求url
|
||||||
|
* @param form 请求数据
|
||||||
|
* @param header header
|
||||||
|
* @return 返回Response
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Response requestForResponse(String url, Map<String, ?> form, Map<String, String> header, HTTPMethod method) throws IOException {
|
||||||
|
Request.Builder requestBuilder = buildRequestBuilder(url, form, method);
|
||||||
|
// 添加header
|
||||||
|
addHeader(requestBuilder, header);
|
||||||
|
|
||||||
|
Request request = requestBuilder.build();
|
||||||
|
return httpClient
|
||||||
|
.newCall(request)
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*
|
||||||
|
* @param url 请求url
|
||||||
|
* @param form 请求数据
|
||||||
|
* @param header header
|
||||||
|
* @return 返回文件流
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public InputStream downloadFile(String url, Map<String, ?> form, Map<String, String> header) throws IOException {
|
||||||
|
Request.Builder requestBuilder = buildRequestBuilder(url, form, HTTPMethod.GET);
|
||||||
|
// 添加header
|
||||||
|
addHeader(requestBuilder, header);
|
||||||
|
|
||||||
|
Request request = requestBuilder.build();
|
||||||
|
Response response = httpClient
|
||||||
|
.newCall(request)
|
||||||
|
.execute();
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
ResponseBody body = response.body();
|
||||||
|
return body == null ? null : body.byteStream();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void addHeader(Request.Builder builder, Map<String, String> header) {
|
private void addHeader(Request.Builder builder, Map<String, String> header) {
|
||||||
if (header != null) {
|
if (header != null) {
|
||||||
Set<Map.Entry<String, String>> entrySet = header.entrySet();
|
Set<Map.Entry<String, String>> entrySet = header.entrySet();
|
||||||
@@ -256,10 +307,15 @@ public class HttpTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum HTTPMethod {
|
public enum HTTPMethod {
|
||||||
|
/** http GET */
|
||||||
GET,
|
GET,
|
||||||
|
/** http POST */
|
||||||
POST,
|
POST,
|
||||||
|
/** http PUT */
|
||||||
PUT,
|
PUT,
|
||||||
|
/** http HEAD */
|
||||||
HEAD,
|
HEAD,
|
||||||
|
/** http DELETE */
|
||||||
DELETE;
|
DELETE;
|
||||||
|
|
||||||
private HTTPMethod() {
|
private HTTPMethod() {
|
||||||
|
@@ -2,15 +2,15 @@ package com.gitee.sop.storyweb.controller;
|
|||||||
|
|
||||||
import com.gitee.sop.servercommon.annotation.ApiMapping;
|
import com.gitee.sop.servercommon.annotation.ApiMapping;
|
||||||
import com.gitee.sop.storyweb.controller.param.StoryParam;
|
import com.gitee.sop.storyweb.controller.param.StoryParam;
|
||||||
import org.apache.commons.io.FileUtils;
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,20 +18,24 @@ import java.io.IOException;
|
|||||||
*
|
*
|
||||||
* @author tanghc
|
* @author tanghc
|
||||||
*/
|
*/
|
||||||
|
@Api(tags = "文件下载")
|
||||||
@Controller
|
@Controller
|
||||||
public class DownloadController {
|
public class DownloadController {
|
||||||
|
|
||||||
@ApiMapping(value = "story.download")
|
@ApiOperation(value = "文件下载", notes = "演示文件下载")
|
||||||
public ResponseEntity<byte[]> export(StoryParam param) throws IOException {
|
@ApiMapping(value = "story.download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE/* 这个一定要加,不然沙箱文档不起作用 */)
|
||||||
|
public ResponseEntity<byte[]> download(StoryParam param) throws IOException {
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
// 假设下载classpath下的application.properties文件
|
// 假设下载classpath下的application.properties文件
|
||||||
ClassPathResource resource = new ClassPathResource("/application.properties");
|
ClassPathResource resource = new ClassPathResource("/application.properties");
|
||||||
File file = resource.getFile();
|
|
||||||
|
|
||||||
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||||
headers.setContentDispositionFormData("attachment", file.getName());
|
headers.setContentDispositionFormData("attachment", resource.getFilename());
|
||||||
|
|
||||||
return new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
|
return ResponseEntity
|
||||||
|
.ok()
|
||||||
|
.headers(headers)
|
||||||
|
.body(IOUtils.toByteArray(resource.getInputStream()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -244,6 +244,26 @@ public class HttpTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求数据
|
||||||
|
*
|
||||||
|
* @param url 请求url
|
||||||
|
* @param form 请求数据
|
||||||
|
* @param header header
|
||||||
|
* @return 返回Response
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Response requestForResponse(String url, Map<String, ?> form, Map<String, String> header, HTTPMethod method) throws IOException {
|
||||||
|
Request.Builder requestBuilder = buildRequestBuilder(url, form, method);
|
||||||
|
// 添加header
|
||||||
|
addHeader(requestBuilder, header);
|
||||||
|
|
||||||
|
Request request = requestBuilder.build();
|
||||||
|
return httpClient
|
||||||
|
.newCall(request)
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载文件
|
* 下载文件
|
||||||
*
|
*
|
||||||
|
@@ -138,6 +138,12 @@ function doTest() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
data.bizContent = JSON.stringify(bizContent);
|
data.bizContent = JSON.stringify(bizContent);
|
||||||
|
if (isDownloadRequest(currentItem)) {
|
||||||
|
data.isDownloadRequest = true;
|
||||||
|
downloadFile(data);
|
||||||
|
// window.open()
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 确定文件数量,并且知道参数名称
|
// 确定文件数量,并且知道参数名称
|
||||||
if (uploadFileObjects.length > 0) {
|
if (uploadFileObjects.length > 0) {
|
||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
@@ -151,6 +157,20 @@ function doTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isDownloadRequest(currentItem) {
|
||||||
|
var produces = currentItem.produces;
|
||||||
|
if (!produces) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < produces.length; i++) {
|
||||||
|
var produce = produces[i];
|
||||||
|
if (produce.indexOf('application/octet-stream') > -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function putVal(obj, input) {
|
function putVal(obj, input) {
|
||||||
if (input.type == 'text') {
|
if (input.type == 'text') {
|
||||||
obj[input.name] = input.value;
|
obj[input.name] = input.value;
|
||||||
@@ -204,6 +224,16 @@ function postFile(data, formData) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function downloadFile(data) {
|
||||||
|
$('.dl-form').remove();
|
||||||
|
var url = SopConfig.url + '/sandbox/test';
|
||||||
|
var form = $('<form class="dl-form"></form>').attr("action", url).attr("method", "get");
|
||||||
|
for(var key in data) {
|
||||||
|
form.append($("<input>").attr("type", "hidden").attr("name", key).attr("value", data[key]));
|
||||||
|
}
|
||||||
|
form.appendTo('body').submit();
|
||||||
|
}
|
||||||
|
|
||||||
function successHandler(resp) {
|
function successHandler(resp) {
|
||||||
setReqInfo(resp);
|
setReqInfo(resp);
|
||||||
showRespnfo(resp.apiResult);
|
showRespnfo(resp.apiResult);
|
||||||
|
@@ -20,6 +20,10 @@ public class DocItem {
|
|||||||
/** http method列表 */
|
/** http method列表 */
|
||||||
private Collection<String> httpMethodList;
|
private Collection<String> httpMethodList;
|
||||||
|
|
||||||
|
private Collection<String> produces;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<DocParameter> requestParameters;
|
List<DocParameter> requestParameters;
|
||||||
List<DocParameter> responseParameters;
|
List<DocParameter> responseParameters;
|
||||||
|
|
||||||
|
@@ -1,12 +1,16 @@
|
|||||||
package com.gitee.sop.websiteserver.controller;
|
package com.gitee.sop.websiteserver.controller;
|
||||||
|
|
||||||
import com.gitee.sop.registryapi.bean.HttpTool;
|
import com.gitee.sop.registryapi.bean.HttpTool;
|
||||||
import com.gitee.sop.registryapi.bean.HttpTool.*;
|
import com.gitee.sop.registryapi.bean.HttpTool.HTTPMethod;
|
||||||
|
import com.gitee.sop.registryapi.bean.HttpTool.UploadFile;
|
||||||
import com.gitee.sop.websiteserver.sign.AlipayApiException;
|
import com.gitee.sop.websiteserver.sign.AlipayApiException;
|
||||||
import com.gitee.sop.websiteserver.sign.AlipaySignature;
|
import com.gitee.sop.websiteserver.sign.AlipaySignature;
|
||||||
import com.gitee.sop.websiteserver.util.UploadUtil;
|
import com.gitee.sop.websiteserver.util.UploadUtil;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import okhttp3.Headers;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
@@ -26,6 +30,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -60,7 +65,10 @@ public class SandboxController {
|
|||||||
, @RequestParam String version
|
, @RequestParam String version
|
||||||
, @RequestParam String bizContent
|
, @RequestParam String bizContent
|
||||||
, @RequestParam(defaultValue = "get") String httpMethod
|
, @RequestParam(defaultValue = "get") String httpMethod
|
||||||
, HttpServletRequest request) throws AlipayApiException {
|
, @RequestParam(defaultValue = "false") boolean isDownloadRequest
|
||||||
|
, HttpServletRequest request
|
||||||
|
, HttpServletResponse response
|
||||||
|
) throws AlipayApiException {
|
||||||
|
|
||||||
Assert.isTrue(StringUtils.isNotBlank(appId), "AppId不能为空");
|
Assert.isTrue(StringUtils.isNotBlank(appId), "AppId不能为空");
|
||||||
Assert.isTrue(StringUtils.isNotBlank(privateKey), "PrivateKey不能为空");
|
Assert.isTrue(StringUtils.isNotBlank(privateKey), "PrivateKey不能为空");
|
||||||
@@ -111,7 +119,21 @@ public class SandboxController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
String responseData;
|
String responseData;
|
||||||
if (!CollectionUtils.isEmpty(files)) {
|
if (isDownloadRequest) {
|
||||||
|
Response resp = httpTool.requestForResponse(url, params, Collections.emptyMap(), HTTPMethod.GET);
|
||||||
|
Headers respHeaders = resp.headers();
|
||||||
|
ResponseBody body = resp.body();
|
||||||
|
if (body == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
respHeaders
|
||||||
|
.names()
|
||||||
|
.forEach(name -> response.setHeader(name, respHeaders.get(name)));
|
||||||
|
|
||||||
|
IOUtils.copy(body.byteStream(), response.getOutputStream());
|
||||||
|
response.flushBuffer();
|
||||||
|
return null;
|
||||||
|
} else if (!CollectionUtils.isEmpty(files)) {
|
||||||
responseData = httpTool.requestFile(url, params, Collections.emptyMap(), files);
|
responseData = httpTool.requestFile(url, params, Collections.emptyMap(), files);
|
||||||
} else {
|
} else {
|
||||||
responseData = httpTool.request(url, params, Collections.emptyMap(), HTTPMethod.fromValue(httpMethod));
|
responseData = httpTool.request(url, params, Collections.emptyMap(), HTTPMethod.fromValue(httpMethod));
|
||||||
|
@@ -92,6 +92,7 @@ public class SwaggerDocParser implements DocParser {
|
|||||||
docItem.setSummary(docInfo.getString("summary"));
|
docItem.setSummary(docInfo.getString("summary"));
|
||||||
docItem.setDescription(docInfo.getString("description"));
|
docItem.setDescription(docInfo.getString("description"));
|
||||||
docItem.setMultiple(docInfo.getString("multiple") != null);
|
docItem.setMultiple(docInfo.getString("multiple") != null);
|
||||||
|
docItem.setProduces(docInfo.getJSONArray("produces").toJavaList(String.class));
|
||||||
String moduleName = this.buildModuleName(docInfo, docRoot);
|
String moduleName = this.buildModuleName(docInfo, docRoot);
|
||||||
docItem.setModule(moduleName);
|
docItem.setModule(moduleName);
|
||||||
List<DocParameter> docParameterList = this.buildRequestParameterList(docInfo, docRoot);
|
List<DocParameter> docParameterList = this.buildRequestParameterList(docInfo, docRoot);
|
||||||
|
Reference in New Issue
Block a user