AJAX 파일업로드 & 미리보기
2022. 1. 5. 11:45ㆍspring
<미리보기>
html
<div class="form-group w-100">
<label for="examTicket" class="m-2 text-primary">수험표</label>
<small class="form-text text-danger">* 수험표는 관리자의 승인 후 수정할 수 없습니다.</small>
<th:block th:if="${#strings.equals(userInfo.membershipCd, '10')}">
<form enctype="multipart/form-data" id="uploadImageForm">
<input type="file" enctype="multipart/form-data" method="POST" class="form-control"
accept=".jpg, .jpeg, .png, .bmp"
id="imageInput" name="examTicketFile" th:value="${userInfo.examTicket}">
</form>
</th:block>
<img class="w-100 my-3" alt="" th:src="${userInfo.examTicketPath}" id="examTicketImg">
</div
js
//이미지 미리보기
var sel_file;
$(document).ready(function() {
$("#imageInput").on("change", handleImgFileSelect);
});
function handleImgFileSelect(e) {
var files = e.target.files;
var filesArr = Array.prototype.slice.call(files);
var reg = /(.*?)\/(jpg|jpeg|png|bmp)$/;
filesArr.forEach(function(f) {
if (!f.type.match(reg)) {
alert("확장자는 이미지 확장자만 가능합니다.");
return;
}
sel_file = f;
var reader = new FileReader();
reader.onload = function(e) {
$("#examTicketImg").attr("src", e.target.result);
}
reader.readAsDataURL(f);
});
}
< 업로드 >
application.yml
spring:
config:
activate:
on-profile: local
servlet:
multipart:
# enabled: true # 멀티파트 업로드 지원여부 (default: true)
# file-size-threshold: 1MB # 파일이 메모리에 기록되는 임계값 (default: 0B)
location: C:/Temp # 업로드된 파일의 임시 저장 공간
max-file-size: 100MB # 파일의 최대 사이즈 (default: 1MB)
max-request-size: 100MB # 요청의 최대 사이즈 (default: 10MB)
config.java
package com.web.lawingmachine.app.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// addResourceHandler : 스프링부트에서 확인할 폴더 위치 설정 (img 폴더 밑에 아무거나 다 들어갈 수 있다)
// addResourceLocations : 실제 시스템의 폴더 위치, 윈도우 시스템의 경우 'file:///경로' 형태로 사용
registry.addResourceHandler("/upload/**").addResourceLocations("file:///C:/Temp/upload/");
}
}
위 예제에서 알 수 있듯이 URI 가 /upload/ 이하로 요청이 될 경우 로컬 Disk 의 /opt/upload/ 경로에 있는 파일을 사용자에게 제공하겠다는 의미입니다. /upload/ 경로 이하의 모든 경로와 파일명은 /opt/upload/ 에서 동일하게 찾아서 제공해줍니다.
주의할 것은 resourceLocation 지정 시 로컬 경로일 때 "file:///" 접두어를 빼먹으면 안된다는 것입니다.
js
function uploadImage() {
var header = $("meta[name='_csrf_header']").attr('content');
var token = $("meta[name='_csrf']").attr('content');
let url = '/mypage/myprofile/uploadImage';
let formData = new FormData();
formData.append("examTicketFile", $("#imageInput")[0].files[0]); // input 추가
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: url,
data: formData,
processData: false,
contentType: false,
beforeSend: function (xhr) {
xhr.setRequestHeader(header, token);
},
success: function (result) {
let image = result['value'];
console.log(image);
$("#examTicket").attr("src", image);
},
error: function (result) {
alert(result['message']);
}
});
-> beforeSend는 security 환경에서 post Ajax를 보낼 때 403 오류가 생기는 것 때문에 설정했다.
controller
@Value("${spring.servlet.multipart.location}")
private String BASE_PATH;
@PostMapping("/myprofile/uploadImage")
@ResponseBody
public ResultMessageVO uploadImage(HttpServletRequest req, @RequestParam("examTicketFile") MultipartFile imageFile) throws IOException {
ResultMessageVO result = new ResultMessageVO();
if (!imageFile.isEmpty()) {
String filename = imageFile.getOriginalFilename();
String ext = null;
if (filename != null) {
if (filename.contains(".")) {
ext = filename.substring(filename.lastIndexOf("."));
} else {
ext = "";
}
}
if (!".jpg".equals(ext) && !".jpeg".equals(ext) && !".png".equals(ext) && !".bmp".equals(ext)) {
result.setMessage("이미지 파일을 업로드 해주세요.(.jpg, .jpeg, .png, .bmp)");
result.setResultCode("FAIL");
return result;
}
String dirPath = "/upload/" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); // 오늘날짜
String filepath = BASE_PATH.endsWith("/") ? BASE_PATH + dirPath : BASE_PATH + "/" + dirPath;
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
String nfileName = uuid + ext;
File targetFile = new File(filepath, nfileName);
if (!targetFile.exists()) {
targetFile.mkdirs();
} else {
targetFile.delete();
}
try {
imageFile.transferTo(targetFile);
} catch (IllegalStateException e) {
e.printStackTrace();
}
String examTicketPath = dirPath + "/" + nfileName;
SessionUser sessionUser = (SessionUser) req.getSession().getAttribute("sessionUser");
int resultCnt = userService.uploadImage(examTicketPath, filename, sessionUser.getUserId());
if (resultCnt > 0) {
result.setValue(examTicketPath);
}
}
return result;
}'spring' 카테고리의 다른 글
| springboot mvn build test error (0) | 2022.01.08 |
|---|---|
| @ConfigurationProperties (0) | 2022.01.07 |
| java.net.BindException: Address already in use: bind (0) | 2022.01.04 |
| Invalid CSRF token found for ... (0) | 2022.01.03 |
| Request header is too large (0) | 2022.01.03 |