最近接到了做在线文档编辑的需求,普通的rpc接口比如dubbo或者spring cloud的feign对文件流操作支持并不太好,所以用原生的httpClient先写一个出来。
上传文件
// upload_url为上传文件的接口调用地址
HttpPost httpPost = new HttpPost(upload_url);
// 使用try resource进行httpClient的关闭
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
URL url = new URL(downloadUri);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
InputStream stream = connection.getInputStream();
if (stream == null) {
throw new Exception("Stream is null");
}
// 使用表单形式提交参数
MultipartEntityBuilder fileBuilder = MultipartEntityBuilder.create();
fileBuilder.setMode(HttpMultipartMode.RFC6532);
// file为提交参数名,stream为要上传的文件的文件流 inputStream,最后一个参数为上传文件名称
fileBuilder.addBinaryBody("file", stream, ContentType.create("multipart/form-data"), FileUtility.GetFileName(url.getPath()));
HttpEntity fileEntity = fileBuilder.build();
httpPost.setEntity(fileEntity);
HttpResponse uploadResponse = httpClient.execute(httpPost);
StatusLine statusLine = uploadResponse.getStatusLine();
// 响应码
int statusCode = statusLine.getStatusCode();
// 请求成功
if (statusCode == 200) {
HttpEntity entity = uploadResponse.getEntity();
log.info("返回结果为 " + EntityUtils.toString(entity));
}
// 断开链接
connection.disconnect();
} catch (Exception ex) {
saved = 1;
} finally {
if (httpPost != null) {
httpPost.releaseConnection();
}
}
下载文件
HttpGet httpGet = null;
String localFileName = null;
String fileOriName = null;
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
// 这里我设置了超时时间的配置,也可以不设
RequestConfig timeoutConfig = RequestConfig.custom()
.setConnectTimeout(5000).setConnectionRequestTimeout(1000)
.setSocketTimeout(5000).build();
// download_url为下载文件接口地址,fileId是我自己文件接口定义的文件标识
// 本例的文件下载接口是直接返回的文件流
httpGet = new HttpGet(download_url + fileId);
httpGet.setConfig(timeoutConfig);
HttpResponse downLoadResponse = httpClient.execute(httpGet);
StatusLine statusLine = downLoadResponse.getStatusLine();
// 响应码
int statusCode = statusLine.getStatusCode();
// 请求成功
if (statusCode == 200) {
// 获取接口返回的文件流
HttpEntity entity = downLoadResponse.getEntity();
InputStream input = entity.getContent();
// 本例是储存到本地文件系统,fileRealName为你想存的文件名称
File dest = new File(DocumentManager.StoragePath(fileRealName, null));
OutputStream output = new FileOutputStream(dest);
int len = 0;
byte[] ch = new byte[1024];
while ((len = input.read(ch)) != -1) {
output.write(ch, 0, len);
}
}
} catch (Exception e) {
log.error("", e);
} finally {
if (httpGet != null) {
httpGet.releaseConnection();
}
}
对接onlyOffice文档编辑
我们目前有自己的文件服务器,onlyOffice在不变动前端Js代码的情况下,只能使用项目下target里的本地文件,所以就有了开头的两个需求。
我目前设计的流程是这样的,
1.前端调用文件服务器上传文件 --> 2.文件服务器返回文件id --> 3.前端拿文件id传到文档编辑接口(文档编辑接口会根据文件id从文件服务器下载文件到target下并返回onlyOffice的格式) --> 4.当文档被编辑后,前端调用文件回写接口,把更改后的文件传到文档编辑接口 --> 5.文档编辑接口根据文件Id,调用文件服务器更改文件内容接口把文件覆盖传上去。
具体onlyOffice详情和概述请参考以下链接,我认为写的比较清楚了。
https://blog.51cto.com/dengshuangfu/2154826