SpringMVC가 파일을 업로드 및 다운로드할 때 war_exploded 배포로 인해 다운로드된 파일이 삭제됨

예전부터 이 글을 쓰고 싶었지만 이 문제를 만나 해결한 직후에 기록을 하지 않았기 때문에 나중에 몇 가지 문제가 프로젝트의 손실로 이어져 잠시 보류하게 되었습니다. 오늘은 옮길 수가 없었습니다. 이 문제가 생각나서 공유합니다. 제 프로젝트가 유실되어 더 이상 프로젝트를 다시 빌드하고 싶지 않아서 말로만 설명할 수 있습니다. I 최선을 다해 말하지만 오래 전 일이고 설명에 약간의 편차가 있을 수 있으니 한 번 살펴보세요.

문제 설명:

SpringMVC의 파일 업로드 및 다운로드 실습의 경우 튜토리얼을 따라 프로젝트를 완료(Qianfeng SSM 튜토리얼)했는데 다운로드 시 문제가 발생했습니다. 폴더 아래에서 다운로드한 파일(연습용 그림)을 찾을 수 없습니다. 디버깅 과정에서 단일 이미지를 다운로드 할 때 프로젝트가 닫히지 않는 것을 발견했습니다.프로젝트의 대상 디렉토리에는 다운로드한 파일이 있으며 다운로드한 이미지는 내가 정의한 폴더에서도 볼 수 있지만 종료 후 프로젝트의 정의된 파일 폴더 아래의 그림이 사라지고 대상 디렉토리의 파일은 그대로 있지만 프로젝트가 다시 시작되고 대상 디렉토리가 새로 고쳐지고 파일이 사라짐 여러 파일을 다운로드할 때 파일이 폴더 아래에 먼저 다운로드된 파일은 나중에 다운로드됩니다 파일은 덮어쓰지만 대상 디렉터리는 덮어쓰지 않습니다 프로젝트를 닫으면 폴더의 파일이 사라집니다.

문제 탐색:

이 문제를 만났을 때 머리가 아팠습니다. 오류 보고 없이는 준정상 문제의 원인을 찾기가 정말 어려웠습니다. 먼저 내 코드와 선생님의 코드가 일치하는지 꼼꼼히 비교했고 정확히 같은 것을 발견했습니다. ; 그런 다음 인터넷에서 내 문제를 설명하려고 최선을 다했습니다 인터넷에서 답변을 찾고 "SpringMVC 파일을 다운로드할 수 없습니다" "SpringMVC 파일을 다운로드한 후 최종 프로젝트가 사라집니다" "SpringMVC 파일을 여러 파일을 다운로드하면 덮어씁니다" 이전에 다운로드한 파일이 있고, 프로젝트 종료 후 파일이 사라집니다"... 내 문제 설명에서 점점 더 자세한 정보를 얻은 후에 답을 찾았습니다.

이유:

블로거의 답변은 아마도 다음과 같을 것입니다: "WAR Exploded 배포 모드에서 프로젝트가 종료되면 웹 서버는 작업 디렉토리에서 웹 애플리케이션의 리소스를 삭제합니다. 따라서 다운로드한 모든 파일도 삭제됩니다." 왜 가려질까, 그 얘기를 안 한 것 같던 기억이 난다.

해결책:

가장 쉬운 방법은 배포 방식을 "war_exploded"에서 "war"로 직접 변경하는 것입니다. 수정 방법은 tomcat 편집 구성 클릭 -> 배포 클릭 -> 다음 파일 뒤에 있는 "_exploded" 삭제 - > "적용" 클릭 -> "확인" 클릭.

요약하다:

문제 소개:

war_exploded 배포를 사용하여 SpringMVC에서 파일을 다운로드할 때 다음과 같은 문제가 발생할 수 있습니다.

  1. 폴더 아래 매번 다운로드되는 파일은 이전에 다운로드한 파일을 덮어쓰지만 프로젝트의 대상 디렉터리에서는 덮어쓰지 않습니다.

  2. 프로젝트를 닫으면 다운로드한 파일이 사라집니다.

해결책:

배포 방법을 "war_exploded"에서 "war"로 직접 변경합니다. Tomcat을 클릭하여 구성 편집 -> 배포 클릭 -> 아래 파일 뒤에 "_exploded" 삭제 -> "적용" 클릭 -> "확인"을 클릭합니다.

심층 탐색:

나중에 war와 war_exploded 배치의 차이점을 살펴보았으며 여기에서 여러분과 공유합니다.

war와 war_exploded 배치의 차이점:

WAR(Web Application Archive)는 자바 웹 애플리케이션을 위한 패키징 방식으로 애플리케이션의 모든 리소스(HTML, JSP, Java 클래스, 구성 파일 등 포함)를 하나의 파일로 패키징할 수 있습니다. 이 파일은 Java 응용 프로그램 서버(예: Tomcat, Jetty, WebLogic 등)에 배포할 수 있습니다. WAR 파일이 애플리케이션 서버에 배치되면 서버는 WAR 파일의 압축을 풀고 이를 작업 디렉토리에 배치합니다. 이 프로세스 중에 웹 페이지, Java 클래스, 리소스 파일 등과 같은 애플리케이션의 다양한 구성 요소에 액세스할 수 있습니다.

WAR Exploded(또는 독립 배포 또는 압축 해제 배포)는 웹 애플리케이션의 모든 리소스를 서버의 디렉터리에 직접 배포하는 것을 말합니다. 이 디렉토리는 종종 웹 애플리케이션의 컨텍스트 디렉토리(컨텍스트 디렉토리)라고 합니다. WAR 파일과 달리 이 배포 방법에서는 파일 압축을 풀거나 애플리케이션을 단일 파일로 패키징할 필요가 없습니다. 응용 프로그램은 추가 구성 없이 서버에서 직접 실행할 수 있습니다.

일반적으로 WAR 파일은 Java 웹 애플리케이션의 수명 주기에서 유용한 도구로 전송, 배포 및 배포를 용이하게 합니다. 이에 대응하는 WAR Exploded는 웹 애플리케이션을 로컬에서 개발하고 테스트할 때(예: IDE를 통해 실행) 개발자에게 애플리케이션 리소스를 검사하고 수정할 수 있는 더 많은 유연성을 제공하기 때문에 유용합니다.

위의 문제에 대한 이유:

이 두 가지 방법에 대한 설명에 따르면 문제의 원인을 알 수 있습니다.

WAR Exploded 배치 방식은 WAR 배치 방식처럼 별도의 파일로 패키징하는 것이 아니라 보통 웹 애플리케이션의 자원을 웹 서버의 특정 디렉토리에 직접 배치한다.

웹 애플리케이션의 저장 위치가 제대로 설정되지 않은 경우 이전에 다운로드한 파일을 덮어쓸 수 있습니다. 각 요청이 동일한 리소스에 액세스할 수 있고 저장 위치가 잘못되어 새로 다운로드한 파일이 이전에 다운로드한 파일을 덮어쓸 수 있기 때문입니다.

또한 WAR Exploded 배포 모드에서 프로젝트가 종료되면 웹 서버는 작업 디렉터리에서 웹 애플리케이션의 리소스를 삭제합니다. 결과적으로 다운로드한 모든 파일도 삭제되어 파일이 사라지는 문제가 발생할 수 있습니다.

배포 방법을 변경하지 않는 솔루션:

배포 방법을 변경할 수 없는 경우 이 문제도 해결할 수 있습니다(답은 chatGPT에서 제공, 시도 없음).

        1. 구성 파일 업로드 디렉터리.

upload.location이를 방지하기 위해 애플리케이션의 구성 파일(예: Web.xml)에 이름이 지정된 컨텍스트 매개변수를 정의 하고 해당 값을 파일이 업로드된 디렉토리로 설정할 수 있습니다 .

예를 들어 Spring MVC에서 다음 코드를 사용하여 컨텍스트 매개 변수를 얻고 파일이 저장되는 위치를 지정할 수 있습니다.

String uploadDir = servletContext.getInitParameter("upload.location");
Path fileStorageLocation = Paths.get(uploadDir).toAbsolutePath().normalize();
Path filePath = fileStorageLocation.resolve(file.getOriginalFilename());

실제 응용 프로그램에서는 요구 사항에 따라 다른 업로드 파일 위치를 선택할 수 있습니다.

        2. 구성 파일 다운로드 디렉토리.

다운로드한 파일이 사라지지 않도록 다운로드한 파일을 디스크의 다른 경로와 같이 웹 응용 프로그램 외부 위치에 저장할 수 있습니다. 파일 다운로드를 구현할 때 먼저 파일을 지정된 디렉터리에 복사한 다음 지정된 디렉터리에서 클라이언트로 파일을 반환할 수 있습니다.

예를 들어 Spring MVC에서 다음 코드를 사용하여 지정된 디렉토리에서 파일을 읽고 클라이언트에 반환할 수 있습니다.

String downloadDir = servletContext.getInitParameter("download.location");
Path fileStorageLocation = Paths.get(downloadDir).toAbsolutePath().normalize();
Path filePath = fileStorageLocation.resolve(fileName);
Resource resource = new UrlResource(filePath.toUri());
return ResponseEntity.ok()
        .contentType(MediaType.parseMediaType(contentType))
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
        .body(resource);

실제 응용 프로그램에서는 다른 다운로드 파일 위치 및 기타 관련 구성을 선택할 수 있습니다.

추천

출처blog.csdn.net/m0_56680022/article/details/130139917