본문 바로가기

Spring

Spring - I/O 파일 업로드, 저장

1. I/O 활용 전 세팅

1-1. pom.xml 세팅

1. maven repository 에서 검색 후 라이브러리 설치

2. pom.xml 에 업로드

3. commons-fileupload 쓰는 이유
          -> @Muticonfig 로 server 에 업로드 하면 CDN서버(이미지 전용 서버)를 못 씀
              ∴ 그래서 commons-fileupload 이 나옴 => CDN ,localserver 다 사용 가능

 

1-2. webpage.xml 세팅 (servlet-context.xml)

1. 파일 업로드를 사용할 수 있도록 class 를XML로 로드
     -> ctrl + h 로 CommonsMultipartResolver 검색 후 패키지 가져와서 property class 로 넣기

🚨 속성 값을 정해주기 : 인코딩, 파일 용량, 업로드 메모리 etc..
     ⑴ id : multipartResolver (필수로 해당 아이디를 적용)
     ⑵ maxInMemorySize 값이 너무 커서 수업 도중 계속 오류발생
          -> maxInMemorySize 값을  200000d으로 수정함
     ⑶ maxUploadSize : 최대 업로드 파일 크기 ( -1 : 업로드 용량 제한 없음)
     ⑷ maxInMemorySize : Tomcat에서 사용되는 메모리와 대칭이 되며 server.xml에
                                          메모리 max에 할당되는 size만큼 적용할 수 있음
                                         => 서버에서 할당되는 만큼 만 사용할 수 있음 (쓸수록 속도가 향상됨) 
                                              잘 못 쓰면 메모리 과부하로 서버 shutdown 

 

2. I/O 활용

2-1. 한개의 파일 업로드, 웹 디렉토리에 저장

1. form 전송 시 enctype="multipart/form-data" 꼭 쓰기
2. I/O(파일 전송)쓸 때 예외처리 안하면 에러남
3. file i/o 문법
          ⑴ RequestParam ("form 에 사용한 name명")
          ⑵ realpath 를 가져오려면 HttpServletRequest가 필수적임
          ⑶ 저장될 경로는 웹 경로 + 파일 명
          ⑷ MultipartFile 자료형 :  @RequestParam 사용시 form 에 대한 Name 만 적용,
                                                  Required 적용 안됨,
                                                  첨부 안했을 때 (null일때) 알아서 거름
 
    @Controller
    public class shop_main2 {

        @PostMapping("/fileupok.do")
        public void fileupok(@RequestParam("mfile") MultipartFile files, 
        HttpServletRequest req) throws Exception{
            String filenm = files.getOriginalFilename(); //파일명
            long filesize = files.getSize(); //파일 사이즈 (int 는 너무 작아서 long 으로 써줌)
            String filetype = files.getContentType(); //파일 속성
            String url = req.getServletContext().getRealPath("/upload/")+filenm; //저장될 경로
            System.out.println(url); //syso 로 띄워서 실제 경로에 upload 폴더 생성해놓기

            if(filesize>2097152) {//2MB
                System.out.println("첨부파일 용량은 2MB이하 입니다.");
            }else {
                File fe = new File(url+filenm);
                byte by[] = files.getBytes();
                FileCopyUtils.copy(by, fe);
                //FileCopyUtils.copy(files.getBytes(), new File(url)); -> 한줄로 줄여쓰기
            }
    }
 4. 출력 파트
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Spring Fileupload 기능 사용법</title>
    </head>
    <body>
    <form id="frm" method="post" action="./fileupok.do" enctype="multipart/form-data">
    <p>첨부파일 업로드</p>
    파일 첨부 : <input type="file" name="mfile"><br>
    <input type="button" value="전송" onclick="fileup()">
    </form>
    </body>
    <script>
    function fileup() {
        frm.submit();
    }
    </script>
    </html>

 

 

2-2. 파일 여러개 업로드

1. 동일한 첨부파일 name 일 경우 원시배열로 값을 이관받음
2. Front 에서 multiple을 구현하더라도 동일하게 원시배열로 이관 받을 수 있음
    @Controller
    public class shop_main2 {
        @PostMapping("/fileupok2.do")
        public void fileupok2(@RequestParam("mfile") MultipartFile files[], 
        HttpServletRequest req)throws Exception {
        	//Front 쪽에서 동일한 name을 사용한 갯수 (첨부한 파일수와 관계 없이)
            int file_ea = files.length; 
            //name 값이 다 다를 경우 
            //@RequestParam("mfile1")MultipartFile files1 
            //@RequestParam("mfile2") MultipartFile files2 
            //@RequestParam("mfile3")MultipartFile files3 형태로 받아야함
        }
    }​
 3. 출력 파트
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>여러개의 파일을 업로드하는 형태(Spring)</title>
    </head>
    <body>
    <form id="frm" method="post" action="./fileupok2.do" enctype="multipart/form-data">
    <p>첨부파일 업로드</p>
    <!--  
    파일 첨부1 : <input type="file" name="mfile"><br>
    파일 첨부2 : <input type="file" name="mfile"><br>
    파일 첨부3 : <input type="file" name="mfile"><br>
    -->
    파일 첨부 : <input type="file" name="mfile" multiple="multiple"><!-- multiple 이어도 뒤에서 받는법은 한개랑 같음 -->
    <input type="button" value="전송" onclick="fileup()">
    </form>
    </body>
    <script>
    function fileup() {
        frm.submit();
    }
    </script>
    </body>
    </html>

 

2-3. 업로드 된 첨부파일 삭제

- DB, 실제 저장된 웹디렉토리 둘다에서 삭제되어야함 -

1. DB 에서 삭제

2. 웹 디렉 토리에서 삭제
     -> DB 에 저장된 웹 디렉토리 경로 가져와야함 (업로드된 파일명 말고 저장한 파일명)
     -> DB 에 저장했다는 가정 하에 코드작성 
    public class gallery_delete {
            Connection con = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            PrintWriter pw = null;
            String result="";

            shop_main2 sm;
            //게시물 삭제
            public String deleteok(BasicDataSource dataSource, 
            HttpServletRequest req) throws Exception{
                try {
                    this.con = dataSource.getConnection();
                    //파일 삭제
                    //웹에 저장된 이름을 가져와야함 (오리지널 필요없음)
                    String query = "select gfile from gallery where gidx=? order by gidx desc";
                    this.ps = this.con.prepareStatement(query);
                    this.ps.setInt(1, sm.gidx);
                    this.rs = this.ps.executeQuery();
                    this.rs.next();

                    //첨부파일 있을 경우 삭제하는 조건문
                    if(this.rs.getString(1)!=null) {//파일이 실제할 경우
                        String filename[] = this.rs.getString(1).split(","); // , 이외 |등 쓸 경우 //|형태로 써야함
                        String url = req.getServletContext().getRealPath("./upload/");
                        int w=0;
                        while(w < filename.length) {
                            File f = new File(url+filename[w]);
                            f.delete();//파일삭제를 실행하는 메소드				
                            w++;
                        }
                    }		
                    //DB 삭제			
                    String sql = "delete from gallery where gidx=? order by gidx desc";
                    //order by 사용 이유 : 최신글 부터 찾게하여 속도 향상을 위한것
                    this.ps = this.con.prepareStatement(sql);
                    this.ps.setInt(1, sm.gidx);
                    this.ps.executeUpdate();
                    this.result = "Y";
                } catch (Exception e) {
                    this.result = "N";
                }finally {
                    this.ps.close();
                }
                return this.result;
            }
        }​

     

 

 

'Spring' 카테고리의 다른 글

Exception 예외처리  (0) 2024.07.12
Spring - I/O + DB gallaryboard 제작  (0) 2024.07.11
Spring - 쿠폰 생성 프로세서  (0) 2024.07.10
legacy project 생성  (0) 2024.07.09
Database 연결 (Spring)  (0) 2024.07.09