import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.*;
@Component
public class FileUploadAndDownloadUtil {
private static Logger logger = LoggerFactory.getLogger(FileUploadAndDownloadUtil.class);
/**
* edoc2的url
*/
private static String baseUrl;
/**
* 集成登录密钥
*/
private static String integrationKey;
/**
* 登录用户名
*/
private static String loginName;
/**
* folderId 上传文件及下载文件关联的文件夹的id
*/
private static String folderId;
/*用户凭证*/
private static String token;
/*登录*/
private static synchronized String CheckAndLogin() {
logger.info("CheckAndLogin......");
if (StringUtils.isEmpty(token))
return login();
boolean isEffective = checkToken();
if (isEffective)
return token;
else
return login();
}
/*登录*/
private static String login() {
String regionUrl = baseUrl + "/api/services/org/UserLoginIntegrationByUserLoginName";
HttpClientRequest req = HttpClientRequest.newInstance();
JSONObject obj = new JSONObject();
obj.put("loginName", loginName);
obj.put("ipAddress", getLocalHost());
obj.put("integrationKey", integrationKey);
String result = req.postJson(regionUrl, obj.toJSONString());
logger.info("login:" + result);
JSONObject obj_result = JSON.parseObject(result);
token = obj_result.get("data").toString();
return token;
}
/**
* 检查token是否有效
*
* @return boolean
*/
private static boolean checkToken() {
String url = baseUrl + "/api/services/Org/CheckUserTokenValidity?token=" + token;
HttpClientRequest req = HttpClientRequest.newInstance();
String result = req.get(url);
logger.info("checkToken:" + result);
JSONObject obj_result = JSON.parseObject(result);
boolean isContain = obj_result.containsKey("data");
if (!isContain)
return false;
return obj_result.getBoolean("data");
}
/**
* 下载
*
* @param fileId 文件id
* @return 响应
* @throws IOException 异常
*/
public static HttpResponse download(String fileId) throws IOException, InterruptedException {
String token = CheckAndLogin();
String url = baseUrl + "/DownLoad/DownLoadCheck?token=" + token + "&fileIds=" + fileId;
HttpClientRequest req = HttpClientRequest.newInstance();
String result = req.get(url);
logger.info("downLoadCheck: {}", result);
JSONObject obj_result = JSON.parseObject(result);
String blockurl;
/*除了0都是有问题*/
if (obj_result.getInteger("nResult") == 0) {
blockurl = baseUrl + "/downLoad/index?regionHash=" + obj_result.get("RegionHash") + "&async=false&token=" + token;
} else {
throw new DefException(obj_result.getString("msg"));
}
// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
// 创建Get请求
HttpGet httpGet = new HttpGet(blockurl);
// 响应模型
// 由客户端执行(发送)Get请求
CloseableHttpResponse response1 = httpClient.execute(httpGet);
logger.info("downLoad: {}", blockurl);
return response1;
}
/**
* 上传文件,这个和upload2是用的两种不同的方式来上传文件
*
* @param file 文件
* @return 返回上传的文件的相关的信息
* @throws IOException 异常
*/
public static String upload(MultipartFile file, String newfilenameString) throws IOException, InterruptedException {
String token = CheckAndLogin();
byte[] b = file.getBytes();
int filesize = b.length;
String UploadId = UUID.randomUUID().toString();
JSONObject obj = new JSONObject();
obj.put("UploadId", UploadId);
/*15是个人文件夹的ParentId ,1044是crm文件管理*/
obj.put("ParentId", folderId);
obj.put("fileSize", filesize);
obj.put("name", newfilenameString);
obj.put("Token", token);
/*第一次请求*/
HttpClientRequest req = HttpClientRequest.newInstance();
String url = baseUrl + "/api/services/Transfer/StartUploadFile";
String json = req.postJson(url, obj.toString());
logger.info("StartUploadFile:" + json);
JSONObject obj_result = JSON.parseObject(json);
String blockurl;
/*除了0都是有问题*/
if (obj_result.getInteger("Result") == 0) {
if (obj_result.getInteger("RegionId") == 1) {
blockurl = baseUrl + "/api/services/Transfer/UploadFileBlock";
} else {
blockurl = obj_result.getString("RegionUrl");
}
} else {
throw new DefException(obj_result.getString("Message"));
}
int buffer = 819216;
int smallData = filesize % buffer;
int blockNum = filesize / buffer == 0 ? 1 : filesize / buffer;
try (InputStream bais = file.getInputStream()) {
for (int i = 0; i <= blockNum; i++) {
byte[] buffers = new byte[buffer];
//noinspection ResultOfMethodCallIgnored
bais.read(buffers);
String base64 = Base64.getEncoder().encodeToString(buffers);
JSONObject obj_block = new JSONObject();
obj_block.put("Token", token);
obj_block.put("dataSize", (i == blockNum ? smallData : buffer));
obj_block.put("FilePos", i * buffer);
obj_block.put("RegionHash", obj_result.getString("RegionHash"));
obj_block.put("BlockData", base64);
obj_block.put("uploadId", UploadId);
/*传输数据*/
String result_block = req.postJson(blockurl, obj_block.toJSONString());
logger.info("UploadFileBlock:" + result_block);
}
} catch (Exception e) {
throw new DefException("传输文件错误。");
}
String endurl = baseUrl + "/api/services/Transfer/EndUploadFile";
JSONObject obj_end = new JSONObject();
obj_end.put("Token", token);
obj_end.put("uploadId", UploadId);
obj_end.put("RegionHash", obj_result.getString("RegionHash"));
/*结束传输请求*/
String end_block = req.postJson(endurl, obj_end.toJSONString());
logger.info(end_block);
return obj_result.getString("FileId");
}
/**
* 上传文件
*
* @param file 文件
* @param newfilenameString 新名字
* @return 返回上传的文件id
* @throws IOException 异常
*/
public static String upload2(MultipartFile file, String newfilenameString) throws IOException, InterruptedException {
String token = CheckAndLogin();
byte[] b = file.getBytes();
int filesize = b.length;
String uploadId = UUID.randomUUID().toString();
String url = baseUrl + "/WebCore";
CloseableHttpClient httpclient = HttpClients.createDefault();
CloseableHttpResponse response;
HttpPost post = new HttpPost(url);
HttpEntity formEntity;
List<NameValuePair> formParams = new ArrayList<>();
formParams.add(new BasicNameValuePair("fileSize", "" + filesize));
formParams.add(new BasicNameValuePair("folderId", folderId));
formParams.add(new BasicNameValuePair("fileName", newfilenameString));
formParams.add(new BasicNameValuePair("module", "RegionDocOperationApi"));
formParams.add(new BasicNameValuePair("fun", "CheckAndCreateDocInfo"));
formParams.add(new BasicNameValuePair("type", file.getContentType()));
formParams.add(new BasicNameValuePair("size", "" + file.getSize()));
formParams.add(new BasicNameValuePair("attachType", "0"));
formParams.add(new BasicNameValuePair("fileModel", "UPLOAD"));
formParams.add(new BasicNameValuePair("token", token));
formEntity = new UrlEncodedFormEntity(formParams, "UTF-8");
post.setEntity(formEntity);
response = httpclient.execute(post);
HttpEntity entity = response.getEntity();
JSONObject str = JSON.parseObject(EntityUtils.toString(entity, "UTF-8"));
logger.info(str.toJSONString());
if (str.getIntValue("result") != 0)
throw new DefException(str.getString("reason"));
String blockurl = baseUrl + "/document/upload?token=" + token;
/*注意:chunkSize不可以过大,否则会导致文件损坏*/
int chunkSize = 1024 * 1024 * 3;
int chunks = filesize / chunkSize == 0 ? 1 : filesize / chunkSize + 1;
int smallData = filesize % chunkSize;
try (InputStream ins = file.getInputStream()) {
for (int i = 0; i < chunks; i++) {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("id", uploadId);
builder.addTextBody("name", newfilenameString);
builder.addTextBody("type", file.getContentType());
builder.addTextBody("lastModifiedDate", new Date().toString());
builder.addTextBody("size", "" + file.getSize());
builder.addTextBody("chunks", "" + chunks);
builder.addTextBody("chunk", "" + i);
builder.addTextBody("fileName", newfilenameString);
builder.addTextBody("blockSize", "" + (i + 1 == chunks ? smallData : chunkSize));
builder.addTextBody("chunkSize", "" + chunkSize);
builder.addTextBody("uploadId", uploadId);
builder.addTextBody("regionId", str.getJSONObject("data").getString("RegionId"));
builder.addTextBody("regionHash", str.getJSONObject("data").getString("RegionHash"));
byte[] bytes = new byte[chunkSize];//每次读取文件的大小为5MB
//noinspection ResultOfMethodCallIgnored
ins.read(bytes);
File tempfile = new File(String.valueOf(0));
FileOutputStream temfileStream = new FileOutputStream(tempfile);
temfileStream.write(bytes);
builder.addBinaryBody("file", tempfile);
// 把文件加到HTTP的post请求中
// builder.addBinaryBody("file", bytes, ContentType.APPLICATION_OCTET_STREAM, file.getOriginalFilename());
post.setURI(URI.create(blockurl));
HttpEntity multipart = builder.build();
post.setEntity(multipart);
temfileStream.close();
response = httpclient.execute(post);
HttpEntity responseEntity = response.getEntity();
String sResponse = EntityUtils.toString(responseEntity, "UTF-8");
logger.info(sResponse);
}
}
return str.getJSONObject("data").getString("FileId");
}
/**
* @return 预览的url
*/
public static String getPreViewUrl() throws InterruptedException {
String token = FileUploadAndDownloadUtil.CheckAndLogin();
return baseUrl + "/jump.html?token=" + token + "&returnUrl=http://192.168.20.194/preview.html?fileid=1082";
}
@Value("${EDOC2_BASE_URL}")
public void setBaseUrl(String baseUrl) {
FileUploadAndDownloadUtil.baseUrl = baseUrl;
}
@Value("${INTEGRATIONKEY}")
public void setIntegrationKey(String integrationKey) {
FileUploadAndDownloadUtil.integrationKey = integrationKey;
}
@Value("${EDOC2_LOGIN_NAME}")
public void setLoginName(String loginName) {
FileUploadAndDownloadUtil.loginName = loginName;
}
@Value("${EDOC2_FOLDER_ID}")
public void setFolderId(String folderId) {
FileUploadAndDownloadUtil.folderId = folderId;
}
/**
* 获取本地的ip
*
* @return ip
*/
private static String getLocalHost() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
throw new DefException("找不到HostAddress。");
}
}
}