mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
支持文件上传
This commit is contained in:
@@ -1,26 +1,26 @@
|
||||
* [首页](/?t=1557743036163)
|
||||
* [首页](/?t=1557833057337)
|
||||
* 开发文档
|
||||
* [快速体验](files/10010_快速体验.md?t=1557743036167)
|
||||
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1557743036187)
|
||||
* [新增接口](files/10020_新增接口.md?t=1557743036187)
|
||||
* [业务参数校验](files/10030_业务参数校验.md?t=1557743036187)
|
||||
* [错误处理](files/10040_错误处理.md?t=1557743036187)
|
||||
* [编写文档](files/10041_编写文档.md?t=1557743036188)
|
||||
* [接口交互详解](files/10050_接口交互详解.md?t=1557743036188)
|
||||
* [easyopen支持](files/10070_easyopen支持.md?t=1557743036188)
|
||||
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1557743036188)
|
||||
* [ISV管理](files/10085_ISV管理.md?t=1557743036188)
|
||||
* [路由授权](files/10090_路由授权.md?t=1557743036188)
|
||||
* [接口限流](files/10092_接口限流.md?t=1557743036188)
|
||||
* [SDK开发](files/10095_SDK开发.md?t=1557743036189)
|
||||
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1557743036189)
|
||||
* [应用授权](files/10097_应用授权.md?t=1557743036189)
|
||||
* [更改数据节点名称](files/10099_更改数据节点名称.md?t=1557743036189)
|
||||
* [对接前端](files/10100_对接前端.md?t=1557743036189)
|
||||
* [自定义过滤器](files/10102_自定义过滤器.md?t=1557743036189)
|
||||
* [快速体验](files/10010_快速体验.md?t=1557833057339)
|
||||
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1557833057355)
|
||||
* [新增接口](files/10020_新增接口.md?t=1557833057355)
|
||||
* [业务参数校验](files/10030_业务参数校验.md?t=1557833057355)
|
||||
* [错误处理](files/10040_错误处理.md?t=1557833057355)
|
||||
* [编写文档](files/10041_编写文档.md?t=1557833057355)
|
||||
* [接口交互详解](files/10050_接口交互详解.md?t=1557833057355)
|
||||
* [easyopen支持](files/10070_easyopen支持.md?t=1557833057356)
|
||||
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1557833057356)
|
||||
* [ISV管理](files/10085_ISV管理.md?t=1557833057356)
|
||||
* [路由授权](files/10090_路由授权.md?t=1557833057356)
|
||||
* [接口限流](files/10092_接口限流.md?t=1557833057356)
|
||||
* [SDK开发](files/10095_SDK开发.md?t=1557833057356)
|
||||
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1557833057356)
|
||||
* [应用授权](files/10097_应用授权.md?t=1557833057356)
|
||||
* [更改数据节点名称](files/10099_更改数据节点名称.md?t=1557833057356)
|
||||
* [对接前端](files/10100_对接前端.md?t=1557833057356)
|
||||
* [自定义过滤器](files/10102_自定义过滤器.md?t=1557833057356)
|
||||
* 原理分析
|
||||
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1557743036189)
|
||||
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1557743036190)
|
||||
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1557743036190)
|
||||
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1557743036190)
|
||||
* [常见问题](files/90100_常见问题.md?t=1557743036190)
|
||||
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1557833057357)
|
||||
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1557833057357)
|
||||
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1557833057357)
|
||||
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1557833057357)
|
||||
* [常见问题](files/90100_常见问题.md?t=1557833057357)
|
||||
|
@@ -11,7 +11,7 @@ zuul过滤器列表如下:
|
||||
| pre | -998 | PreLimitFilter (SOP自带) | 限流拦截器 |
|
||||
| pre | -3 | ServletDetectionFilter | 标记处理 Servlet 的类型 |
|
||||
| pre | -2 | Servlet30WrapperFilter | 包装 HttpServletRequest 请求 |
|
||||
| pre | -1 | FormBodyWrapperFilter | 包装请求体 |
|
||||
| pre | -1 | FormBodyWrapperFilter | 包装请求体 Servlet30WrapperFilter |
|
||||
| pre | 1 | DebugFilter | 标记调试标志 |
|
||||
| pre | 5 | PreDecorationFilter | 决定路由转发过滤器 |
|
||||
| route | 10 | RibbonRoutingFilter | serviceId 请求转发 |
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
|
@@ -5,11 +5,11 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>sop-gateway-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sop-gateway-common</name>
|
||||
|
@@ -34,6 +34,9 @@ public abstract class BaseParamBuilder<T> implements ParamBuilder<T> {
|
||||
}
|
||||
|
||||
protected void initOtherProperty(ApiParam apiParam) {
|
||||
if (apiParam.size() == 0) {
|
||||
throw ErrorEnum.ISV_INVALID_METHOD.getErrorMeta().getException();
|
||||
}
|
||||
RouteRepository<? extends TargetRoute> routeRepository = RouteRepositoryContext.getRouteRepository();
|
||||
if (routeRepository == null) {
|
||||
log.error("RouteRepositoryContext.setRouteRepository()方法未使用");
|
||||
|
@@ -1,7 +1,12 @@
|
||||
package com.gitee.sop.gatewaycommon.util;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
@@ -9,6 +14,8 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -18,7 +25,12 @@ import java.util.Set;
|
||||
*/
|
||||
public class RequestUtil {
|
||||
|
||||
private RequestUtil(){}
|
||||
private static Logger log = LoggerFactory.getLogger(RequestUtil.class);
|
||||
|
||||
private RequestUtil() {
|
||||
}
|
||||
|
||||
public static final String MULTIPART = "multipart/";
|
||||
|
||||
private static final String UTF8 = "UTF-8";
|
||||
|
||||
@@ -57,7 +69,7 @@ public class RequestUtil {
|
||||
*/
|
||||
public static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
|
||||
Map<String, String[]> paramMap = request.getParameterMap();
|
||||
if(paramMap == null || paramMap.isEmpty()) {
|
||||
if (paramMap == null || paramMap.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<String, String> retMap = new HashMap<>(paramMap.size());
|
||||
@@ -76,6 +88,40 @@ public class RequestUtil {
|
||||
return retMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件上传表单中的字段,不包括文件,请求类型是multipart/form-data
|
||||
*
|
||||
* @param request
|
||||
* @return 返回表单中的字段内容
|
||||
*/
|
||||
public static Map<String, String> convertMultipartRequestToMap(HttpServletRequest request) {
|
||||
DiskFileItemFactory factory = new DiskFileItemFactory();
|
||||
//2、创建一个文件上传解析器
|
||||
ServletFileUpload upload = new ServletFileUpload(factory);
|
||||
Map<String, String> params = new HashMap<>();
|
||||
try {
|
||||
List<FileItem> fileItems = upload.parseRequest(request);
|
||||
for (FileItem fileItem : fileItems) {
|
||||
if (fileItem.isFormField()) {
|
||||
params.put(fileItem.getFieldName(), fileItem.getString(UTF8));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("参数解析错误", e);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
public static boolean isMultipart(HttpServletRequest request) {
|
||||
String contentType = request.getContentType();
|
||||
// Don't use this filter on GET method
|
||||
if (contentType == null) {
|
||||
return false;
|
||||
}
|
||||
return contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART);
|
||||
}
|
||||
|
||||
|
||||
public static String getText(HttpServletRequest request) throws IOException {
|
||||
return IOUtils.toString(request.getInputStream(), UTF8);
|
||||
}
|
||||
|
@@ -4,10 +4,12 @@ import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
||||
import com.gitee.sop.gatewaycommon.manager.AbstractConfiguration;
|
||||
import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext;
|
||||
import com.gitee.sop.gatewaycommon.zuul.filter.ErrorFilter;
|
||||
import com.gitee.sop.gatewaycommon.zuul.filter.FormBodyWrapperFilterExt;
|
||||
import com.gitee.sop.gatewaycommon.zuul.filter.PostResultFilter;
|
||||
import com.gitee.sop.gatewaycommon.zuul.filter.PreLimitFilter;
|
||||
import com.gitee.sop.gatewaycommon.zuul.filter.PreRoutePermissionFilter;
|
||||
import com.gitee.sop.gatewaycommon.zuul.filter.PreValidateFilter;
|
||||
import com.gitee.sop.gatewaycommon.zuul.filter.Servlet30WrapperFilterExt;
|
||||
import com.gitee.sop.gatewaycommon.zuul.route.SopRouteLocator;
|
||||
import com.gitee.sop.gatewaycommon.zuul.route.ZuulRouteRepository;
|
||||
import com.gitee.sop.gatewaycommon.zuul.route.ZuulZookeeperRouteManager;
|
||||
@@ -42,6 +44,16 @@ public class BaseZuulConfiguration extends AbstractConfiguration {
|
||||
return zuulRouteRepository;
|
||||
}
|
||||
|
||||
@Bean
|
||||
FormBodyWrapperFilterExt formBodyWrapperFilterExt() {
|
||||
return new FormBodyWrapperFilterExt();
|
||||
}
|
||||
|
||||
@Bean
|
||||
Servlet30WrapperFilterExt servlet30WrapperFilterExt() {
|
||||
return new Servlet30WrapperFilterExt();
|
||||
}
|
||||
|
||||
/**
|
||||
* 选取路由
|
||||
* @param zuulRouteRepository
|
||||
|
@@ -0,0 +1,22 @@
|
||||
package com.gitee.sop.gatewaycommon.zuul.filter;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.util.RequestUtil;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class FormBodyWrapperFilterExt extends FormBodyWrapperFilter {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
// 不是上传文件请求,则进行包装
|
||||
return !RequestUtil.isMultipart(request);
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package com.gitee.sop.gatewaycommon.zuul.filter;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.util.RequestUtil;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class Servlet30WrapperFilterExt extends Servlet30WrapperFilter {
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
// 不是上传文件请求,则进行包装
|
||||
return !RequestUtil.isMultipart(request);
|
||||
}
|
||||
}
|
@@ -6,10 +6,16 @@ import com.gitee.sop.gatewaycommon.param.ApiParam;
|
||||
import com.gitee.sop.gatewaycommon.param.BaseParamBuilder;
|
||||
import com.gitee.sop.gatewaycommon.util.RequestUtil;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import com.netflix.zuul.http.HttpServletRequestWrapper;
|
||||
import com.netflix.zuul.http.ServletInputStreamWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -24,7 +30,6 @@ public class ZuulParamBuilder extends BaseParamBuilder<RequestContext> {
|
||||
private static final String CONTENT_TYPE_TEXT = MediaType.TEXT_PLAIN_VALUE;
|
||||
private static final String GET = "get";
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, String> buildRequestParams(RequestContext ctx) {
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
@@ -44,6 +49,11 @@ public class ZuulParamBuilder extends BaseParamBuilder<RequestContext> {
|
||||
// json或者纯文本形式
|
||||
if (contentType.contains(CONTENT_TYPE_JSON) || contentType.contains(CONTENT_TYPE_TEXT)) {
|
||||
throw ErrorEnum.ISV_INVALID_CONTENT_TYPE.getErrorMeta().getException();
|
||||
} else if (ServletFileUpload.isMultipartContent(request)) {
|
||||
MultipartRequestWrapper wrapper = new MultipartRequestWrapper(request);
|
||||
ctx.setRequest(wrapper);
|
||||
ctx.getZuulRequestHeaders().put("content-type", wrapper.getContentType());
|
||||
params = RequestUtil.convertMultipartRequestToMap(wrapper);
|
||||
} else {
|
||||
params = RequestUtil.convertRequestParamsToMap(request);
|
||||
}
|
||||
@@ -63,4 +73,45 @@ public class ZuulParamBuilder extends BaseParamBuilder<RequestContext> {
|
||||
return apiParam;
|
||||
}
|
||||
|
||||
public static class MultipartRequestWrapper extends HttpServletRequestWrapper {
|
||||
private HttpServletRequest request;
|
||||
|
||||
private volatile byte[] contentData;
|
||||
|
||||
private MediaType contentType;
|
||||
|
||||
private int contentLength;
|
||||
|
||||
public MultipartRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
this.request = request;
|
||||
try {
|
||||
this.contentType = MediaType.valueOf(this.request.getContentType());
|
||||
byte[] input = IOUtils.toByteArray(request.getInputStream());
|
||||
this.contentData = input;
|
||||
this.contentLength = input.length;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Cannot convert form data", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return this.contentType.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContentLength() {
|
||||
if (super.getContentLength() <= 0) {
|
||||
return super.getContentLength();
|
||||
}
|
||||
return this.contentLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
return new ServletInputStreamWrapper(this.contentData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,11 +6,11 @@
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>sop-service-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sop-service-common</name>
|
||||
|
@@ -26,7 +26,7 @@
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-service-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
|
@@ -23,7 +23,7 @@
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-service-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
|
@@ -29,7 +29,7 @@
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-service-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
|
@@ -20,7 +20,7 @@
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-service-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- eureka 服务发现 -->
|
||||
<dependency>
|
||||
|
@@ -23,7 +23,7 @@
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-service-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
|
@@ -0,0 +1,56 @@
|
||||
package com.gitee.sop.storyweb.controller;
|
||||
|
||||
import com.gitee.sop.servercommon.annotation.ApiMapping;
|
||||
import com.gitee.sop.storyweb.controller.param.FileUploadParam;
|
||||
import com.gitee.sop.storyweb.vo.FileUploadVO;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 演示文件上传
|
||||
* @author tanghc
|
||||
*/
|
||||
@RestController
|
||||
public class FileUploadDemoController {
|
||||
|
||||
/**
|
||||
* 接收客户端上传的文件,然后把文件信息返回给客户端
|
||||
* @param param
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@ApiMapping(value = "demo.file.upload", ignoreValidate = true)
|
||||
public FileUploadVO file(FileUploadParam param, HttpServletRequest request) {
|
||||
System.out.println(param.getRemark());
|
||||
FileUploadVO vo = new FileUploadVO();
|
||||
//检查form中是否有enctype="multipart/form-data"
|
||||
if (ServletFileUpload.isMultipartContent(request)) {
|
||||
//将request变成多部分request
|
||||
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multiRequest.getFileMap();
|
||||
fileMap.entrySet()
|
||||
.stream()
|
||||
.forEach(entry->{
|
||||
MultipartFile multipartFile = entry.getValue();
|
||||
try {
|
||||
String fileName = multipartFile.getOriginalFilename();
|
||||
long size = multipartFile.getSize();
|
||||
String fileContent = IOUtils.toString(multipartFile.getInputStream(), "UTF-8");
|
||||
FileUploadVO.FileMeta fileMeta = new FileUploadVO.FileMeta(fileName, size, fileContent);
|
||||
vo.getFiles().add(fileMeta);
|
||||
System.out.println(fileContent);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package com.gitee.sop.storyweb.controller.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Data
|
||||
public class FileUploadParam {
|
||||
private String remark;
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package com.gitee.sop.storyweb.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Data
|
||||
public class FileUploadVO {
|
||||
|
||||
private List<FileMeta> files = new ArrayList();
|
||||
|
||||
@Data
|
||||
public static class FileMeta {
|
||||
|
||||
public FileMeta(String filename, long size, String content) {
|
||||
this.filename = filename;
|
||||
this.size = size;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public FileMeta() {
|
||||
}
|
||||
|
||||
private String filename;
|
||||
private long size;
|
||||
private String content;
|
||||
}
|
||||
}
|
@@ -23,7 +23,7 @@
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-gateway-common</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ↓↓↓ 使用spring cloud zuul ↓↓↓ -->
|
||||
|
@@ -4,8 +4,15 @@ server:
|
||||
zuul:
|
||||
# 入口地址,不用改,默认是/zuul
|
||||
servlet-path: /api
|
||||
# 禁用默认的过滤器,不能删,不用改
|
||||
FormBodyWrapperFilter:
|
||||
pre:
|
||||
disable: true
|
||||
Servlet30WrapperFilter:
|
||||
pre:
|
||||
disable: true
|
||||
|
||||
# 注册中心
|
||||
# 注册中心,根据实际情况修改
|
||||
eureka:
|
||||
serverAddr: localhost:1111
|
||||
client:
|
||||
@@ -15,21 +22,29 @@ eureka:
|
||||
spring:
|
||||
application:
|
||||
name: api-gateway
|
||||
|
||||
# zookeeper,根据实际情况修改
|
||||
cloud:
|
||||
zookeeper:
|
||||
connect-string: localhost:2181
|
||||
|
||||
gateway: # Spring Cloud Gateway配置,如果用了zuul,这段配置没有效果
|
||||
# Spring Cloud Gateway配置,如果用了zuul,这段配置没有效果,不用改
|
||||
gateway:
|
||||
discovery:
|
||||
locator:
|
||||
lower-case-service-id: true
|
||||
enabled: true
|
||||
|
||||
|
||||
# 数据源
|
||||
# 数据源,根据实际情况修改
|
||||
datasource:
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
|
||||
username: root
|
||||
password: root
|
||||
password: root
|
||||
|
||||
# 上传文件配置,根据实际情况修改
|
||||
servlet:
|
||||
multipart:
|
||||
enabled: true
|
||||
max-file-size: 20MB # 上传文件最大20MB,默认1MB
|
||||
max-request-size: 20MB
|
||||
|
@@ -25,6 +25,7 @@ public class OpenClient {
|
||||
private static final Log log = LogFactory.getLog(OpenClient.class);
|
||||
|
||||
private static final OpenConfig DEFAULT_CONFIG = new OpenConfig();
|
||||
public static final String ERROR_RESPONSE_KEY = "error_response";
|
||||
|
||||
private String url;
|
||||
private String appId;
|
||||
@@ -110,6 +111,10 @@ public class OpenClient {
|
||||
String method = request.getMethod();
|
||||
String dataName = dataNameBuilder.build(method);
|
||||
JSONObject jsonObject = JSON.parseObject(resp);
|
||||
boolean errorResponse = jsonObject.containsKey(ERROR_RESPONSE_KEY);
|
||||
if (errorResponse) {
|
||||
dataName = ERROR_RESPONSE_KEY;
|
||||
}
|
||||
JSONObject data = jsonObject.getJSONObject(dataName);
|
||||
T t = data.toJavaObject(request.getResponseClass());
|
||||
t.setBody(data.toJSONString());
|
||||
|
@@ -6,7 +6,6 @@ import okhttp3.Cookie;
|
||||
import okhttp3.CookieJar;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.MultipartBody;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
@@ -26,8 +25,6 @@ import java.util.concurrent.TimeUnit;
|
||||
* @author tanghc
|
||||
*/
|
||||
public class OpenHttp {
|
||||
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
|
||||
private Map<String, List<Cookie>> cookieStore = new HashMap<String, List<Cookie>>();
|
||||
|
||||
private OkHttpClient httpClient;
|
||||
|
@@ -3,6 +3,8 @@ package com.gitee.sop.sdk.common;
|
||||
|
||||
import com.gitee.sop.sdk.util.FileUtil;
|
||||
import com.gitee.sop.sdk.util.MD5Util;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -13,6 +15,8 @@ import java.io.Serializable;
|
||||
* 文件上传类
|
||||
* @author tanghc
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class UploadFile implements Serializable {
|
||||
private static final long serialVersionUID = -1100614660944996398L;
|
||||
|
||||
@@ -53,36 +57,4 @@ public class UploadFile implements Serializable {
|
||||
private byte[] fileData;
|
||||
private String md5;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public byte[] getFileData() {
|
||||
return fileData;
|
||||
}
|
||||
|
||||
public void setFileData(byte[] fileData) {
|
||||
this.fileData = fileData;
|
||||
}
|
||||
|
||||
public String getMd5() {
|
||||
return md5;
|
||||
}
|
||||
|
||||
public void setMd5(String md5) {
|
||||
this.md5 = md5;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,11 @@
|
||||
package com.gitee.sop.sdk.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Data
|
||||
public class DemoFileUploadModel {
|
||||
private String remark;
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package com.gitee.sop.sdk.request;
|
||||
|
||||
import com.gitee.sop.sdk.response.DemoFileUploadResponse;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class DemoFileUploadRequest extends BaseRequest<DemoFileUploadResponse> {
|
||||
@Override
|
||||
protected String method() {
|
||||
return "demo.file.upload";
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package com.gitee.sop.sdk.response;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class DemoFileUploadResponse extends BaseResponse {
|
||||
|
||||
private List<FileMeta> files = new ArrayList();
|
||||
|
||||
@Data
|
||||
public static class FileMeta {
|
||||
|
||||
public FileMeta(String filename, long size, String content) {
|
||||
this.filename = filename;
|
||||
this.size = size;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public FileMeta() {
|
||||
}
|
||||
|
||||
private String filename;
|
||||
private long size;
|
||||
private String content;
|
||||
}
|
||||
}
|
1
sop-sdk/sdk-java/src/main/resources/file1.txt
Normal file
1
sop-sdk/sdk-java/src/main/resources/file1.txt
Normal file
@@ -0,0 +1 @@
|
||||
file1 content
|
1
sop-sdk/sdk-java/src/main/resources/file2.txt
Normal file
1
sop-sdk/sdk-java/src/main/resources/file2.txt
Normal file
@@ -0,0 +1 @@
|
||||
file2 content...
|
@@ -1,2 +0,0 @@
|
||||
回忆起 20多年来我们一起走过的日子,我就感到特别温馨、特别甜蜜。你第一次闯入我生命中的情景,仿佛就在眼前……第一次偶然相遇是1996年5月,那是一个夏风习习的夜晚,我刚从工地回来,同事就邀我一起去城建学院跳舞,踏进舞厅的一瞬间,在暗淡温柔的霓虹灯下,你那清新脱俗的靓影一下子就深深的嵌入了我的心里。
|
||||
记得大学时代,李春波的歌曲“小芳”响彻校园,那个叫小芳的村里姑娘,也深深的烙进了我的心底,成了我少年时的梦中偶像。二十多年来,我一直期盼着找到一个象歌曲中所唱的长得好看又善良、有着一双美丽的大眼睛和两条粗辫子的姑娘做我的爱人,但苦苦寻觅却难见芳踪,谁知众里寻她千百度,蓦然回首,那人却在灯火阑珊处……你就这样俏生生的突然出现在我眼前。当时,你穿着浅绿色的衬衣,正在与一位女同学翩翩起舞,两条又粗又长的辫子在身后灵巧的晃动。一曲终了,我急忙挤到你身边请你跳舞。当时的我还不太会跳舞,还好是一首慢四舞曲,我才没出洋相。拥着你在舞厅漫步,因为心情特别激动,又怕舞步不熟踩到你脚,我眼睛始终盯着脚下,不敢正视你的目光;好不容易平复心情与你搭讪,才打探到你是教育学院的学生舞曲就结束了。后面的舞曲不是我不会跳就是被你那“讨厌”的女同学捷足先登了,始终没有机会再次与你共舞,但我的心已经完完全全的被你牵走了。同事周云看我不再跳舞、心事重重的,就问我为什么,得知我心事后,自告奋勇的说下一曲他去邀请你同学,让我有机会请你跳舞。可没想到我那同事的“光头”会把你们吓跑,让上天给我们安排的第一次相遇就这样擦肩而过。
|
@@ -1 +0,0 @@
|
||||
红与青 时光如流水般,在我面前一闪而过,但我却只能暗暗叹息。 台灯下,小桌前,我坐在那儿,目光停在桌子上的那一个西瓜面前。十几年前的往事仿佛就在昨日。 小时候,我们兄弟几个围坐在一张破破的桌子前。一个勺子,半个西瓜,大家围着轮流舀着吃,大家的目光都聚焦在西瓜上,也许只有在这一刻,我们才不会那样的打闹。我们都想吃最中间的部分,最红的,最甜的部分,可是又如同大人世界般,我们显得那样腼腆。最后,总是你一小口我一小口,把那中间红红的果肉吞进肚子里,更埋下友谊的种子。 日子深一脚浅一脚的过,学习似乎成了我们唯一的公同语言,我们也从一个被别人称为“造反派”的顽童变为一个学子。甚至有时,在哪儿碰见也只会向对方点点头,丝毫没有了小时烈日下奔跑的情谊。家里的那张破破的桌子也不知去向,取而代之的是一张豪华的青瓷桌…… 小学毕业后那年暑假的最后一天,刚刚步入六年级的他们来送别我,我们围坐在桌边,夏日的炎热似乎把我们所有要诉说的话都给憋了回去,我们都沉默着。冰爽的西瓜成了我们释放的对象,我们不再像小时那样子吃西瓜,所有的西瓜都被切成了片,有红,有青。红红的那部分就在最上面,我们之间的友情就像这样火红。 没有告别仪式,只是如青般离开。 “悄悄,是别离的笙箫” 迈入初中,一切都是陌生,交流变少了,浑浑噩噩的梦中,我又梦见了他们。 关了台灯,寂静与黑暗容我沉思。 初一就要结束的几天里,夏天悄无声息得把炎热带来,家人们又带回来了西瓜,复习之余,我又捧起了半个西瓜,这一回就我一人沉默。握着勺子,一口一口舀着慢慢品味。“嗯?”与瓜皮连着的青色果肉吸引了我。“啊!原来他们比中间的果肉更惹人迷!” 我舀了一勺,“咔嚓”,是多么清脆。 “但我不能放歌”,时光荏苒,十几年前的往事似乎又模模糊糊。 他们如流水划过,留下一道青色的痕迹。青,是青。
|
@@ -3,15 +3,23 @@ package com.gitee.sop.sdk;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.gitee.sop.sdk.client.OpenClient;
|
||||
import com.gitee.sop.sdk.common.UploadFile;
|
||||
import com.gitee.sop.sdk.model.DemoFileUploadModel;
|
||||
import com.gitee.sop.sdk.model.GetStoryModel;
|
||||
import com.gitee.sop.sdk.request.CommonRequest;
|
||||
import com.gitee.sop.sdk.request.DemoFileUploadRequest;
|
||||
import com.gitee.sop.sdk.request.GetStoryRequest;
|
||||
import com.gitee.sop.sdk.response.CommonResponse;
|
||||
import com.gitee.sop.sdk.response.DemoFileUploadResponse;
|
||||
import com.gitee.sop.sdk.response.GetStoryResponse;
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SdkTest extends TestCase {
|
||||
@@ -70,4 +78,35 @@ public class SdkTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
// 文件上传
|
||||
@Test
|
||||
public void testUpload() throws IOException {
|
||||
DemoFileUploadRequest request = new DemoFileUploadRequest();
|
||||
|
||||
DemoFileUploadModel model = new DemoFileUploadModel();
|
||||
model.setRemark("上传文件参数");
|
||||
request.setBizModel(model);
|
||||
|
||||
List<UploadFile> files = new ArrayList<>();
|
||||
String root = System.getProperty("user.dir");
|
||||
System.out.println(root);
|
||||
files.add(new UploadFile("file1", new File(root + "/src/main/resources/file1.txt")));
|
||||
files.add(new UploadFile("file2", new File(root + "/src/main/resources/file2.txt")));
|
||||
request.setFiles(files);
|
||||
|
||||
DemoFileUploadResponse response = client.execute(request);
|
||||
|
||||
System.out.println("--------------------");
|
||||
if (response.isSuccess()) {
|
||||
List<DemoFileUploadResponse.FileMeta> responseFiles = response.getFiles();
|
||||
System.out.println("您上传的文件信息:");
|
||||
responseFiles.stream().forEach(file->{
|
||||
System.out.println(file);
|
||||
});
|
||||
} else {
|
||||
System.out.println("errorCode:" + response.getCode() + ",errorMsg:" + response.getMsg());
|
||||
}
|
||||
System.out.println("--------------------");
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user