티스토리 뷰
1. 개요
로컬 환경은 Spring Framework와 Tomcat 서버를 기반으로 개발되어 있었으며, 파일 업로드 기능은 MultipartFile을 활용하여 구현되어 있었다.
프로젝트의 서버 환경의 경우 WAS(Web Application Server)를 Tomcat이 아닌 Resin을 사용하는 것을 뒤늦게 확인하였고
이 과정에서 파일 업로드 기능에 문제가 발생하였다.
2. 문제 상황
Resin 서버로 이관 후, 클라이언트에서 전송한 파일이 서버에서 MultipartFile 객체로 정상적으로 매핑되지 않거나,
transferTo() 호출 시 내부적으로 발생하는 권한/호환성 오류로 인해 업로드가 실패하였다.
대표적인 예외 메시지는 다음과 같았다.
java.lang.NullPointerException : null
at cohttp://m.caucho.server.http.MultipartRequest$PartImpl.write(AbstractCauchoRequest.java:xxxx)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:xxx)
3. 원인 분석
Resin 서버가 multipart 처리 과정에서 자체적으로 파일을 기록하려 할 때 문제가 발생.
이는 Resin 내부의 가상 파일 시스템(VFS) 처리 방식과 Spring의 Multipart 처리 방식이 충돌한 것으로 보여짐.
* Resin 의 버전별로 MultipartFile.transferTo() 호환여부
Resin 4.0.65 및 이전 버전: 호환되지 않음
Resin 4.0.66 이후 버전: 호환
4. 해결 방안
transferTo() 대신 FileOutputStream을 사용하여 업로드된 파일의 바이트를 직접 저장하는 방식으로 변경함으로써 문제를 해결
5. 적용 코드
기존 소스코드
@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return "업로드할 파일을 선택해주세요.";
}
try {
// 저장할 경로 설정
String uploadDir = "/data/uploads/";
String filePath = uploadDir + file.getOriginalFilename();
// 디렉토리 없을 경우 생성
File dir = new File(uploadDir);
if (!dir.exists()) dir.mkdirs();
//MultipartFile의 transferTo 사용
file.transferTo(filePath);
return "업로드 성공: " + file.getOriginalFilename();
} catch (IOException e) {
e.printStackTrace();
return "업로드 실패: " + e.getMessage();
}
}
해결 소스코드
@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return "업로드할 파일을 선택해주세요.";
}
try {
// 저장할 경로 설정
String uploadDir = "/data/uploads/";
String filePath = uploadDir + file.getOriginalFilename();
// 디렉토리 없을 경우 생성
File dir = new File(uploadDir);
if (!dir.exists()) dir.mkdirs();
// FileOutputStream을 통한 수동 저장
try (FileOutputStream fos = new FileOutputStream(filePath)) {
fos.write(file.getBytes());
}
return "업로드 성공: " + file.getOriginalFilename();
} catch (IOException e) {
e.printStackTrace();
return "업로드 실패: " + e.getMessage();
}
}
'server' 카테고리의 다른 글
웹서버 이미지 호출이 안되는 경우(이기종 WAS 운영 환경) (0) | 2023.06.27 |
---|---|
다중 컨테이너 일괄 관리 docker compose 적용해보기 (0) | 2023.05.19 |
Docker 다량 컨테이너 실행 간소화 (0) | 2023.01.21 |
spring, react 사용 CORS 오류 조치 (0) | 2022.08.31 |
Docker WEB WAS AJP 연결 실패 해결 (0) | 2022.06.29 |
- Total
- Today
- Yesterday
- abstractcauchorequest
- 컨테이너
- vscode
- SpringBoot
- JPA
- Java
- 깨짐
- gradle
- html
- Linux
- JSON
- TLS
- spring
- web
- jQuery
- Oracle
- WAS
- IMAGE
- Git
- mybatis
- React
- standardmultiparthttpservletrequest
- SQL
- tomcat
- SSL
- 날짜
- Eclipse
- parse
- Windows
- docker
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |