FolderAttachmentServiceImpl.java
11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
package com.hotent.file.attachmentService;
import cn.hutool.core.lang.Assert;
import com.hotent.base.attachment.Attachment;
import com.hotent.base.attachment.AttachmentService;
import com.hotent.base.attachment.MultipartFileParam;
import com.hotent.base.attachment.UploadShardResult;
import com.hotent.base.cache.annotation.*;
import com.hotent.base.constants.CacheKeyConst;
import com.hotent.base.exception.BaseException;
import com.hotent.base.util.BeanUtils;
import com.hotent.base.util.FileUtil;
import com.hotent.base.util.StringUtil;
import com.hotent.base.util.UniqueIdUtil;
import com.hotent.file.model.UploadProperties;
import com.hotent.file.service.FlowUploadPropertiesService;
import com.hotent.file.util.AppFileUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class FolderAttachmentServiceImpl implements AttachmentService{
@Resource
FlowUploadPropertiesService flowUploadPropertiesService;
@Resource
FolderAttachmentServiceImpl folderAttachmentService;
public FolderAttachmentServiceImpl(){
}
public void remove(Attachment attachment,String propertiesId) throws Exception {
if(attachment == null){
return;
}
String attachPath = getAttachPath(propertiesId,attachment);
String filePath = attachment.getFilePath();
if(!attachment.getEntryptName()){
filePath = filePath.replace(attachment.getId(), attachment.getFileName());
}
String fullPath = attachPath + File.separator + filePath;
// 删除文件
FileUtil.deleteFile(fullPath);
}
@Override
public void upload(Attachment attachment, InputStream inputStream,String propertiesId) throws Exception {
String filePath = attachment.getFilePath();
String attachPath = getAttachPath(propertiesId,attachment);
if(!attachment.getEntryptName()){
filePath = filePath.replace(attachment.getId(), attachment.getFileName());
}
filePath=attachPath+File.separator+filePath;
FileUtil.createFolderFile(filePath);
if(BeanUtils.isNotEmpty(inputStream)) {
FileUtil.writeFile(filePath, inputStream);
}
else {
FileUtil.writeByte(filePath, attachment.getBytes());
}
}
public void download(Attachment attachment, OutputStream outStream,String propertiesId)
throws Exception {
String filePath = attachment.getFilePath();
String attachPath = getAttachPath(propertiesId,attachment);
if(!attachment.getEntryptName()){
filePath = filePath.replace(attachment.getId(), attachment.getFileName());
}
filePath=attachPath+File.separator+filePath;
String fullPath = filePath.replace("/", File.separator);
File file = new File(fullPath);
if (file.exists()) {
FileInputStream inputStream = null;
try{
inputStream = new FileInputStream(fullPath);
byte[] b = new byte[1024];
int i = 0;
while ((i = inputStream.read(b)) > 0) {
outStream.write(b, 0, i);
}
outStream.flush();
}
catch(Exception e){
throw e;
}
finally{
if (inputStream != null) {
inputStream.close();
inputStream = null;
}
if (outStream != null) {
outStream.close();
outStream = null;
}
}
}
else {
throw new BaseException("该附件不存在");
}
}
@Override
public String getStoreType() {
return "folder";
}
@Override
public boolean chekckFile(Attachment attachment,String propertiesId) {
String filePath = attachment.getFilePath();
String attachPath = getAttachPath(propertiesId,attachment);
if(!attachment.getEntryptName()){
filePath = filePath.replace(attachment.getId(), attachment.getFileName());
}
filePath=attachPath+File.separator+filePath;
String fullPath = filePath.replace("/", File.separator);
File file = new File(fullPath);
return file.exists();
}
/**
* 获取文件上传根目录
* @param propertiesId
* @return
*/
private String getAttachPath(String propertiesId,Attachment attachment){
UploadProperties uploadProperties = flowUploadPropertiesService.getUploadProperties(propertiesId);
String attachPath = "";
if(BeanUtils.isNotEmpty(uploadProperties)){
attachPath = uploadProperties.getLocation();
attachment.setEntryptName(uploadProperties.getEncryptName()== 0 ? false : true);
}else{
attachPath = AppFileUtil.getAttachPath();
}
return attachPath;
}
@Override
public byte[] getFileBytes(Attachment sysFile) throws Exception {
String propertiesId = BeanUtils.isNotEmpty(sysFile)?sysFile.getProp6():"";
String location = this.getByUploadProperties(propertiesId);
if(StringUtil.isEmpty(location)){
location = AppFileUtil.getAttachPath();
}
String fullPath = StringUtil.trimSufffix(location,
File.separator)
+ File.separator
+ sysFile.getFilePath().replace("/", File.separator);
File file = new File(fullPath);
if (file.exists()) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(fullPath);
byte[] b = new byte[1024];
int i = 0;
while ((i = inputStream.read(b)) > 0) {
outStream.write(b, 0, i);
}
outStream.flush();
return outStream.toByteArray();
} catch (Exception e) {
throw e;
} finally {
if (inputStream != null) {
inputStream.close();
inputStream = null;
}
if (outStream != null) {
outStream.close();
outStream = null;
}
}
} else {
throw new RuntimeException("该附件不存在");
}
}
/**
* 根据配置id获取文件上传配置
* @param propertiesId 流程附件配置ID
* @return 文件路径
*/
private String getByUploadProperties(String propertiesId){
if(StringUtil.isNotEmpty(propertiesId)){
UploadProperties uploadProperties = flowUploadPropertiesService.getUploadProperties(propertiesId);
if(BeanUtils.isNotEmpty(uploadProperties)){
String location = uploadProperties.getLocation();
if(StringUtil.isNotEmpty(location)){
return location.replace("/", File.separator);
}
}
}
return Strings.EMPTY;
}
@Override
public UploadShardResult uploadByShard(MultipartFileParam multipartFileParam,Attachment attachment, String propertiesId) throws Exception {
multipartFileParam.setUniqueKey(multipartFileParam.getIdentifier()+"_"+multipartFileParam.getUniqueIdCard());
UploadShardResult uploadShardResult=new UploadShardResult();
uploadShardResult.setComplete(false);
String filePath = attachment.getFilePath();
String attachPath = getAttachPath(propertiesId,attachment);
String fileName = multipartFileParam.getFile().getOriginalFilename();
String extensionName="";
if(fileName.indexOf(".")!=-1){
extensionName=fileName.substring(fileName.lastIndexOf(".")+1);
}
String fileId=folderAttachmentService.getIdentifierIdFromCache(multipartFileParam.getUniqueKey());
if(StringUtil.isEmpty(fileId)){
fileId=UniqueIdUtil.getSuid();
folderAttachmentService.putIdentifierIdCache(multipartFileParam.getUniqueKey(),fileId);
}
attachment.setId(fileId);
String fullFilePath=attachPath+File.separator+filePath;
String tempFilePath=fullFilePath.substring(0,fullFilePath.lastIndexOf(File.separator));
String tempFileName=fileId+"."+extensionName+"."+"tmp";
FileUtil.createFolderFile(fullFilePath);
File tempFile = new File(tempFilePath, tempFileName);
try(
//第一步 打开将要写入的文件
RandomAccessFile raf = new RandomAccessFile(tempFile, "rw");
//第二步 打开通道
FileChannel fileChannel = raf.getChannel()
) {
//第三步 计算偏移量
long position = (multipartFileParam.getChunkNumber() - 1) * multipartFileParam.getChunkSize();
//第四步 获取分片数据
byte[] fileData = multipartFileParam.getFile().getBytes();
//第五步 写入数据
fileChannel.position(position);
fileChannel.write(ByteBuffer.wrap(fileData));
fileChannel.force(true);
}
//判断是否完成文件的传输并进行校验与重命名
boolean isComplete = checkUploadStatus(multipartFileParam,attachment, tempFilePath);
if (!isComplete) {
return uploadShardResult;
}
folderAttachmentService.delIdentifierIdCache(multipartFileParam.getUniqueKey());
try(FileInputStream fileInputStream = new FileInputStream(tempFile.getPath())){
String md5 = DigestUtils.md5Hex(fileInputStream);
if (StringUtils.isNotBlank(md5) && !md5.equals(multipartFileParam.getIdentifier())) {
throw new IllegalArgumentException("MD5校验失败");
}
}
attachment.setFilePath(filePath.substring(0,filePath.lastIndexOf(File.separator))+
File.separator+attachment.getId()+"."+extensionName);
renameFile(tempFile, attachment.getId()+"."+extensionName);
uploadShardResult.setComplete(true);
return uploadShardResult;
}
@Override
public Map<String,Object> generatePolicy(Attachment attachment, String propertiesId) {
return null;
}
@Override
public String getUrl(Attachment attachment, String propertiesId) throws UnsupportedEncodingException {
return null;
}
@Override
public InputStream getFileInputStream(Attachment attachment) throws FileNotFoundException {
String filePath = attachment.getFilePath();
String fullPath = StringUtil.trimSufffix(AppFileUtil.getAttachPath(),
File.separator)
+ File.separator
+ filePath.replace("/", File.separator);
File file = new File(fullPath);
if (file.exists()) {
return new FileInputStream(fullPath);
} else {
throw new RuntimeException("该附件不存在");
}
}
@Override
public String getFilePath(String account, String fileName) {
return AppFileUtil.getFilePath(account,fileName);
}
public void renameFile(File toBeRenamed, String toFileNewName) {
Assert.isTrue(toBeRenamed.exists() && !toBeRenamed.isDirectory(),"文件不存在");
String p = toBeRenamed.getParent();
File newFile = new File(p + File.separatorChar + toFileNewName);
toBeRenamed.renameTo(newFile);
}
@SuppressWarnings("all")
public boolean checkUploadStatus(MultipartFileParam param,Attachment attachment, String filePath) throws IOException {
File confFile = new File(filePath, attachment.getId() + ".conf");
try(RandomAccessFile confAccessFile = new RandomAccessFile(confFile, "rw")) {
//设置文件长度
confAccessFile.setLength(param.getTotalChunks());
//设置起始偏移量
confAccessFile.seek(param.getChunkNumber() - 1);
//将指定的一个字节写入文件中 127,
confAccessFile.write(Byte.MAX_VALUE);
byte[] completeStatusList = FileUtils.readFileToByteArray(confFile);
//创建conf文件文件长度为总分片数,每上传一个分块即向conf文件中写入一个127,那么没上传的位置就是默认的0,已上传的就是127
for (int i = 0; i < completeStatusList.length; i++) {
if (completeStatusList[i] != Byte.MAX_VALUE) {
return false;
}
}
}
confFile.delete();
return true;
}
/**
* 缓存分片上传文件id
* @param key
* @return
*/
@Cacheable(value = CacheKeyConst.EIP_UPLOAD_ALIYUN_FILE_ID, key="#key",
firstCache = @FirstCache(expireTime = 1, timeUnit = TimeUnit.DAYS),secondaryCache = @SecondaryCache(expireTime = 1, timeUnit = TimeUnit.DAYS))
public String getIdentifierIdFromCache(String key) {
return null;
}
@CachePut(value = CacheKeyConst.EIP_UPLOAD_ALIYUN_FILE_ID, key="#key",
firstCache = @FirstCache(expireTime = 1, timeUnit = TimeUnit.DAYS),secondaryCache = @SecondaryCache(expireTime = 1, timeUnit = TimeUnit.DAYS))
public String putIdentifierIdCache(String key,String id) {
return id;
}
@CacheEvict(value = CacheKeyConst.EIP_UPLOAD_ALIYUN_FILE_ID, key="#key")
public void delIdentifierIdCache(String key) {}
}