Spring Boot)File Upload 파일업로드

메타플랫폼대표
|2024. 8. 13. 14:38
반응형

 

파일 업로드를 스프링 부트로 만들어보자.

 

프로젝트 생성하기

 

 

application.properties 넣어주기

spring.application.name=demo_fileupload

#단일화일 최대용량(생략시 기본 1MB)
spring.servlet.multipart.max-file-size=100MB
#업로드화일 총화일의 최대용량(생략시 기본 10MB)
spring.servlet.multipart.max-request-size=512MB

 


[ JSP 세팅 ]

 

spring.application.name=demo_fileupload


spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp


#단일화일 최대용량(생략시 기본 1MB)
spring.servlet.multipart.max-file-size=100MB
#업로드화일 총화일의 최대용량(생략시 기본 10MB)
spring.servlet.multipart.max-request-size=512MB

 

 

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>


        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>jakarta.servlet.jsp.jstl</groupId>
            <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>jakarta.servlet.jsp.jstl</artifactId>
            <version>3.0.1</version>
        </dependency>

 

 

 

 

 

반드시 form method는 POST 타입으로 지정해준다!

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script>
        function send(f) {
            let title = f.title.value.trim();
            let photo = f.photo.value;

            if(title=="") {
                alert("제목을 입력하세요.");
                f.title.value="";
                f.title.focus();
                return;
            }

            if(photo=="") {
                alert("사진을 선택하세요.");
                return;
            }

            f.action = "upload1.do";
            f.submit();
        }
    </script>
</head>
<body>
    <form method="POST" enctype="multipart/form-data">
        제목 : <input name="title"><br>
        사진 : <input type="file" name="photo"><br>
        <input type="button" value="전송" onclick="send(this.form);">
    </form>
</body>
</html>

 

 

[ @PostMapping, @RequestMapping RequestMethod.POST ]

@Controller
public class FileUploadController {

    @Autowired
    ServletContext application;

    // upload1.do?title=제목&photo=a.jpg

    // @PostMapping()으로 적어도됨. method=POST로 받고 있기 때문
    @RequestMapping(value = "/upload1.do", method = RequestMethod.POST)
    public String upload1(String title, MultipartFile photo) {

        return "result1";
    }

}

 

 

 

parameter에 MultipartFile을 받기 위해서는 @RequestParam을 남겨주어야 한다.

 

결론적으로, 요청 파라미터를 명시적으로 바인딩하고 싶다면 @RequestParam을 사용하는 것이 좋습니다. 그렇지 않으면, 해당 매개변수는 null이 될 수 있습니다.

 

 

@Controller
public class FileUploadController {

    @Autowired
    ServletContext application;

    // upload1.do?title=제목&photo=a.jpg

    // @PostMapping()으로 적어도됨. method=POST로 받고 있기 때문
    //                              @RequestParam(name="photo") <= param name과 
    @RequestMapping(value = "/upload1.do", method = RequestMethod.POST)
    public String upload1(String title, @RequestParam(name="photo") MultipartFile photo) {

        // 저장할 위치정보 구하기(절대경로)
        String absPath = application.getRealPath("/images/");
        System.out.println(absPath);

        return "result1";
    }

}

 

 

 

 

 

 

 

@Controller 최종

@Controller
public class FileUploadController {

    @Autowired
    ServletContext application;

    // upload1.do?title=제목&photo=a.jpg

    // @PostMapping()으로 적어도됨. method=POST로 받고 있기 때문
    //                              @RequestParam(name="photo") <= param name과 
    @RequestMapping(value = "/upload1.do", method = RequestMethod.POST)
    public String upload1(String title, @RequestParam(name="photo") MultipartFile photo,
                            Model model) throws IllegalStateException, IOException {

        // 저장할 위치정보 구하기(절대경로)
        String absPath = application.getRealPath("/images/");
        System.out.println(absPath);

        // 파일업로드 처리
        String filename = "no_file";
        if(!photo.isEmpty()) {

            filename = photo.getOriginalFilename();

            File f = new File(absPath, filename);

            if(f.exists()) { // 동일 파일명 존재시 이름변경
                long tm = System.currentTimeMillis(); // 시간 생성
                filename = String.format("%d_%s", tm, filename); // 시간을 앞에 붙인다.
                f = new File(absPath, filename);
            }

            photo.transferTo(f);
        }

        // request Binding
        model.addAttribute("title", title);
        model.addAttribute("filename", filename); // 위는 실질적인 경로 저장이고, 이건 image 호출용으로 넘긴다.

        return "result1";
    }

}

 

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    여기는 result1입니다.
    제목:${ title }<br>
    이미지: <img src="images/${ filename }" width="300">
    <br>
    <br>
    <a href="input1.html">다시해보자</a>
</body>
</html>

 

 

 

 

 

 

[ 업로드 File 두개 이상 있을 때 ]

유의할점 : 여기서 이름이 photo로 달라질 경우 Spring에서 받지 못한다. 반드시 name 통일

 

MultipartFile은 하나로 묶어서 처리하기 때문이다.

그래서, 두개 이상 저장할 때는 배열로 저장한다.

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script>
        function send(f) {
            let title = f.title.value.trim();
            let photo1 = f.photo[0].value;
            let photo2 = f.photo[1].value;

            if(title=="") {
                alert("제목을 입력하세요.");
                f.title.value="";
                f.title.focus();
                return;
            }

            if(photo1=="") {
                alert("사진1을 선택하세요.");
                return;
            }

            if(photo2=="") {
                alert("사진2을 선택하세요.");
                return;
            }

            f.action = "upload2.do";
            f.submit();
        }
    </script>
</head>
<body>
    <form method="POST" enctype="multipart/form-data">
        제목 : <input name="title"><br>
        사진1 : <input type="file" name="photo"><br>
        사진2 : <input type="file" name="photo"><br>
        <input type="button" value="전송" onclick="send(this.form);">
    </form>
</body>
</html>

 

 

 

    // upload2.do?title=제목&photo=a.jpg&photo=b.jpg
    @PostMapping("/upload2.do")
    public String upload2(String title, 
                        @RequestParam(name="photo") MultipartFile [] photo_array,
                        Model model) throws IllegalStateException, IOException {
        
        // 저장할 위치정보 구하기(절대경로)
        String absPath = application.getRealPath("/images/");

        String filename1 = "no_file";
        String filename2 = "no_file";

        for(int i=0; i<photo_array.length; i++) { // i = 0 1
            MultipartFile photo = photo_array[i];

            if(!photo.isEmpty()) {

                String filename = photo.getOriginalFilename();
    
                File f = new File(absPath, filename);
    
                if(f.exists()) { // 동일 파일명 존재시 이름변경
                    long tm = System.currentTimeMillis(); // 시간 생성
                    filename = String.format("%d_%s", tm, filename); // 시간을 앞에 붙인다.
                    f = new File(absPath, filename);
                }
    
                photo.transferTo(f);
                if(i==0) {
                    filename1 = filename;
                } else if (i==1) {
                    filename2 = filename;
                }
            }

        }// end:for

        // request Binding
        model.addAttribute("title", title);
        model.addAttribute("filename1", filename1);
        model.addAttribute("filename2", filename2);
                    
        return "result2";
    }

 

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    여기는 result2입니다.
    제목:${ title }<br>
    이미지: <img src="images/${ filename1 }" width="300">
    이미지: <img src="images/${ filename2 }" width="300">
    <br>
    <br>
    <a href="input2.html">다시해보자</a>
</body>
</html>

 

 

 

 

 

 

 

[ File n개 업로드 ]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script>
        function send(f) {
            let title = f.title.value.trim();
            let count = f.photo.files.length;

            if(title=="") {
                alert("제목을 입력하세요.");
                f.title.value="";
                f.title.focus();
                return;
            }

            // 파일 선택 갯수 제한 1~6개는 선택 해야한다.
            if(count < 1 || count > 6) {
                alert("업로드 시킬 사진은 1~6개 사이를 선택하세요.");
                return;
            }

            f.action = "upload3.do";
            f.submit();
        }
    </script>
</head>
<body>
    <form method="POST" enctype="multipart/form-data">
        제목 : <input name="title"><br>
        사진1 : <input type="file" name="photo" multiple><br>
        <input type="button" value="전송" onclick="send(this.form);">
    </form>
</body>
</html>

 

 

 

@Controller에서 List<MultipartFile>로 다수의 파일을 받아준다.

    @RequestMapping(value = "/upload3.do", method = RequestMethod.POST)
    public String upload3(String title, @RequestParam(name="photo") List<MultipartFile> photo_list, Model model) throws IllegalStateException, IOException {

        String absPath = application.getRealPath("/images");

        List<String> filename_list = new ArrayList<String>();

        for(MultipartFile photo : photo_list) {
            if(!photo.isEmpty()) {
                String filename = photo.getOriginalFilename();

                File f = new File(absPath, filename);

                if(f.exists()) {
                    long tm = System.currentTimeMillis();
                    filename = String.format("%d_%s", tm, filename);
                    f = new File(absPath, filename);
                }

                photo.transferTo(f);

                filename_list.add(filename);
            }
        }// end:for

        model.addAttribute("title", title);
        model.addAttribute("filename_list", filename_list);
        
        return "result3";
    }

 

 

 

jsp로 출력해주면 끝

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    여기는 result3입니다.
    제목:${ title }<br>
    <c:forEach var="filename" items="${ filename_list }">
        이미지: <img src="images/${ filename }" width="300">
    </c:forEach>
    <br>
    <br>
    <a href="input3.html">다시해보자</a>
</body>
</html>

 

 

 

반응형

'SpringBoot↗' 카테고리의 다른 글

Spring Boot)Interceptor  (0) 2024.08.13
Spring Boot) AOP  (0) 2024.08.13
AWS 서버(프로젝트 업로드)  (0) 2024.08.13
Spring Boot)Transaction  (0) 2024.08.12
Spring Boot)JPA로 Sawon 데이터 활용하기  (0) 2024.08.12