2022.10.04

Jimin·2022년 10월 4일
0

비트캠프

목록 보기
50/60
post-thumbnail
  • 서블릿 프로그래밍
    • Servlet 3.0 에 추가된 API를 사용하여 파일 업로드를 처리하는 방법
  • board-app 프로젝트 수행
      1. 파일을 업로드하기: multipart/form-data MIME 타입(계속)
      1. 파일을 업로드하기 II: Servler API로 파일업로드 처리하기

069. 파일을 업로드하기:
multipart/form-data MIME 타입

3단계 - 멀티 방식 형식으로 업로드된 게시글의 입력을 처리한다.

  • com.bitcamp.board.controller.BoardUpdateController 클래스 변경
  • com.bitcamp.board.controller.MariaDBBoardDao 클래스 변경
    • insert()

4단계 - 게시글을 조회할 때 첨부파일 목록을 출력한다.

  • com.bitcamp.board.controller.MariaDBBoardDao 클래스 변경
    • findByNo() 변경
  • /webapp/board/detial.jsp 변경

5단계 - 첨부파일 삭제 기능을 추가한다.

  • /webapp/board/detial.jsp 변경
  • com.bitcamp.board.controller.BoardFileDeleteController 클래스 생성
  • com.bitcamp.board.dao.BoardDao 인터페이스 변경
    • findFileByNo(), deleteFile() 추가
  • com.bitcamp.board.dao.MariaDBBoardDao 클래스 변경
    • findFileByNo(), deleteFile() 구현
@Override
    public int deleteFile(int fileNo) throws Exception {
        try (PreparedStatement pstmt = con.prepareStatement(
                "delete from app_board_file where bfno=?")) {

            pstmt.setInt(1, fileNo);
            return pstmt.executeUpdate();
        }
    }

    @Override
    public int deleteFiles(int boardNo) throws Exception {
        try (PreparedStatement pstmt = con.prepareStatement(
                "delete from app_board_file where bno=?")) {

            pstmt.setInt(1, boardNo);
            return pstmt.executeUpdate();
        }
    }

6단계 - 게시글을 변경할 때 첨부파일을 추가할 수 있게 만든다.

  • /webapp/board/detial.jsp 변경
  • com.bitcamp.board.controller.BoardFileDeleteController 클래스 변경
  • com.bitcamp.board.dao.MariaDBBoardDao 클래스 변경
    • insertFiles() 추가
    • update(), insert() 변경
  • detial.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>bitcamp</title>
</head>
<body>
<h1>게시글 상세 정보(JSP + Servlet + EL)</h1>
<form action='update' method="post" enctype="multipart/form-data">
<table border='1'>
  <tr>
    <th>번호</th><td><input name='no' type='number' value='${board.no}' readonly></td>
  </tr>
  <tr>
    <th>제목</th><td><input name='title' type='text' value='${board.title}' size='60'></td>
  </tr>
  <tr>
    <th>내용</th><td><textarea name='content' rows='10' cols='60'>${board.content}</textarea></td>
  </tr>
  <tr>
    <th>조회수</th><td>${board.viewCount}</td>
  </tr>
  <tr>
    <th>작성자</th><td>${board.writer.name}</td>
  </tr>
  <tr>
    <th>등록일</th><td>${board.createdDate}</td>
  </tr>
  <tr>
    <th>첨부파일</th>
    <td>
      <ul>
      <c:forEach items="${board.attachedFiles}" var="file">
        <li>
          <a href="files/${file.filepath}">${file.filepath}</a>
          [<a href="fileDelete?no=${file.no}">삭제</a>]
        </li>
      </c:forEach>
      </ul>
      파일 추가: <input name='files' type="file" multiple>
    </td>
  </tr>
</table>
<p>
  <button type='submit'>변경</button>
  <a href='delete?no=${board.no}'>삭제</a>
  <a href='list'>목록</a>
</p>
</form>
</body>
</html>
  • MariaDBBoardDao class
  • insertFiles()
 public int insertFiles(Board board) throws Exception {
        try (PreparedStatement pstmt = con.prepareStatement(
                "insert into app_board_file(filepath,bno) values(?,?)")) {

            List<AttachedFile> attachedFiles = board.getAttachedFiles();
            for (AttachedFile attachedFile : attachedFiles) {
                pstmt.setString(1, attachedFile.getFilepath());
                pstmt.setInt(2, board.getNo());
                pstmt.executeUpdate();
            }
            return attachedFiles.size();
        }
    }
  • update()
public int update(Board board) throws Exception {
        try (PreparedStatement pstmt = con.prepareStatement(
                "update app_board set title=?, content=? where bno=?")) {

            pstmt.setString(1, board.getTitle());
            pstmt.setString(2, board.getContent());
            pstmt.setInt(3, board.getNo());

            int count = pstmt.executeUpdate();

            // 게시글을 변경했다면 첨부 파일 이름을 추가한다.
            if (count > 0) {
                insertFiles(board);
            }

            return count;
        }
    }
  • insert()
public int insert(Board board) throws Exception {
        try (
                PreparedStatement pstmt = con.prepareStatement(
                        "insert into app_board(title,content,mno) values(?,?,?)",
                        Statement.RETURN_GENERATED_KEYS)) {

            // 게시글 제목과 내용을 app_board 테이블에 저장한다.
            pstmt.setString(1, board.getTitle());
            pstmt.setString(2, board.getContent());
            pstmt.setInt(3, board.getWriter().getNo());
            int count = pstmt.executeUpdate();

            // 게시글을 app_board 테이블에 입력 한 후 자동 증가된 PK 값을 꺼낸다.
            try (ResultSet rs = pstmt.getGeneratedKeys()) {
                rs.next();
                board.setNo(rs.getInt(1));
            }

            insertFiles(board);

            return count;
        }
    }

DAO와 테이블

방법1

방법2

결론

7단계 - 게시글을 삭제할 때 첨부파일도 함께 삭제한다.

  • com.bitcamp.board.dao.BoardDao 인터페이스 변경
    • deleteFiles() 추가
  • com.bitcamp.board.dao.MariaDBBoardDao 클래스 변경
    • deleteFiles() 구현
    • delete() 변경

070. 파일을 업로드하기 2:
Servlet API로 파일 업로드 처리하기

  • Servlet에서 제공하는 API(3.0부터 추가됨)를 사용하여 파일 업로드를 처리하는 방법

1단계 - Apache commons-fileupload 대신 Servlet API로 대체한다.

  • com.bitcamp.board.controller.BoardAddController 클래스 변경

  • com.bitcamp.board.controller.BoardUpdateController 클래스 변경

  • BoardAddController class

// Servlet API에서 제공하는 multipart/form-data 처리기를 사용하려면
// 서블릿에 다음 애노테이션으로 설정해야 한다.
@MultipartConfig(maxFileSize = 1024 * 1024 * 10) // 최대 10M까지 업로드 허용
@WebServlet("/board/add")
public class BoardAddController extends HttpServlet {
  private static final long serialVersionUID = 1L;

  BoardDao boardDao;

  @Override
  public void init() {
    boardDao = (BoardDao) this.getServletContext().getAttribute("boardDao");
  }

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    try {
      request.setCharacterEncoding("UTF-8");

      Board board = new Board();
      board.setTitle(request.getParameter("title"));
      board.setContent(request.getParameter("content"));

      // 첨부파일명을 저장할 컬렉션 객체 준비
      List<AttachedFile> attachedFiles = new ArrayList<>();

      // 임시 폴더에 저장된 첨부 파일을 옮길 폴더 경로 알아내기
      String dirPath = this.getServletContext().getRealPath("/board/files");

      Collection<Part> parts = request.getParts();

      for(Part part:parts) {
        if(!part.getName().equals("files")) {
          continue;
        }

        String filename = UUID.randomUUID().toString();
        part.write(dirPath + "/" + filename);
        attachedFiles.add(new AttachedFile(filename));
      }

      // Board 객체에서 파일명 목록을 담고 있는 컬렉션 객체를 저장한다.
      board.setAttachedFiles(attachedFiles);

      // Board 객체에 로그인 사용자 정보를 저장한다.
      Member loginMember = (Member) request.getSession().getAttribute("loginMember");
      board.setWriter(loginMember);

      if (boardDao.insert(board) == 0) {
        throw new Exception("게시글 등록 실패!");
      }

      response.sendRedirect("list");

    } catch (Exception e) {
      request.setAttribute("exception", e);
      request.getRequestDispatcher("/error.jsp").forward(request, response);
    }
  }
}
profile
https://github.com/Dingadung

0개의 댓글