복붙노트

[SPRING] Spring FileUpload의 문제점

SPRING

Spring FileUpload의 문제점

내 봄 MVC 웹 응용 프로그램에서 사용하고있는 사진의 파일 업로드를 처리하는 다음 코드 블록이 있습니다. 나는 파일 업로드를 처리하기 위해 Spring MVC CommonsMultipartFileResolver를 사용하고있다.

if(model.getPhoto() != null){
    if(!model.getPhoto().isEmpty()){
        MultipartFile file = model.getPhoto();
        String fileName = file.getOriginalFilename();
        String filePath = baseDirectory + fileName;
        FileOutputStream fos = new FileOutputStream(filePath);
         try 
         {
            fos.write(file.getBytes());
            agentProfile.setPhotoUri(fileName);
         } 
         catch (IllegalStateException e) 
         {
            System.out.println(e);

         }
         finally   
         {
             fos.close();
         }
    }
}

내 app-servlet.xml 파일에서 MultipartFile 해석자 Bean을 설정하는 다음 코드를 가지고있다.

 <bean id="multipartResolver"   class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
 </bean>

사진을 업로드 할 때 임의의 문제가 발생합니다.

1) 약 3KB 정도의 작은 사진을 업로드하면 성공적으로 업로드됩니다.

2) 약간 큰 사진을 업로드하면 디렉토리에 파일이 생성되지만 크기는 0 바이트이며 다음과 같은 오류 메시지가 표시됩니다.

 java.lang.IllegalStateException: File has been moved - cannot be read again
org.springframework.web.multipart.commons.CommonsMultipartFile.getBytes(CommonsMultipartFile.java:112)
com.mmz.admin.mvc.controller.AddAgentController.processFinish(AddAgentController.java:145)
org.springframework.web.servlet.mvc.AbstractWizardFormController.validatePagesAndFinish(AbstractWizardFormController.java:642)
org.springframework.web.servlet.mvc.AbstractWizardFormController.processFormSubmission(AbstractWizardFormController.java:492)
org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:265)
org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:874)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:808)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:476)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:441)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Multipart resolver를 CommonsMultipartFile 객체를 일반 MultipartFile 객체와 반대되는 것으로 처리하도록 전환하는 것과 같은 몇 가지 옵션을 시도했지만 아무 것도 변경되지 않았습니다.

또한 다음 속성을 사용하여 CommonsMultipartFile Resolver 빈에서 최대 업로드 크기를 수동으로 구성하려고했습니다.

 <property name="maxUploadSize" value="1024000000"/>  

아무것도 바뀌지 않았다. CommonsMultipartResolver가 기본적으로 업로드 할 수있는 파일의 크기까지 무엇인지 모르겠지만 그건 내 질문이 아닙니다.

내가 겪고있는 문제는 스프링이 사용하는 Multipart 파서 / 핸들러의 문제 때문이라고 들었다. 나는이 같은 문제에 관한 최근 게시물을 가지고 있었고 새로운 정보가 발견 되었기 때문에 새로운 정보로 다시 게시하기를 원했습니다. 이전 게시물은 CommonsMultipartFileResolver 문제에서 찾을 수 있습니다.

인터넷상의 거의 모든 자료를 확인하여 추가 문서를 찾은 것 같지만 문제를 파악할 수 없습니다.

제발 이걸로 무슨 일이 일어나고 있는지 알아낼 수 있고 어쩌면 그 옵션을 탐색기에 더 나은, 간단한 해결책이 있다면,하지만 내가 해결책을 찾을 수 있다면 내 현재의 방법으로 유지하는 것이 좋습니다.

편집하다 참고 - 업로드 할 다른 크기의 사진을 실험하고 있으며 업로드가 허용되는 한도가 약 10KB라고 생각합니다. 10Kb보다 큰 값이 있으면 오류가 발생하여 위의 오류가 발생합니다.

해결법

  1. ==============================

    1.많은 연구를 한 후에, 나는 나의 문제를 해결했다. CommonsMultipartFileResolver를 사용하여 업로드 할 수있는 최대 바이트 수에 대한 기본 제한이 설정되어 있지 않음이 밝혀졌습니다. 물론 다음 속성을 설정하여이 양에 대해 원하는 모든 것을 bean에 지정할 수 있습니다.

    많은 연구를 한 후에, 나는 나의 문제를 해결했다. CommonsMultipartFileResolver를 사용하여 업로드 할 수있는 최대 바이트 수에 대한 기본 제한이 설정되어 있지 않음이 밝혀졌습니다. 물론 다음 속성을 설정하여이 양에 대해 원하는 모든 것을 bean에 지정할 수 있습니다.

    <property name="maxUploadSize" value="99999999999"/>
    

    또한 파일에 디스크 쓰기 전에 허용되는 최대 크기를 지정할 수있는 maxInMemorySize 속성이 있습니다. 최대 업로드 크기와 동일한 방식으로 작동하지만 금액을 지정하지 않으면 기본값은 1024 바이트입니다. 이렇게하면 큰 파일을 업로드하려고 시도했을 때 깨지는 현상을 설명 할 수 있습니다.

    1024 바이트 이상의 파일을 업로드하려면 maxInMemorySize 값을 다음과 같이 필요한만큼 늘려야합니다 ...

    이것이 내 문제를 해결 한 것입니다. CommonsFileUpload Documentation에 대한 문서를 검토 할 때이 속성 기본값이 1024 인 것을 알았습니다.

    이 문서는 CommonsFileUpload Documentation에서 볼 수 있습니다.

    CommonsMultipartFile 사용에 관한 문서가별로 없기 때문에 이것이 누구에게 도움이되기를 바랍니다.

  2. ==============================

    2.이 오류는 파일이 1024 바이트를 초과하고 파일을 두 번 읽으려고 할 때만 발생합니다. CitadelCSAlum에서 언급했듯이 maxInMemorySize = maxUploadSize로 설정하면이 문제가 해결되지만 메모리 사용에 유의해야합니다. 메모리가 문제가되면 다른 옵션으로 다중 파트 파일 데이터를 첫 번째 읽기의 임시 파일에 쓰고 그 파일을 후속 읽기에 사용합니다. 두 번 읽지 않으면 maxInMemorySize를 늘릴 필요가 없습니다.

    이 오류는 파일이 1024 바이트를 초과하고 파일을 두 번 읽으려고 할 때만 발생합니다. CitadelCSAlum에서 언급했듯이 maxInMemorySize = maxUploadSize로 설정하면이 문제가 해결되지만 메모리 사용에 유의해야합니다. 메모리가 문제가되면 다른 옵션으로 다중 파트 파일 데이터를 첫 번째 읽기의 임시 파일에 쓰고 그 파일을 후속 읽기에 사용합니다. 두 번 읽지 않으면 maxInMemorySize를 늘릴 필요가 없습니다.

  3. ==============================

    3.귀하의 질문에 언급 한 예외 상태 : "파일 이동되었습니다 - 다시 읽을 수 없습니다". 이는 멀티 파트 파일에서 한 번 이상 입력 스트림을 읽으려고하기 때문입니다.

    귀하의 질문에 언급 한 예외 상태 : "파일 이동되었습니다 - 다시 읽을 수 없습니다". 이는 멀티 파트 파일에서 한 번 이상 입력 스트림을 읽으려고하기 때문입니다.

    나는 또한이 문제에 한 번에 직면했으며, 제 경우에는 파일의 내용을 확인한 후 Spring MultiPart에서 "transferTo"메소드를 사용하여 저장하려고했습니다. 이 예외는 "transferTo"메서드를 사용하려고 할 때 발생합니다. 여기에 inputstream을 두 번 요구합니다.

    파일 크기가 너무 작 으면이 문제가 발생하지 않습니다. "transferTo"메서드에는 "isAvailable"메서드에 대한 내부 호출이 있습니다. 아래의 코드 부분을 따르십시오 :

        protected boolean More ...isAvailable() {
                // If in memory, it's available.
            if (this.fileItem.isInMemory()) {
                return true;
            }
            // Check actual existence of temporary file.
            if (this.fileItem instanceof DiskFileItem) {
                return ((DiskFileItem) this.fileItem).getStoreLocation().exists();
            }
            // Check whether current file size is different than original one.
            return (this.fileItem.getSize() == this.size);
        }
    

    링크 : http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-web/3.2.1.RELEASE/org/springframework/web/multipart/commons/CommonsMultipartFile.java#CommonsMultipartFile. isAvailable % 28 % 29

    관찰 :

    그래서 내 솔루션은 먼저 "transferTo"메서드를 사용하여 서버 위치에 저장하고 유효성 검사 또는 다른 두 번째 시간 필요에 해당 로컬 파일을 검색 할 수 있습니다.

    파일이 너무 큰 경우 더 많은 메모리를 소비하므로 "multipartResolver"bean에서 "maxUploadSize"를 늘리는 것이 좋지 않다고 생각합니다.

  4. from https://stackoverflow.com/questions/3747430/problem-with-spring-fileupload by cc-by-sa and MIT license