혜미의 개발 일지

[Java] 자바 파일 업로드& 다운로드 구현하기 본문

프레임워크/Spring framework

[Java] 자바 파일 업로드& 다운로드 구현하기

혜미 2022. 3. 10. 18:04
반응형

내가 보고 따라해서 구현한 블로그

 

[펌]파일 업로드 & 다운로드 (1/3)

웹에서 첨부파일은 상당히 문제가 많이 일어나는 부분이기도 합니다. 실제로 프로젝트중에서 첨부파일때문에 오픈이 지연되는 경우도 봤었구요. 제가 이번글에서 쓸 내용은 첨부파일 업&다운

enterkey.tistory.com

이를 통해 참고하여 구현하였다. (사실 이 밖에도 몇개 있었는데 다 기억이 나지 않는다..)

파일은 모듈로 공용으로 쓸 수 있게 따로 빼두었다.

주석은 내가 해석하며 작성해 놓았던건데 그대로 가져다써도 각 프로젝트 환경은 다 다르기에 참고만 해주세요.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Iterator;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import com..file.web.FileController;

import egovframework.util.CommonUtils;
import egovframework.util.Globals;

import com..cmm.CmmInterface;
import com..file.model.FileVO;
import com.r.file.service.FileService;

/**
 * 시스템      : 코어
 * 단위 시스템 :
 * 프로그램 명 : 엑셀 업로드 및 DB저장, 다운로드, 삭제
 * 파일명      : File.java
 * 설명        : 파일관련 모음
 
 * 이력사항
 * 송혜미  : 2022.01.04
 */
@Controller
public class FileController extends CmmInterface{


Logger logger = LogManager.getLogger(FileController.class);

@Resource(name="FileService")
private FileService fileService;


@RequestMapping({"/file/ajaxUploadAndSaveFile.do"})
public ModelAndView ajaxUploadAndSaveFile(MultipartHttpServletRequest mtfRequest, ModelAndView mv) throws Exception {
this.logger.info("===============ajaxUploadAndSaveFile ====================");

String result = "OK";

String src = mtfRequest.getParameter("src");

MultipartFile mf = mtfRequest.getFile("fileList"); //멀티파일 형식으로 받음
//MultipartHttpServletRequset 형식으로 형변환을 하였다.
   
String filePath = Globals.FILE_PATH; //글로벌프로퍼티에서 미리 설정해놓은 파일 주소로 로컬용과 서버용을 바꿔서 사용한다.
//참고로 서버용시 엔진엑스에 따로 파일 설정을 하지않아 파일 접근이 내부만 가능하기에 주소에 프로젝트 내부주소로 업로드 시켜 공유하도록 했다. 

String originFileName = mf.getOriginalFilename(); //원본 파일 명
   
Iterator<String> iterator = mtfRequest.getFileNames();
//Iterator를 이용하여 Map에 있는 데이터를 while문을 이용하여 순차적으로 접근하려고 한다.
  
MultipartFile multipartFile = null;
String originalFileName = null;
String originalFileExtension = null;
String storedFileName = null;
File file = new File(filePath);
   
if (!file.exists())
     file.mkdirs(); 
     //파일폴더가 없으면 폴더를 생성해줌
   while (iterator.hasNext()) {
     multipartFile = mtfRequest.getFile(iterator.next());
     
     if (!multipartFile.isEmpty()) {
      
       originalFileName = multipartFile.getOriginalFilename();
       originalFileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
       //파일의 원본이름을 받아와서 해당 파일의 확장자를 알아낸 후,
       //아까 CommonUtils 클래스에 만들었던 getRandomString() 메서드를 이용하여 32자리의 랜덤한 파일이름을 생성하고
       
   	   storedFileName = String.valueOf(CommonUtils.getRandomString()) + originalFileExtension;
   	   //원본파일의 확장자를 다시 붙여주었다.
       
       file = new File(String.valueOf(filePath) + storedFileName);
    
  	   multipartFile.transferTo(file); //지정된 경로에 파일을 생성
   
       String str = String.valueOf(filePath) + storedFileName;

       this.logger.info("------------- file start -------------");
       this.logger.info("name : " + multipartFile.getName());
       this.logger.info("src value : " + src);
       this.logger.info("filePath : " + str);
       this.logger.info("originFileName : " + originalFileName);
       this.logger.info("storedFileName : " + storedFileName);//물리적 파일이름
       this.logger.info("fileSize : " + multipartFile.getSize());
       this.logger.info("-------------- file end ---------------");
 
   	 }
  } 
       String safeFile = String.valueOf(filePath) + storedFileName;
       
       FileVO vo = new FileVO(); //vo로 저장
       vo.setFileNm(originalFileName);
       vo.setFileTitle(storedFileName);//물리적이름생성넣기
       vo.setFilePath(safeFile);//지정된 경로에 물리적파일 이름으로 파일이 생성됨.
       vo.setFileSize(multipartFile.getSize());
       
       this.fileService.insertFile(vo);
       int fileSeq = 0;
       fileSeq = this.fileService.selectFileSeq(vo); //파일 아이디 조회 나중에 리턴으로 넘겨줘야함

       
       try {
         mf.transferTo(new File(safeFile));
       } catch (IllegalStateException e) {
         e.printStackTrace();
       } catch (IOException e) {
         e.printStackTrace();
       } 
       mv.addObject("fileSeq", Integer.valueOf(fileSeq));
       mv.addObject("OriginalFileName", originalFileName);
       mv.addObject("result", result);
       mv.setViewName("jsonView");
       return mv;
     }
     
     //파일을 다운로드한다.
     @RequestMapping("/file/ajaxFileDown.do")
     public void fileDown(@ModelAttribute FileVO fileVO, ModelMap model, HttpServletRequest request,
          HttpServletResponse response, HttpSession session) throws Exception {

        String fileId =  "" + request.getParameter("fileId");
        String fileNm =  "" + request.getParameter("fileNm");

         String path = fileService.selectFilePath( fileVO );
        
         File file = new File(path);
         
         String userAgent = request.getHeader("User-Agent");
         boolean ie = userAgent.indexOf("MSIE") > -1 || userAgent.indexOf("rv:11") > -1;
         String fileName = null;
         
         if (ie) {
            fileName = URLEncoder.encode( fileNm , "utf-8");
         } else {
            fileName = new String(fileNm.getBytes("utf-8"),"iso-8859-1");
         }
         
         response.setContentType("application/octet-stream");
         response.setHeader("Content-Disposition","attachment;filename=\"" +fileName+"\";");
         
         FileInputStream fis=new FileInputStream(file);
         BufferedInputStream bis=new BufferedInputStream(fis);
         ServletOutputStream so=response.getOutputStream();
         BufferedOutputStream bos=new BufferedOutputStream(so);
         
         byte[] data=new byte[2048];
         int input=0;
         while((input=bis.read(data))!=-1){
            bos.write(data,0,input);
            bos.flush();
         }
         
        if(bos!=null) bos.close();
        if(bis!=null) bis.close();
        if(so!=null) so.close();
        if(fis!=null) fis.close();
        
     }
     
     @RequestMapping(value = "/file/ajaxfileDelete.do")
     public ModelAndView ajaxfileDelete(@ModelAttribute FileVO fileVO, ModelAndView mv,
           HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
        
        String result = "OK";      
        
        int seq = Integer.parseInt(request.getParameter("seq"));
        logger.info("=====seq====" + seq );
        
        fileVO.setSeq(seq);
        
        try {
           fileService.fileDelete(fileVO);
           
           
        } catch (Exception e) {
           result = "FAIL";
           logger.debug("ajaxfileDelete=====================> Error" + e);
        }
        mv.addObject("result", result);
        mv.setViewName("jsonView");
        return mv;
     }


}

 

코드블럭으로 작성하니까 괄호 맞춤이 제대로 안 이뤄지네요. 보기에 불편할 수 있겠습니다.

 

 

반응형
BIG
Comments