3

파일을 업로드하여 서버에 저장하려고합니다. 그러나 나는 얻는다 :java.lang.IllegalStateException : 파일이 이미 이동되었습니다. 다시 전송할 수 없습니다.

java.lang.IllegalStateException: File has already been moved - cannot be transferred again 

나는 Commons FileUpload jar (CommonsMultipartFile)를 사용하고있다. 문에 대한 IllegalStateException이 발생합니다. user.getFileData().transferTo(new File("/home/xavier/uploads/" + user.getFileData().getOriginalFilename()));

여기서 user은 빈입니다. 그것은 처음에는 나를 위해 일했지만 다시 업로드 폴더에서 파일을 삭제하여 테스트했을 때 위와 같이 예외가 발생했습니다.

스택 트레이스는 :

java.lang.IllegalStateException: File has already been moved - cannot be transferred again 
    at org.springframework.web.multipart.commons.CommonsMultipartFile.transferTo(CommonsMultipartFile.java:126) 
    at com.raistudies.controllers.RegistrationController.processForm(RegistrationController.java:113) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641) 
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97) 
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165) 
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791) 
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693) 
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954) 
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170) 
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) 
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76) 
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) 
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) 
    at com.sun.grizzly.ContextTask.run(ContextTask.java:69) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309) 
    at java.lang.Thread.run(Thread.java:722) 
+0

스택 트레이스를 게시 할 수 있습니까? – NINCOMPOOP

+1

이것은 1) multipartFile.transferTo (destFile)을 한 번 이상 호출하거나 2) 요청 수명주기 밖에서 transferTo를 호출하여 발생합니다. – NINCOMPOOP

+0

나는 내 문제를 해결했다. 다음은 http : // stackoverflow 링크입니다.com/questions/3747430/with-spring-fileupload –

답변

3

질문에서 언급 한 예외는 "파일 이동 - 다시 읽을 수 없습니다."입니다. 이는 멀티 파트 파일에서 한 번 이상 inputstream을 읽으려고하기 때문입니다.

또한 한 번에이 문제에 직면했으며, 제 경우에는 파일의 내용을 확인한 후 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

관찰 : 아래의 코드 세그먼트를 따르십시오

가 너무 작 으면

, 봄이 저장 메모리에 우리가 파일을 요청할 때 메모리에서 가져 오지. 파일이 메모리에 있기 때문에 여러 번 요청할 수 있습니다.

크기가 크다면, Spring은 위치를 알지 못하는 임시 파일로 저장하지만 일단 inputstream을 읽은 후에는 그 파일을 Spring에서 내부적으로 삭제할 수 있습니다. 그런 다음 두 번째로 "다시 읽을 수 없습니다"라는 오류 메시지가 표시됩니다.

내 솔루션은 먼저 "transferTo"방법을 사용하여 서버 loaction에 저장하고 유효성 검사 또는 다른 두 번째 시간 필요에 해당 로컬 파일을 다시 얻어야합니다.

"multipartResolver"bean에서 "maxUploadSize"를 늘리는 것이 좋지 않다고 생각합니다. 파일이 너무 크면 더 많은 메모리를 소비하기 때문입니다.

+0

포맷을 변경하고자 할 수 있습니다. 비 코드를 코드로 포맷하면 읽기가 어렵습니다. 마지막 부분도 잘립니다. 네가 말하려고했던 다른 것이 있었 니? –

+0

나는 내 대답의 형식을 지정했습니다. 우려되는 점을 회신 해주십시오. – Arosha