승두루
22
2019-04-29 21:49:19 작성 2019-04-29 21:56:43 수정됨
2
377

Spring 다중이미지 FormData ajax 업로드 에러


홈페이지 개발중 다중이미지를 업로드하는 게시판을 만들었습니다.

하지만 업로드하면 아래와 같은 에러가 납니다


org.apache.catalina.core.StandardWrapperValve invoke
심각: Servlet.service() for servlet [appServlet] in context with path [/daekwang] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket] with root cause
java.io.EOFException: Unexpected EOF read on the socket
	at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:734)
	at org.apache.coyote.http11.Http11InputBuffer.access$300(Http11InputBuffer.java:40)
	at org.apache.coyote.http11.Http11InputBuffer$SocketInputBuffer.doRead(Http11InputBuffer.java:1084)
	at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:140)
	at org.apache.coyote.http11.Http11InputBuffer.doRead(Http11InputBuffer.java:263)
	at org.apache.coyote.Request.doRead(Request.java:581)
	at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:326)
	at org.apache.catalina.connector.InputBuffer.checkByteBufferEof(InputBuffer.java:642)
	at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:349)
	at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:183)
	at java.io.FilterInputStream.read(Unknown Source)
	at org.apache.commons.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:134)
	at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:999)
	at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:903)
	at java.io.InputStream.read(Unknown Source)
	at org.apache.commons.fileupload.util.Streams.copy(Streams.java:100)
	at org.apache.commons.fileupload.util.Streams.copy(Streams.java:70)
	at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:347)
	at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115)
	at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:158)
	at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:142)
	at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1175)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1010)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:901)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Unknown Source)


현재 이미지 업로드는 insert 페이지에서 추가되는 파일을 FormData에 하나씩 담아

컨트롤러로 넘겨서 처리하고 있습니다.



               // 이미지 담을 폼데이터 세팅
		var formData = new FormData($('#uploadForm')[0]);
	
		// 이미지 배열을 폼데이터에 추가
		for(var i=0 ; i < filesTempArr.length; i++) {
		   formData.append("img", filesTempArr[i]);
		}
		
		$.ajax({
		    url : "insertChurchPhoto.do",
		    type : "POST",
		    data : formData,
		    processData: false,
		    contentType : false,
		    success : function(data) {
		    	if(data = "success"{
	        	    location.href = "churchPhoto.do";
                        }
		    },
		    error : function(err) {
		        alert(err.status);
		        location.href = "churchPhoto.do";
		    }
		});

선택된 파일을 filesTempArr 라는 배열에 넣고 formdata에 하나씩 append 시켜서 ajax로 컨트롤러로 넘깁니다.


@RequestMapping(value = "/insertChurchPhoto.do", method=RequestMethod.POST)
	public void insertChurchPhoto(Model model, MultipartHttpServletRequest mtfRequest, HttpServletRequest request, BoardVo boardVo, PhotoVo photoVo, HttpServletResponse response) throws IOException {
		
		//파일객체생성
		List<MultipartFile> fileList = mtfRequest.getFiles("img");
		System.out.println(fileList);
		System.out.println(boardVo);
		
		경로설정
		String root = request.getSession().getServletContext().getRealPath("resources");
		String path = root + "\\uploadChurch\\";
		
		//변수 설정
		String originFileName = null ;// 원본 파일 명
        String ext = null;//확장자명
        long reFileName = 0;  // 고유 파일 명
		String safeFile = null;
		int result = 0;
		
		if(fileList != null && fileList.size() > 0) {
		
			//게시판 정보 저장
			int board_no = boardSerivce.insertChurchPhotoBoardVo(boardVo);
			
			
	        for (MultipartFile mf : fileList) {
	        	
	        	if(!mf.isEmpty()) {
		        	
		            originFileName = mf.getOriginalFilename(); // 원본 파일 명
		            ext = originFileName.substring(originFileName.lastIndexOf('.')); //확장자명 추출
		            reFileName = System.currentTimeMillis();  // 고유 파일 명
		            
		            photoVo.setPHOTO_ORNAME(originFileName);
		            photoVo.setPHOTO_RENAME(Long.valueOf(reFileName).toString() + ext);
		            photoVo.setBOARD_NO(board_no);
		            photoVo.setMEMBER_NO(boardVo.getMEMBER_NO());
		            photoVo.setUPLOAD_YYMM(format_time);
		            
		            //사진 정보 저장
		            result = boardSerivce.insertChurchPhotoPhotoVo(photoVo);
		            
		            //생성된 파일 객체 이미지파일로 변환
		    		BufferedImage image = ImageIO.read(mf.getInputStream());
		            //저장될 파일 명
		            safeFile = path + reFileName + ext;
		            
		            try {
		            	ImageIO.write(imageResize(image), "jpg", new File(safeFile));
		            	ImageIO.setUseCache(false);
		            	
		            } catch (IllegalStateException e) {
		                // TODO Auto-generated catch block
		                e.printStackTrace();
		            } catch (IOException e) {
		                // TODO Auto-generated catch block
		                e.printStackTrace();
		            }
	        	}
	        }
	}

formdata로 넘어온 파일을 List<MultiparFile> 로 받아서 for문으로 하나씩 풀어 업로드 시킵니다.

중간에 BufferedImage로 바꿔주는 것은 용량이 큰 이미지를 resizing 시켜주기위한 것입니다.


아무리 찾아보고 바꾸어보아도 같은 에러에 직면하여 이렇게 도움의 손길을 구합니다.

0
0
  • 답변 2

  • full
    835
    2019-04-30 09:21:30 작성 2019-04-30 09:22:48 수정됨

    스트림을 close해주지 않아서 그런게 아닐가요??


    대게 저오류는 깨진 파일 업로드, 파일업로드 용량초과 등 서버에 파일올리는 중간에 오류가 발생할때 자주보이는 현상입니다.

    0
  • 승두루
    22
    2019-04-30 09:53:50

    @full

    답변감사합니다.

    제가 어제 글을 올린후 찾아보기위해 

    하나하나씩 주석처리 하면서 실행해봤습니다.

    근데 제일위에 List<Multipartfile> fileList

    이부분만 남겼는데 이곳에서 에러는 뱉더군요..

    현재 servlet-context에 multipartResolver에

    업로드 용량은 50M로 넉넉하게 잡아놨고

    이미지 하나하나의 용량은 1M 도 되지 않습니다

    이미지가 5장 정도 넘어오면 리스트에서 받아지는데

    7장~10장 정도 넘어오게되면 EOFException이 

    발생합니다.

    그래서 Map<string, Multipartfile>로 받아보아도

    이미지가 많이 넘어오면 같은 Exception이 발생합니다ㅜ

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.