A> 정규식을 이용한 파일 확장자 체크
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
var regex = new RegExp("(.*?)\.(exe|sh|zip|alz)$");
var maxSize = 5242880; //5MB
function checkExtension(fileName, fileSize){
if(fileSize >= maxSize){
alert("파일 사이즈 초과");
return false;
}
if(regex.test(fileName)){
alert("해당 종류의 파일은 업로드할 수 없습니다.");
return false;
}
return true;
}
|
cs |
B> 중복된 이름 파일 처리
spring --9. 에 있음
a> UUID를 이용한 고유한 문자열 생성
1. 매년,매월,매일로 구분한 디렉토리 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
private String getFolder() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
String str = sdf.format(date);
return str.replace("-", File.separator);
}
그 후에
File uploadPath = new File(uploadFolder, getFolder());
log.info("upload path: " + uploadPath);
|
cs |
2.UUID 로 파일 중복 없애기
1
2
3
4
5
6
7
8
9
10
11
12
13
|
UUID uuid = UUID.randomUUID();
uploadFileName = uuid.toString() + "_" + uploadFileName;
File saveFile = new File(uploadPath, uploadFileName);
try {
multipartFile.transferTo(saveFile); //저장 폴더에 저장
} catch (Exception e) {
log.error(e.getMessage());
} // end catch
|
cs |
C> 섬네일 이미지 생성
1. pom.xml 에 추가
1
2
3
4
5
6
|
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
|
cs |
2.섬네일 처리 단계
a> 이미지 여부 판단
.
1
2
3
4
5
6
7
8
9
10
|
try {
String contentType = Files.probeContentType(file.toPath());
return contentType.startsWith("image");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
|
cs |
b> 섬네일 생성
1
2
3
4
5
6
7
8
9
10
|
if (checkImageType(saveFile)) {
FileOutputStream thumbnail =
new FileOutputStream(new File(uploadPath, "s_" + uploadFileName));
Thumbnailator.createThumbnail(multipartFile.getInputStream(), thumbnail, 100, 100);
thumbnail.close();
}
|
cs |
D> 브라우저에서의 ajax 처리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$.ajax({
url: '/uploadAjaxAction',
processData: false,
contentType: false,
data: formData,
type: 'POST',
dataType:'json',
success: function(result){
console.log(result);
}
}); //$.ajax
|
cs |
E> 섬네일 띄우기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
$.ajax({
url : '/uploadAjaxAction',
processData : false,
contentType : false,
data : formData,
type : 'POST',
dataType : 'json',
success : function(result) {
console.log(result);
showUploadedFile(result);
$(".uploadDiv").html(cloneObj.html());
}
}); //$.ajax
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function showUploadedFile(uploadResultArr) {
var str = "";
$(uploadResultArr).each(function(i, obj) {
str += "<li>" + obj.fileName + "</li>";
});
uploadResult.append(str);
}
|
cs |
F> 이미지 다운로드
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
|
@GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseBody
public ResponseEntity<Resource> downloadFile(@RequestHeader("User-Agent") String userAgent, String fileName) {
Resource resource = new FileSystemResource("c:\\upload\\" + fileName);
if (resource.exists() == false) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
String resourceName = resource.getFilename();
// remove UUID
String resourceOriginalName = resourceName.substring(resourceName.indexOf("_") + 1);
HttpHeaders headers = new HttpHeaders();
try {
String downloadName = null;
if ( userAgent.contains("Trident")) {
log.info("IE browser");
downloadName = URLEncoder.encode(resourceOriginalName, "UTF-8").replaceAll("\\+", " ");
}else if(userAgent.contains("Edge")) {
log.info("Edge browser");
downloadName = URLEncoder.encode(resourceOriginalName,"UTF-8");
}else {
log.info("Chrome browser");
downloadName = new String(resourceOriginalName.getBytes("UTF-8"), "ISO-8859-1");
}
log.info("downloadName: " + downloadName);
headers.add("Content-Disposition", "attachment; filename=" + downloadName);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new ResponseEntity<Resource>(resource, headers, HttpStatus.OK);
}
|
cs |
29 라인의 ISO-8859-1 은 크롬에서 쓰는 형식
34 라인처럼 header에 추가해서 전달
G> 첨부파일의 삭제
1. 첨부파일 생성, 제거시 발생하는 문제점 최소화 하기 위해
Quartz 라이브러리 사용
- Quartz 라이브러리 : 주기적으로 작업을 처리 하기 위한 라이브러리
-db에 있는 첨부파일 목록과 실제 업로드 폴더의 목록을 주기적으로 비교
2. 추가해야 할 라이브러리들
a. quartz
b. quartz-jobs
3.root-context 에 설정해야 하는 것
1
2
|
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
<task:annotation-driven /> |
cs |
4.cron 설정
--시간 단위의 값을 조정
0 * * * * * (*)
초 분 시 날 달 매주 년
0~59 0~59 0~23 1~31 1~12 1~7 optional
5.컨트롤러에서의 사용 예시
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
|
private String getFolderYesterDay() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
String str = sdf.format(cal.getTime());
return str.replace("-", File.separator);
}
@Scheduled(cron = "0 0 2 * * *") //매달 매일 매2시 마다
public void checkFiles() throws Exception {
log.warn("File Check Task run.................");
log.warn(new Date());
// file list in database
List<BoardAttachVO> fileList = attachMapper.getOldFiles();
// ready for check file in directory with database file list
List<Path> fileListPaths = fileList.stream()
.map(vo -> Paths.get("C:\\upload", vo.getUploadPath(), vo.getUuid() + "_" + vo.getFileName()))
.collect(Collectors.toList());
// image file has thumnail file
fileList.stream().filter(vo -> vo.isFileType() == true)
.map(vo -> Paths.get("C:\\upload", vo.getUploadPath(), "s_" + vo.getUuid() + "_" + vo.getFileName()))
.forEach(p -> fileListPaths.add(p));
log.warn("===========================================");
fileListPaths.forEach(p -> log.warn(p));
// files in yesterday directory
File targetDir = Paths.get("C:\\upload", getFolderYesterDay()).toFile();
File[] removeFiles = targetDir.listFiles(file -> fileListPaths.contains(file.toPath()) == false);
log.warn("-----------------------------------------");
for (File file : removeFiles) {
log.warn(file.getAbsolutePath());
file.delete();
}
}
|
cs |