怎建远程调用文件上传

This commit is contained in:
wanggeng 2022-08-07 22:00:10 +08:00
parent aa85cae903
commit 4354516b20
5 changed files with 381 additions and 54 deletions

View File

@ -6,6 +6,8 @@ import ink.wgink.annotation.rpc.rest.method.RemoteGetMethod;
import ink.wgink.annotation.rpc.rest.method.RemotePostMethod;
import ink.wgink.annotation.rpc.rest.method.RemotePutMethod;
import ink.wgink.annotation.rpc.rest.params.*;
import ink.wgink.common.rpc.rest.pojo.RemoteFileInputStream;
import ink.wgink.common.rpc.rest.pojo.RemoteRequest;
import ink.wgink.common.rpc.rest.request.RestRemoteRequest;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.exceptions.base.SystemException;
@ -15,6 +17,7 @@ import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMethod;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@ -63,6 +66,8 @@ public class RestRemoteHandler implements InvocationHandler {
MultiValueMap<String, Object> formVariableParams = null;
String uri;
Object requestBody = null;
Map<String, RemoteFileInputStream> fileInputStreamVariableParams = null;
Map<String, File> fileVariableParams = null;
RequestMethod requestMethod;
if (method.isAnnotationPresent(RemoteGetMethod.class)) {
// GET请求
@ -79,8 +84,18 @@ public class RestRemoteHandler implements InvocationHandler {
requestMethod = RequestMethod.POST;
RemotePostMethod postMethod = method.getAnnotation(RemotePostMethod.class);
uri = postMethod.value();
// 1. 先判断是否有文件
fileVariableParams = getFileParams(method.getParameters(), args);
if (fileVariableParams.isEmpty()) {
// 2. 判断是否是文件流
fileInputStreamVariableParams = getFileInputStreamParams(method.getParameters(), args);
}
// 3. 判断表单
formVariableParams = getFormVariableParams(method.getParameters(), args);
if (formVariableParams.isEmpty()) {
if ((fileInputStreamVariableParams == null || fileInputStreamVariableParams.isEmpty()) &&
fileVariableParams.isEmpty() &&
formVariableParams.isEmpty()) {
// 4. 文件与表单都不存在判断json
requestBody = getRequestBody(method.getParameters(), args);
}
} else if (method.isAnnotationPresent(RemotePutMethod.class)) {
@ -97,8 +112,18 @@ public class RestRemoteHandler implements InvocationHandler {
checkPathVariableParams(pathVariable, pathVariableParams);
uri = buildUri(baseUri, uri, pathVariable, pathVariableParams);
String remoteFullPath = buildFullUri(remotePath, uri, queryVariableParams, queryMapParams);
RestRemoteRequest restRemoteRequest = new RestRemoteRequest();
return restRemoteRequest.request(requestMethod, remoteFullPath, headerVariableParams, formVariableParams, requestBody, method.getGenericReturnType());
// 发起请求
RemoteRequest remoteRequest = new RemoteRequest();
remoteRequest.setRequestMethod(requestMethod);
remoteRequest.setRemoteUri(remoteFullPath);
remoteRequest.setHeaders(headerVariableParams);
remoteRequest.setFormVariableParams(formVariableParams);
remoteRequest.setFileVariableParams(fileVariableParams);
remoteRequest.setFileInputStreamVariableParams(fileInputStreamVariableParams);
remoteRequest.setJsonBody(requestBody);
remoteRequest.setResultType(method.getGenericReturnType());
return new RestRemoteRequest().request(remoteRequest);
}
/**
@ -172,6 +197,68 @@ public class RestRemoteHandler implements InvocationHandler {
return queryVariableParamsMap;
}
/**
* 文件
*
* @param parameters
* @param args
* @return
*/
private Map<String, File> getFileParams(Parameter[] parameters, Object[] args) {
Map<String, File> fileParams = new HashMap<>(0);
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(RemoteFileParams.class)) {
continue;
}
RemoteFileParams annotation = parameter.getAnnotation(RemoteFileParams.class);
String variableName = annotation.value();
if (StringUtils.isBlank(variableName)) {
throw new ParamsException("参数 " + parameter.getName() + " 名称不能为空");
}
Object arg = args[i];
if (arg == null) {
throw new ParamsException("参数 " + parameter.getName() + " 不能为空");
}
if (!(arg instanceof File)) {
throw new ParamsException("参数 " + parameter.getName() + " 类型需为 java.io.File");
}
fileParams.put(variableName, (File) arg);
}
return fileParams;
}
/**
* 文件流
*
* @param parameters
* @param args
* @return
*/
private Map<String, RemoteFileInputStream> getFileInputStreamParams(Parameter[] parameters, Object[] args) {
Map<String, RemoteFileInputStream> inputStreamParams = new HashMap<>(0);
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (!parameter.isAnnotationPresent(RemoteFileInputStreamParams.class)) {
continue;
}
RemoteFileInputStreamParams annotation = parameter.getAnnotation(RemoteFileInputStreamParams.class);
String variableName = annotation.value();
if (StringUtils.isBlank(variableName)) {
throw new ParamsException("参数 " + parameter.getName() + " 名称不能为空");
}
Object arg = args[i];
if (arg == null) {
throw new ParamsException("参数 " + parameter.getName() + " 不能为空");
}
if (!(arg instanceof RemoteFileInputStream)) {
throw new ParamsException("参数 " + parameter.getName() + " 类型需为 ink.wgink.common.rpc.rest.pojo.RemoteFileInputStream");
}
inputStreamParams.put(variableName, (RemoteFileInputStream) arg);
}
return inputStreamParams;
}
/**
* 表单参数
*

View File

@ -0,0 +1,41 @@
package ink.wgink.common.rpc.rest.pojo;
import java.io.InputStream;
/**
* @ClassName: RemoteFileInputStream
* @Description: 远程文件流
* @Author: wanggeng
* @Date: 2022/8/4 14:44
* @Version: 1.0
*/
public class RemoteFileInputStream {
private String fileName;
private long fileSize;
private InputStream inputStream;
public String getFileName() {
return fileName == null ? "" : fileName.trim();
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
}

View File

@ -0,0 +1,94 @@
package ink.wgink.common.rpc.rest.pojo;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMethod;
import java.io.File;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: RemoteRequest
* @Description: 远程请求
* @Author: wanggeng
* @Date: 2022/8/4 14:43
* @Version: 1.0
*/
public class RemoteRequest {
private RequestMethod requestMethod;
private String remoteUri;
private Map<String, String> headers;
private MultiValueMap<String, Object> formVariableParams;
private Object jsonBody;
private Map<String, File> fileVariableParams;
private Map<String, RemoteFileInputStream> fileInputStreamVariableParams;
private Type resultType;
public RequestMethod getRequestMethod() {
return requestMethod;
}
public void setRequestMethod(RequestMethod requestMethod) {
this.requestMethod = requestMethod;
}
public String getRemoteUri() {
return remoteUri == null ? "" : remoteUri.trim();
}
public void setRemoteUri(String remoteUri) {
this.remoteUri = remoteUri;
}
public Map<String, String> getHeaders() {
return headers == null ? new HashMap<>() : headers;
}
public void setHeaders(Map<String, String> headers) {
this.headers = headers;
}
public MultiValueMap<String, Object> getFormVariableParams() {
return formVariableParams == null ? new LinkedMultiValueMap<>() : formVariableParams;
}
public void setFormVariableParams(MultiValueMap<String, Object> formVariableParams) {
this.formVariableParams = formVariableParams;
}
public Object getJsonBody() {
return jsonBody;
}
public void setJsonBody(Object jsonBody) {
this.jsonBody = jsonBody;
}
public Map<String, File> getFileVariableParams() {
return fileVariableParams == null ? new HashMap<>() : fileVariableParams;
}
public void setFileVariableParams(Map<String, File> fileVariableParams) {
this.fileVariableParams = fileVariableParams;
}
public Map<String, RemoteFileInputStream> getFileInputStreamVariableParams() {
return fileInputStreamVariableParams;
}
public void setFileInputStreamVariableParams(Map<String, RemoteFileInputStream> fileInputStreamVariableParams) {
this.fileInputStreamVariableParams = fileInputStreamVariableParams;
}
public Type getResultType() {
return resultType;
}
public void setResultType(Type resultType) {
this.resultType = resultType;
}
}

View File

@ -3,19 +3,28 @@ package ink.wgink.common.rpc.rest.request;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import ink.wgink.common.rpc.rest.pojo.RemoteFileInputStream;
import ink.wgink.common.rpc.rest.pojo.RemoteRequest;
import ink.wgink.exceptions.FileException;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.exceptions.rpc.RemoteRequestException;
import ink.wgink.exceptions.rpc.RemoteResponseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
@ -48,7 +57,15 @@ public class RestRemoteRequest {
this.httpsTemplate = new RestTemplate(httpsClientRequestFactory);
}
public Object request(RequestMethod requestMethod, String remoteUri, Map<String, String> headers, MultiValueMap<String, Object> formVariableParams, Object jsonBody, Type resultType) {
public Object request(RemoteRequest remoteRequest) {
RequestMethod requestMethod = remoteRequest.getRequestMethod();
String remoteUri = remoteRequest.getRemoteUri();
Map<String, String> headers = remoteRequest.getHeaders();
MultiValueMap<String, Object> formVariableParams = remoteRequest.getFormVariableParams();
Map<String, File> fileVariableParams = remoteRequest.getFileVariableParams();
Map<String, RemoteFileInputStream> fileInputVariableParams = remoteRequest.getFileInputStreamVariableParams();
Object jsonBody = remoteRequest.getFormVariableParams();
Type resultType = remoteRequest.getResultType();
String result;
if (RequestMethod.GET.equals(requestMethod)) {
result = get(remoteUri, headers);
@ -56,8 +73,8 @@ public class RestRemoteRequest {
result = delete(remoteUri, headers);
} else if (RequestMethod.POST.equals(requestMethod)) {
// form表单优先
if (!formVariableParams.isEmpty()) {
result = post(remoteUri, headers, formVariableParams);
if (!fileVariableParams.isEmpty() || !fileInputVariableParams.isEmpty() || !formVariableParams.isEmpty()) {
result = post(remoteUri, headers, fileVariableParams, fileInputVariableParams, formVariableParams);
} else {
result = post(remoteUri, headers, jsonBody);
}
@ -66,7 +83,7 @@ public class RestRemoteRequest {
} else {
throw new ParamsException("请求方法不支持");
}
// 除了合其余均按对象
// 除了合其余均按对象
return JSONObject.parseObject(result, resultType);
}
@ -79,7 +96,7 @@ public class RestRemoteRequest {
*/
public String get(String remoteUri, Map<String, String> headers) {
try {
HttpEntity<String> httpEntity = getHttpEntity(headers, null, null);
HttpEntity<String> httpEntity = getHttpEntity(headers, null, null, null, null);
ResponseEntity<String> responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.GET, httpEntity, String.class);
return getStringResponse(responseEntity);
} catch (Exception e) {
@ -96,7 +113,7 @@ public class RestRemoteRequest {
*/
public String delete(String remoteUri, Map<String, String> headers) {
try {
HttpEntity<String> httpEntity = getHttpEntity(headers, null, null);
HttpEntity<String> httpEntity = getHttpEntity(headers, null, null, null, null);
ResponseEntity<String> responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.DELETE, httpEntity, String.class);
return getStringResponse(responseEntity);
} catch (Exception e) {
@ -114,7 +131,7 @@ public class RestRemoteRequest {
public String post(String remoteUri, Map<String, String> headers, Object jsonBody) {
LOG.debug("Request POST Json: {}", jsonBody);
try {
HttpEntity<String> httpEntity = getHttpEntity(headers, null, jsonBody);
HttpEntity<String> httpEntity = getHttpEntity(headers, null, null, null, jsonBody);
ResponseEntity<String> responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.POST, httpEntity, String.class);
return getStringResponse(responseEntity);
} catch (Exception e) {
@ -129,10 +146,14 @@ public class RestRemoteRequest {
* @param headers
* @return
*/
public String post(String remoteUri, Map<String, String> headers, MultiValueMap<String, Object> formVariableParams) {
public String post(String remoteUri,
Map<String, String> headers,
Map<String, File> fileMap,
Map<String, RemoteFileInputStream> fileInputStreamMap,
MultiValueMap<String, Object> formVariableParams) {
LOG.debug("Request POST Form: {}", formVariableParams);
try {
HttpEntity<String> httpEntity = getHttpEntity(headers, formVariableParams, null);
HttpEntity<String> httpEntity = getHttpEntity(headers, fileMap, fileInputStreamMap, formVariableParams, null);
ResponseEntity<String> responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.POST, httpEntity, String.class);
return getStringResponse(responseEntity);
} catch (Exception e) {
@ -149,7 +170,7 @@ public class RestRemoteRequest {
*/
public String put(String remoteUri, Map<String, String> headers, Object jsonBody) {
try {
HttpEntity<String> httpEntity = getHttpEntity(headers, null, jsonBody);
HttpEntity<String> httpEntity = getHttpEntity(headers, null, null, null, jsonBody);
ResponseEntity<String> responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.PUT, httpEntity, String.class);
return getStringResponse(responseEntity);
} catch (Exception e) {
@ -164,7 +185,11 @@ public class RestRemoteRequest {
* @param jsonBody
* @return
*/
private HttpEntity<String> getHttpEntity(Map<String, String> headerMap, MultiValueMap<String, Object> formVariableParams, Object jsonBody) {
private HttpEntity<String> getHttpEntity(Map<String, String> headerMap,
Map<String, File> fileMap,
Map<String, RemoteFileInputStream> fileInputStreamMap,
MultiValueMap<String, Object> formVariableParams,
Object jsonBody) {
LOG.debug("Request Header: {}", headerMap);
HttpEntity<String> httpEntity;
if (jsonBody != null) {
@ -175,16 +200,93 @@ public class RestRemoteRequest {
} else {
httpEntity = new HttpEntity(JSONObject.toJSONString(jsonBody), httpHeaders);
}
} else if (formVariableParams != null) {
} else if (!fileMap.isEmpty() || !fileInputStreamMap.isEmpty() || !formVariableParams.isEmpty()) {
HttpHeaders httpHeaders = getHttpHeaders(headerMap);
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
httpEntity = new HttpEntity(formVariableParams, httpHeaders);
MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
if (!fileMap.isEmpty()) {
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
setFileVariable(multiValueMap, fileMap);
} else if (!fileInputStreamMap.isEmpty()) {
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
setFileInputStreamVariable(multiValueMap, fileInputStreamMap);
} else {
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
}
if (!formVariableParams.isEmpty()) {
formVariableParams.forEach(multiValueMap::add);
}
httpEntity = new HttpEntity(multiValueMap, httpHeaders);
} else {
httpEntity = new HttpEntity(getHttpHeaders(headerMap));
}
return httpEntity;
}
/**
* 设置文件
*
* @param multiValueMap
* @param fileMap
*/
private void setFileVariable(MultiValueMap<String, Object> multiValueMap, Map<String, File> fileMap) {
try {
for (Map.Entry<String, File> kv : fileMap.entrySet()) {
String key = kv.getKey();
File file = kv.getValue();
FileInputStream fileInputStream = new FileInputStream(file);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 1M
byte[] buf = new byte[1024 * 1000];
for (int len = 0; (len = fileInputStream.read(buf)) > -1; ) {
byteArrayOutputStream.write(buf, 0, len);
}
ByteArrayResource fileAsResource = new ByteArrayResource(byteArrayOutputStream.toByteArray()) {
@Override
public String getFilename() {
return file.getName();
}
@Override
public long contentLength() {
return file.length();
}
};
multiValueMap.add(key, fileAsResource);
}
} catch (Exception e) {
throw new FileException(e);
}
}
/**
* 设置文件
*
* @param multiValueMap
* @param fileInputStreamMap
*/
private void setFileInputStreamVariable(MultiValueMap<String, Object> multiValueMap, Map<String, RemoteFileInputStream> fileInputStreamMap) {
try {
for (Map.Entry<String, RemoteFileInputStream> kv : fileInputStreamMap.entrySet()) {
String key = kv.getKey();
RemoteFileInputStream remoteFileInputStream = kv.getValue();
InputStreamResource inputStreamResource = new InputStreamResource(remoteFileInputStream.getInputStream()) {
@Override
public String getFilename() {
return remoteFileInputStream.getFileName();
}
@Override
public long contentLength() {
return remoteFileInputStream.getFileSize();
}
};
multiValueMap.add(key, inputStreamResource);
}
} catch (Exception e) {
throw new FileException(e);
}
}
/**
* 得到HTTP请求头
*

View File

@ -3,17 +3,13 @@ import ink.wgink.annotation.rpc.rest.method.RemoteDeleteMethod;
import ink.wgink.annotation.rpc.rest.method.RemoteGetMethod;
import ink.wgink.annotation.rpc.rest.method.RemotePostMethod;
import ink.wgink.annotation.rpc.rest.method.RemotePutMethod;
import ink.wgink.annotation.rpc.rest.params.RemoteJsonBodyParams;
import ink.wgink.annotation.rpc.rest.params.RemotePathParams;
import ink.wgink.annotation.rpc.rest.params.RemoteQueryParams;
import ink.wgink.annotation.rpc.rest.params.RemoteServerParams;
import ink.wgink.annotation.rpc.rest.params.*;
import ink.wgink.common.rpc.rest.proxy.RestRemoteProxy;
import ink.wgink.pojo.dtos.user.UserDTO;
import ink.wgink.pojo.result.SuccessResult;
import ink.wgink.pojo.result.SuccessResultList;
import java.util.ArrayList;
import java.util.HashMap;
import java.io.File;
import java.util.List;
import java.util.Map;
@ -48,43 +44,50 @@ public class RemoteTest {
@RemoteDeleteMethod("/app/user-expand/delete-release/{userIds}")
SuccessResult deleteRelease(@RemoteServerParams String remotePath, @RemotePathParams("userIds") String userIds);
@RemotePostMethod("/api/file/v2/upload-file")
String file(@RemoteServerParams String remotePath, @RemoteFileParams("file") File file);
}
public static void main(String[] args) {
String remotePath = "http://127.0.0.1:7008/study";
IDemo instance = RestRemoteProxy.getInstance(IDemo.class);
UserDTO userDTO = instance.getUser(remotePath, "e48e9c4a-995e-4061-abcd-a3c260c11333");
System.out.println(userDTO);
System.out.println();
// UserDTO userDTO = instance.getUser(remotePath, "e48e9c4a-995e-4061-abcd-a3c260c11333");
// System.out.println(userDTO);
// System.out.println();
//
// List<UserDTO> userDTOs = instance.listUser(remotePath);
// System.out.println(userDTOs.size());
// System.out.println();
//
// SuccessResultList<List<UserDTO>> successResultUserList = instance.listPageUser(remotePath, 1, 5);
// System.out.println(successResultUserList.getPage());
// System.out.println();
//
// Map<String, Object> requestBody = new HashMap<>();
// requestBody.put("aaa", "aaa1");
// SuccessResult successResult = instance.postRelease(remotePath, requestBody);
// System.out.println(successResult);
// System.out.println();
//
// List<Map<String, Object>> listBody = new ArrayList<>();
// listBody.add(requestBody);
// SuccessResult successResult1 = instance.postListRelease(remotePath, listBody);
// System.out.println(successResult1);
// System.out.println();
//
// requestBody.put("aaa", "aaa2");
// SuccessResult successResult2 = instance.putRelease(remotePath, requestBody);
// System.out.println(successResult2);
// System.out.println();
//
// SuccessResult successResult3 = instance.deleteRelease(remotePath, "abc_def_ghi");
// System.out.println(successResult3);
// System.out.println();
List<UserDTO> userDTOs = instance.listUser(remotePath);
System.out.println(userDTOs.size());
System.out.println();
SuccessResultList<List<UserDTO>> successResultUserList = instance.listPageUser(remotePath, 1, 5);
System.out.println(successResultUserList.getPage());
System.out.println();
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("aaa", "aaa1");
SuccessResult successResult = instance.postRelease(remotePath, requestBody);
System.out.println(successResult);
System.out.println();
List<Map<String, Object>> listBody = new ArrayList<>();
listBody.add(requestBody);
SuccessResult successResult1 = instance.postListRelease(remotePath, listBody);
System.out.println(successResult1);
System.out.println();
requestBody.put("aaa", "aaa2");
SuccessResult successResult2 = instance.putRelease(remotePath, requestBody);
System.out.println(successResult2);
System.out.println();
SuccessResult successResult3 = instance.deleteRelease(remotePath, "abc_def_ghi");
System.out.println(successResult3);
System.out.println();
File file = new File("/Users/wanggeng/Desktop/UploadFiles/files/20220413/b92bcd7e553d4074afd4b36efc3b0899.docx");
String file1 = instance.file(remotePath, file);
System.out.println(file1);
}
}