JSP 파일 업로드

MINJU KIM·2023년 12월 12일

JSP

목록 보기
29/30
  1. 화면(폼)작성
  2. 데이터베이스 테이블 준비
  3. DTO/ DAO 작성
  4. 모두를 연동하여 파일 업로드 완성

작성폼

method 속성은 반드시 post로, enctype속성은 multipart/form-data로 지정해야한다.
enctype은 폼값을 서버로 전송할 때의 인코딩 방식을 지정하는 속성.

application/x-www-form-urlencoded 모든 문자를 서버로 전송하기 전에 인코딩한다. enctype의 기본값.
multipart/form-data 모든 문자를 인코딩하지 않는다. form 태그를 통해 파일을 서버로 전송할 때 주로 사용.
text/plain 공백 문자(space)만 "+" 기호로 변환하고, 나머지 문자는 인코딩하지않는다.
        <!-- https://mvnrepository.com/artifact/com.jfinal/cos -->
        <dependency>
            <groupId>com.jfinal</groupId>
            <artifactId>cos</artifactId>
            <version>2022.2</version>
        </dependency>

pom.xml에 라이브러리 추가.
추가하면 메이븐 새로고침을 꼭 해주자
컨트롤 쉬프트 F로 전에 작성한 validateForm을 찾아서 복사했다.

//FileUploadMain.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    function validateForm(form){
        if(!form.title.value){
            alert("제목을 입력 하세요");
            form.title.focus();
            return false;
        }
        if(!form.name.value){
            alert("작성자를 입력 하세요");
            form.name.focus();
            return false;
        }
        if(!form.attachedFile.value){
            alert("첨부파일은 필수입력하세요");
            return false;
        }
    }
</script>

</body>
<h2>파일 업로드</h2>
<span style="color: red">${errMsg}</span>
<form name="fileform" method="post" enctype="multipart/form-data" action="UploadProcess.jsp" onsubmit="return validateForm(this);">
    작성자 : <input type="text" name="name" value="머스트해브"/><br/>
    제목 : <input type="text" name="title"/><Br/>
    카테고리(선택사항) :
    <input type="checkbox" name="cate" value="사진" checked /> 사진
    <input type="checkbox" name="cate" value="과제" /> 과제
    <input type="checkbox" name="cate" value="워드" /> 워드
    <input type="checkbox" name="cate" value="음원" /> 음원 <br/>
    첨부파일: <input type="file" name="attachedFile" /><br/>
    <input type="submit" value="전송하기"/>

</form>
</html>


create table myfile (
    idx number primary key,
    title varchar2(200) not null,
    cate varchar2(100),
    ofile varchar2(100) not null,
    sfile varchar2(30) not null,
    postdate date default sysdate not null
);
//로 DB를 만들어준다. 

DTO DAO 만들기

java폴더 밑에 fileupload 경로를 만들어서
MYFileDAO, MYFileDTO.java를 만들어준다.

//MyFileDTO.java
package com.fileupload;

public class MyFileDTO {

    private String idx;
    private String title;
    private String cate;
    private String ofile;
    private String sfile;
    private String postdate;
    //getter setter 만들어주기

    public String getIdx() {
        return idx;
    }

    public void setIdx(String idx) {
        this.idx = idx;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCate() {
        return cate;
    }

    public void setCate(String cate) {
        this.cate = cate;
    }

    public String getOfile() {
        return ofile;
    }

    public void setOfile(String ofile) {
        this.ofile = ofile;
    }

    public String getSfile() {
        return sfile;
    }

    public void setSfile(String sfile) {
        this.sfile = sfile;
    }

    public String getPostdate() {
        return postdate;
    }

    public void setPostdate(String postdate) {
        this.postdate = postdate;
    }
}

//MyFileDAO.java
package com.fileupload;

import com.common.DBConnPool;

import java.util.ArrayList;
import java.util.List;

public class MyFileDAO extends DBConnPool {
    // CRUD
    // 게시글 작성
    public int insertFile(MyFileDTO dto) {
        int applyResult = 0;
        try {
            String query = "INSERT INTO myfile ("
                    + "idx, title, cate, ofile, sfile)"
                    + "VALUES (seq_board_num.nextval, ?,?,?,?)";
            psmt = con.prepareStatement(query);
            psmt.setString(1,dto.getTitle());
            psmt.setString(2,dto.getCate());
            psmt.setString(3,dto.getOfile());
            psmt.setString(4,dto.getSfile());

            applyResult = psmt.executeUpdate();

        } catch(Exception e) {
            System.out.println("insert 파일 오류 발생");
            e.printStackTrace();
        }
        return applyResult;
    }

    // 게시글 리스트 불러오기


    // 쿼리문
    public List<MyFileDTO> myFileList() {
        List<MyFileDTO> fileList = new ArrayList<>();
        String query = "SELECT * FROM myfile ORDER BY idx DESC";
        try {
            psmt = con.prepareStatement(query);
            rs = psmt.executeQuery();

            while(rs.next()) {
                MyFileDTO dto = new MyFileDTO();
                dto.setIdx(rs.getString("idx"));
                dto.setTitle(rs.getString("title"));
                dto.setCate(rs.getString("cate"));
                dto.setOfile(rs.getString("ofile"));
                dto.setSfile(rs.getString("sfile"));
                dto.setPostdate(rs.getString("postdate"));

                fileList.add(dto);
            }
        } catch(Exception e) {
            System.out.println("MyFileList 오류 발생");
            e.printStackTrace();
        }
        return fileList;
    }



    // 게시글 업데이트

    // 게시글 삭제
}
//UploadProcess.jsp
<%@ page import="com.oreilly.servlet.MultipartRequest" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.io.File" %>
<%@ page import="com.fileupload.MyFileDTO" %>
<%@ page import="com.fileupload.MyFileDAO" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
//저장할 디렉토리
    String saveDir = application.getRealPath("/upload");
    //업로드 폴더 어디인지 잘 보기
    //파일 최대크기(1MB)
    int maxSize = 1024 * 1000;

    //인코딩 방식
    String encoding = "UTF-8";

    try{
        //1. MultipartRequest 객체 생성
        MultipartRequest mr = new MultipartRequest((HttpServletRequest) request, saveDir, maxSize, encoding);

        //2. 새로운 파일명 생성
        String fileName = mr.getFilesystemName("attachedFile") ; //현재 파일 이름
        String ext = fileName.substring(fileName.lastIndexOf(".")); //파일 확장자
        String now = new SimpleDateFormat("yyyyMMdd_MmsS").format(new Date());
        String newFileName = now + ext; //새로운 파일 이름(업로드일시, 확장자)

        //3. 파일명 변경
        File oldFile = new File(saveDir + File.separator + fileName);
        File newFile = new File(saveDir + File.separator + newFileName);
        oldFile.renameTo(newFile);

        //4. 다른 폼 값 받기
        String title = mr.getParameter("title");
        String[] cateArr = mr.getParameterValues("cate");
        StringBuffer cateBuf = new StringBuffer();

        if(cateArr == null){
            cateBuf.append("선택없음");
        }else {
            for(String s : cateArr){
                cateBuf.append(s + ",");
            }
        }
        //5. DTO 생성
        MyFileDTO dto = new MyFileDTO();
        dto.setTitle(title);
        dto.setCate(cateBuf.toString());
        dto.setOfile(fileName);
        dto.setSfile(newFileName);

        //6. DAO 통해 DB에 입력
        MyFileDAO dao = new MyFileDAO();
        dao.insertFile(dto);
        dao.close();
        //7. 파일 목록 리다이렉션
        response.sendRedirect("FileList.jsp");
    }catch(Exception e){
        System.out.println("파일 업로드 오류");
        e.printStackTrace();
        request.setAttribute("effMsg", "파일 업로드 오류");
        request.getRequestDispatcher("FileUploadMain.jsp").forward(request, response);
    }

%>

//FileList.jsp
<%@ page import="com.fileupload.MyFileDAO" %>
<%@ page import="com.fileupload.MyFileDTO" %>
<%@ page import="java.util.List" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>FileUpload</title>
</head>
<body>
    <h2>DB에 등록된 파일보기</h2>
    <a href="FileUploadMain.jsp">파일 등록하기</a>
    <%
        MyFileDAO dao = new MyFileDAO();
        List<MyFileDTO> fileList = dao.myFileList();
        dao.close();

    %>

    <table border="1">
        <tr>
            <th>No</th>
            <th>제목</th>
            <th>카테고리</th>
            <th>원본 파일명</th>
            <th>저장된 파일명</th>
            <th>작성일</th>
            <th>다운로드</th>
        </tr>

            <%
            for (MyFileDTO f : fileList){
            %>
        <tr>
            <td><%=f.getIdx()%></td>
            <td><%=f.getTitle()%></td>
            <td><%=f.getCate()%></td>
            <td><%=f.getOfile()%></td>
            <td><%=f.getSfile()%></td>
            <td><%=f.getPostdate()%></td>
            <td>
                <a href="Download.jsp?oName=<%=URLEncoder.encode(f.getOfile(), "UTF-8")%>
&sName=<%=URLEncoder.encode(f.getSfile(), "UTF-8")%>">[다운로드]</a>
            </td>
        </tr>


            <%
            }
            %>

    </table>
</body>
</html>
//Download.jsp
<%@ page import="com.util.JSFunction" %>
<%@ page import="java.io.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%
    String saveDir = application.getRealPath("/upload");
    String saveFilename = request.getParameter("sName");
    String originalFileName = request.getParameter("oName");

    try {
        // 파일을 찾아 입력 스트림 생성
        File file = new File(saveDir, saveFilename);
        InputStream inStream = new FileInputStream(file);

        String client = request.getHeader("User-Agent");
        if(client.indexOf("W0W64") == -1) { // 익스플로러가 아닌 경우
            originalFileName = new String(originalFileName.getBytes("UTF-8"),"ISO-8859-1");
        } else { // 익스플로러인 경우
            originalFileName = new String(originalFileName.getBytes("KSC5601"),"ISO-8859-1");
        }
        // 파일 다운로드용 응답 헤더 설정
        response.reset();
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition","attachment; filename=\"" + originalFileName + "\"");
        response.setHeader("Content-Length","" + file.length());

        // 출력 스트림 초기화
        out.clear();

        // response 내장 객체로부터 새로운 출력 스트림 생성
        OutputStream outStream = response.getOutputStream();

        // 출력 스트림에 파일 내용 출력
        byte[] b = new byte[(int)file.length()];
        int readBuffer = 0;
        while((readBuffer = inStream.read(b)) > 0) {
            outStream.write(b,0,readBuffer);
        }
        // 입출력 스트림 닫음
        inStream.close();
        outStream.close();

    }
    catch (FileNotFoundException e) {
        JSFunction.alertBack("파일을 찾을 수 없습니다.",out);
    } catch(Exception e) {
        JSFunction.alertBack("예외가 발생 했습니다.",out);
    }
%>

0개의 댓글