You will be fine

<Spring> 11. File Upload&Download

by BFine
반응형

1. Spring file upload

  • Dependency 추가 : commons-fileupload 

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

// multipart type을 사용할 경우 필요, id 변경 불가

  • Form 설정에서 enctype="multipart/form-data" 으로 사용, input 타입은 file 설정

1
2
3
4
5
6
7
8
9
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String uploadfile(MultipartFile file) throws IOException{
File newfile=new File("c:/upload/"+file.getOriginalFilename());// 객체만 생성        
file.transferTo(newfile); //file부분의 내용만 던짐 
===================form=======================
<form action="<%=request.getContextPath()%>/upload" method="post"
enctype="multipart/form-data" >
파일첨부: <input type=file name="file"><br>
<input type=submit value="upload" >
cs

  • 위처럼 간단하게 업로드 가능하지만 파일명 중복이 생길 수 있다. --> 유니크한 ID 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
@RequestMapping(value="/upload",method=RequestMethod.POST)
    public String uploadfile(MultipartFile file) throws IOException{
 
        String fname=file.getOriginalFilename();
        String ext=fname.substring(fname.lastIndexOf("."));// 확장자 추출
        String uuid=UUID.randomUUID().toString().replaceAll("-""");//유니크한 uuid생성
        String uname=uuid+ext; //새로운 유니크한 이름 생성
        
        
          File newfile=new File("c:/upload/"+uname);  // 객체만 생성
          file.transferTo(newfile)//file부분의 내용만 던짐 
cs


실행



2. Spring file download

  • 서버 내에 특정 폴더에 있는 다운로드 목록 list 필요, UUID를 사용할경우 실제파일명 따로 저장 필요

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public String uploadfile(MultipartFile file) throws IOException{
        
        String fname=file.getOriginalFilename();
        String ext=fname.substring(fname.lastIndexOf("."));// 확장자 추출
        String uuid=UUID.randomUUID().toString().replaceAll("-""");//유니크한 uuid생성
        String uname=uuid+ext; //새로운 유니크한 이름 생성
        File list=new File("c:/upload/list.txt");
        
        BufferedWriter bw= new BufferedWriter(new FileWriter(list,true));
        PrintWriter pw=new PrintWriter(bw,true);
        pw.write(fname+" "+uname+"\r\n");// UUID이름 실제이름 txt에 저장
        pw.flush();
        pw.close();
 
        File newfile=new File("c:/upload/"+uname);// 객체만 생성
        file.transferTo(newfile); //file부분의 내용만 던짐 
cs

  • 다운로드시 텍스트 파일 안에 리스트 목록을 불러와서 Map에 저장한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public ModelAndView download() throws IOException{
        ModelAndView mv=new ModelAndView();
        File path=new File("c:/upload"); //내용을 보려면 not / 
    
       BufferedReader br=new BufferedReader(new FileReader("c:/upload/list.txt"));
       Map<StringString> map=new HashMap<StringString>();
       int i=0;
       String[] unames=new String[path.list().length-1];
        //path.list()는 경로 내에 모든 파일 이름을 가져온다 (list.,txt있기에 -1)
       while(br.read()!=-1){// 다음라인이 비어있지 않을때까지
          String[] fname=br.readLine().split(" ");
          map.put(fname[1], fname[0]); 
             // UUID , 실제이름(실제이름은 중복될 수 있으므로)
          unames[i++]=fname[1]; // key값 저장
       }
       
        mv.addObject("map",map);
        mv.addObject("list",unames);
        mv.setViewName("downloadform");
        return mv;
    }
cs

  • Map에 저장된 실제이름과 UUID 키들을 사용하여 링크를 구성한다. 

<c:forEach var="key" items="${list}"> 

<a href="<%=request.getContextPath()%>/down?uname=${key}">${map[key]}</a> // key는 UUID

</c:forEach>

  • File을 읽어서 outputstream을 통해 내보낸다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@RequestMapping("/down")
public  void downfile(HttpServletRequest request,HttpServletResponse response) 
throws IOException{
        String uname=request.getParameter("uname");
 
        //링크된 파일 불러오기
        File file=new File("c:/upload"+"/"+uname);
        
            //클라이언트에게 전달할 파일 정보설정
        response.setContentType("application/download");
        response.setContentLength((int)file.length());
        response.setHeader("Content-Disposition""attachment;filename=\""+uname+"\"");
        //Response 헤더에 정보 설정, attachment는 첨부하겠다는 의미
        
           OutputStream out=response.getOutputStream();
        //클라이언트와의 통로
        FileInputStream fis=new FileInputStream(file);
        // file을 읽어드린다
        FileCopyUtils.copy(fis, out);
        /*fis을 out에 복사(클라이언트로 전달) class 내부 (fis 읽고 out 방출)
         * return copy(new BufferedInputStream(new FileInputStream(in)),
          new BufferedOutputStream(new FileOutputStream(out)));*/
        fis.close();
        out.close();
    }
cs


실행

     


반응형

'공부(2018~2019) - 스킨변경전 > Spring' 카테고리의 다른 글

<Spring> 13. Mybatis-Spring  (0) 2018.05.18
<Spring> 12. Mybatis  (0) 2018.05.17
<Spring> 10. internationalization, Spring JSON  (1) 2018.05.15
<Spring> 9. MVC pattern  (0) 2018.05.09
<Spring> 8. AOP  (0) 2018.05.04

블로그의 정보

57개월 BackEnd

BFine

활동하기