본문 바로가기
Java/Servlet & JSP

JSP) 첨부파일 있는 게시글 수정

by 박채니 2022. 7. 5.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


첨부파일 있는 게시글 수정

 

boardUpdate.jsp

<%@page import="com.ce.mvc2.board.model.dto.BoardExt"%>
<%@page import="com.ce.mvc2.board.model.dto.Attachment"%>
<%@page import="java.util.List"%>
<%@page import="com.ce.mvc2.board.model.dto.Board"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/common/header.jsp" %>    
<%
	Board board = (Board)request.getAttribute("board");
	List<Attachment> attachments = ((BoardExt) board).getAttachments();
%>
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/board.css" />

<section id="board-container">
<h2>게시판 수정</h2>
<form name="boardUpdateFrm" action="<%=request.getContextPath() %>/board/boardUpdate" method="post" enctype="multipart/form-data">
	<input type="hidden" name="no" value="<%= board.getNo() %>" />
	<table id="tbl-board-view">
	<tr>
		<th>제 목</th>
		<td><input type="text" name="title" value="<%= board.getTitle().replace("\"", "&quot;") %>" required></td>
	</tr>
	<tr>
		<th>작성자</th>
		<td>
			<input type="text" name="writer" value="<%= board.getWriter() %>" readonly/>
		</td>
	</tr>
	<tr>
		<th>첨부파일</th>
		<td>
		<% if(attachments != null && !attachments.isEmpty()) {
			for(int i = 0; i < attachments.size(); i++) {
				Attachment attach = attachments.get(i);
		%>
				<img src="<%= request.getContextPath() %>/images/file.png" width="16px"/>
				<%= attach.getOriginalFilename() %>
				<input type="checkbox" name="delFile" id="delFile<%=i %>" value="<%= attach.getNo()%>"/>
				<label for="delFile<%=i%>">삭제</label>
				<br />
		<% 	}
		} %>
			<input type="file" name="upFile1">
			<input type="file" name="upFile2">
		</td>
	</tr>
	<tr>
		<th>내 용</th>
		<td><textarea rows="5" cols="40" name="content"><%= board.getContent() %></textarea></td>
	</tr>
	<tr>
		<th colspan="2">
			<input type="submit" value="수정하기"/>
			<input type="button" value="취소" onclick="history.go(-1);"/>
		</th>
	</tr>
</table>
</form>
</section>
<script>
document.boardUpdateFrm.onsubmit = (e) => {
	const frm = e.target;
	//제목을 작성하지 않은 경우 폼제출할 수 없음.
	const titleVal = frm.title.value.trim(); // 좌우공백
	if(!/^.+$/.test(titleVal)){
		alert("제목을 작성해주세요.");
		frm.title.select();
		return false;
	}		
					   
	//내용을 작성하지 않은 경우 폼제출할 수 없음.
	const contentVal = frm.content.value.trim();
	if(!/^(.|\n)+$/.test(contentVal)){
		alert("내용을 작성해주세요.");
		frm.content.select();
		return false;
	}
}
</script>
<%@ include file="/WEB-INF/views/common/footer.jsp" %>

input 태그 file속성은 사용자의 컴퓨터에 접근 가능하므로, 보안적인 위협이 될 수 있기에 value 속성을 조작할 수 없습니다.

value = "flower.jpg"를 해도 브라우저상으로는 화면 되지 않습니다.

 

따라서, 기존 파일명을 보여주고 삭제 여부를 체크하고 input:file은 새로운 파일 등록용으로 사용하는 방법을 이용하여 첨부파일 삭제/추가 기능을 구현하였습니다.

 

Controller

BoardUpdateServlet

@WebServlet("/board/boardUpdate")
public class BoardUpdateServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private BoardService boardService = new BoardService();
	
	/**
	 * GET 수정폼요청
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			int no = Integer.parseInt(request.getParameter("no"));
			Board board = boardService.findByNo(no);
			request.setAttribute("board", board);
			request.getRequestDispatcher("/WEB-INF/views/board/boardUpdate.jsp").forward(request, response);
		} catch(Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * POST db update 요청
	 * - 파일업로드 가능성있음
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			// 첨부파일 처리
			// saveDirectory, maxPostSize, encoding, policy
			ServletContext application = getServletContext();
			String saveDirectory = application.getRealPath("/upload/board");
			int maxPostSize = 1024 * 1024 * 10; // 10MB
			String encoding = "utf-8";
			FileRenamePolicy policy = new HelloMvcFileRenamePolicy();
			MultipartRequest multiReq = new MultipartRequest(request, saveDirectory, maxPostSize, encoding, policy);
			
			// 삭제파일 처리
			String[] delFiles = multiReq.getParameterValues("delFile");
			if(delFiles != null) {
				for(String value : delFiles) {
					int attachNo = Integer.parseInt(value);
					// 첨부파일 삭제
					Attachment attach = boardService.findAttachmentByNo(attachNo);
					File delFile = new File(saveDirectory, attach.getRenamedFilename());
					delFile.delete();
					
					// db 레코드 삭제
					int result = boardService.deleteAttachment(attachNo);
				}
			}
			
			// 사용자 입력값 처리
			int no = Integer.parseInt(multiReq.getParameter("no"));
			String title = multiReq.getParameter("title");
			String writer = multiReq.getParameter("writer");
			String content = multiReq.getParameter("content");
			BoardExt board = new BoardExt(no, title, writer, content, 0, null);
			
			Enumeration<String> filenames = multiReq.getFileNames();
			while(filenames.hasMoreElements()) {
				String filename = filenames.nextElement();
				File upFile = multiReq.getFile(filename);
				
				if(upFile != null) {
					Attachment attach = new Attachment();
					attach.setBoardNo(no);
					attach.setOriginalFilename(multiReq.getOriginalFileName(filename));
					attach.setRenamedFilename(multiReq.getFilesystemName(filename));
					board.addAttachment(attach);
				}
			}
			
			// 업무로직
			int result = boardService.updateBoard(board);
			
			// redirect 처리
			request.getSession().setAttribute("msg", "게시글을 성공적으로 수정하였습니다.");
			response.sendRedirect(request.getContextPath() + "/board/boardView?no=" + no);
		} catch(Exception e) {
			e.printStackTrace();
			throw e;
		}
	}
}

delFile로 가져와 String 배열에 담아주었고, value값 (attachNo)을 이용하여 attachment 객체를 리턴 받은 후 서버 컴퓨터의 파일 삭제, DB 레코드 삭제처리 하였습니다.

 

Service

BoardService

public int deleteAttachment(int attachNo) {
    Connection conn = getConnection();
    int result = 0;
    try {
        result = boardDao.deleteAttachment(conn, attachNo);
        commit(conn);
    } catch(Exception e) {
        rollback(conn);
        throw e;
    } finally {
        close(conn);
    }
    return result;
}

 

Dao

BoardDao

// deleteAttachment = delete from attachment where no = ?
public int deleteAttachment(Connection conn, int attachNo) {
    PreparedStatement pstmt = null;
    int result = 0;
    String sql = prop.getProperty("deleteAttachment");

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setInt(1, attachNo);
        result = pstmt.executeUpdate();
    } catch (SQLException e) {
        throw new BoardException("첨부파일 삭제 오류!", e);
    } finally {
        close(pstmt);
    }
    return result;
}

 

 

244 첨부파일 삭제 / 새로운 첨부파일 2개 추가

 

서버 컴퓨터와 DB레코드 모두 잘 삭제 된 것을 확인할 수 있습니다.