본문 바로가기
학습/JSP

30. 파일 업로드(제이쿼리 사용)

by Elfen Lied 2022. 12. 1.
반응형

- 작업순서

  1. 데이터 베이스(테이블, 테스트 데이터)
  2. VO 클래스
  3. DAO 클래스
  4. Service 클래스
  5. Controller 클래스
  6. view page

- sql

DROP TABLE BOARD_TBL;

CREATE TABLE BOARD_TBL(
    BNO NUMBER(10) PRIMARY KEY,
    TITLE VARCHAR2(500) NOT NULL,
    CONTENT VARCHAR2(4000) NOT NULL,
    WRITER VARCHAR2(100) NOT NULL,
    imageFileName VARCHAR2(100),
    WRITEDATE DATE DEFAULT SYSDATE
);

INSERT INTO BOARD_TBL(BNO, TITLE, CONTENT, WRITER)
VALUES (1, '제목임1', '내용임1', '관리자1');
INSERT INTO BOARD_TBL(BNO, TITLE, CONTENT, WRITER)
VALUES (2, '제목임2', '내용임2', '관리자2');
INSERT INTO BOARD_TBL(BNO, TITLE, CONTENT, WRITER)
VALUES (3, '제목임3', '내용임3', '관리자3');
INSERT INTO BOARD_TBL(BNO, TITLE, CONTENT, WRITER)
VALUES (4, '제목임4', '내용임4', '관리자4');

COMMIT;

SELECT * FROM BOARD_TBL;

-- SELECT MAX(BNO)+1 AS baordNo FROM BOARD_TBL;

 

maven 프로젝트로 변경

- pom.xml

  <dependencies>
  
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.24</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<dependency>
			<groupId>com.oracle.database.jdbc</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>11.2.0.4</version>
		</dependency>

		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-dbcp</artifactId>
			<version>10.1.2</version>
		</dependency>
		
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.4</version>
		</dependency>

		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.11.0</version>
		</dependency>

	</dependencies>

 

 

 

 

- package 트리

- common 패키지 ConnectionUtil 클래스, EncodingFilter 필터 생성

 

- EncodingFilter

package com.common;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;

@WebFilter("/*")
public class EncodingFilter extends HttpFilter implements Filter {
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		request.setCharacterEncoding("utf-8");
		chain.doFilter(request, response);
	}
}

 

ConnectionUtil 

package com.common;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class ConnectionUtil {
	
	private static final String RESOURCE = "java:/comp/env"; 
	private static final String RESOURCE_NAME = "jdbc/oracle";  
	
	public static DataSource getDatasource() {
		DataSource dataSource = null;
		try {
			Context ctx = new InitialContext();
			Context envCtx = (Context) ctx.lookup(RESOURCE);
			dataSource = (DataSource) envCtx.lookup(RESOURCE_NAME);
		} catch (NamingException e) {
			e.printStackTrace();
		}
		return dataSource;
	}
}

 

- FileDownload 서블릿

package com.common;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/fileDownload")
public class FileDownload extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}

	private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String fileRepo = "c:/file_repo";
		String bno = request.getParameter("bno");
		String fileName = request.getParameter("imageFileName");
		File downloadFile = new File(fileRepo + "/" + bno, fileName);
	
		fileName = URLEncoder.encode(fileName, "utf-8");
		response.setHeader("Cache-Control", "no-cache");
		response.addHeader("Content-disposition", "attachment; fileName=" + URLEncoder.encode(fileName, "utf-8"));
		
		try (
			OutputStream out = response.getOutputStream(); 
			InputStream in = new FileInputStream(downloadFile);
		){
			
			byte[] buffer = new byte[1024*8];
			int count = 0;
			while ((count = in.read(buffer)) != -1) {
				out.write(buffer, 0, count);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

 

- domain 패키지에 BoardVO 생성

 

- BoardVO

package com.domain;

import java.util.Date;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class BoardVO {
	private int bno;
	private String title;
	private String content;
	private String writer;
	private String imageFileName;
	private Date writeDate;
}

 

 

 

- controller 패키지 BoardController 서블릿 생성

 

- BoardController

package com.controller;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;

import com.dao.BoardDao;
import com.domain.BoardVO;
import com.service.BoardService;

@WebServlet("/board/*")
public class BoardController extends HttpServlet {
	
	private BoardService service;
	
	@Override
	public void init() throws ServletException {
		BoardDao dao = new BoardDao();
		service = new BoardService(dao);
	}
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String pathInfo = request.getPathInfo();
		String contextPath = request.getContextPath();
		final String PREFIX = "/WEB-INF/views/board/";
		final String SUFFIX = ".jsp";
		
		RequestDispatcher rd = null;
		String nextPage = null;
		
		if(pathInfo == null || pathInfo.equals("/") || pathInfo.equals("/list")) { // 글 목록
			List<BoardVO> boardList = service.boardList();
			request.setAttribute("list", boardList);
			nextPage = "list";
			
		} else if(pathInfo.equals("/detail")) { // 글 상세
			String paramBno = request.getParameter("bno");
			int bno = Integer.parseInt(paramBno);
			BoardVO board = service.findBoard(bno);
			request.setAttribute("board", board);
			nextPage = "detail";
		} else if(pathInfo.equals("/writeForm")) { // 글 쓰기 폼
			nextPage = "writeForm";
		} else if(pathInfo.equals("/write")) { // 글 쓰기 처리
			Map<String, String> req = getMultipartRequest(request);
			String imageFileName = req.get("imageFileName");
			
			BoardVO vo = BoardVO.builder()
						.title(req.get("title"))
						.content(req.get("content"))
						.writer(req.get("writer"))
						.imageFileName(req.get("imageFileName"))
						.build();
			int boardNo = service.addBoard(vo);
			
			// 이미지 파일을 첨부한 경우
			if(imageFileName != null && imageFileName.length() > 0) {
				File srcFile = new File("c:/file_repo/temp", imageFileName);
				File destFile = new File("c:/file_repo/" + boardNo);
				destFile.mkdirs();
				FileUtils.moveFileToDirectory(srcFile, destFile, false);
			}
			
			response.sendRedirect(contextPath + "/board");
			return;
		} else if(pathInfo.equals("/modBoard")) { // 글 수정 처리
			Map<String, String> req = getMultipartRequest(request);
			String paramBno = req.get("bno");
			int bno = Integer.parseInt(paramBno);
			String title = req.get("title");
			String content = req.get("content");
			String imageFileName = req.get("imageFileName");
			
			BoardVO vo = BoardVO.builder()
					.bno(bno)
					.title(title)
					.content(content)
					.imageFileName(imageFileName).build();
			service.modBoard(vo);
			
			if(imageFileName != null) { // 이미지 파일이 있을 때
				String originFileName = req.get("originFileName");
				// 새로운 이미지 업로드
				File srcFile = new File("c:/file_repo/temp", imageFileName);
				File destFile = new File("c:/file_repo/" + bno);
				destFile.mkdirs();
				FileUtils.moveFileToDirectory(srcFile, destFile, false);
				// 기존 이미지 삭제
				if(originFileName != null) {
					File oldFile = new File("c:/file_repo/" + bno + "/" + originFileName);
					oldFile.delete();
				}
			}
			response.sendRedirect(contextPath + "/board");
			return;
		} else if(pathInfo.equals("/removeBoard")) { // 삭제처리
			Map<String, String> req = getMultipartRequest(request);
			String paramBno = req.get("bno");
			int bno = Integer.parseInt(paramBno);
			service.removeBoard(bno);
			File targetDir = new File("c:/file_repo/" + bno);
			if(targetDir.exists()) { // 대상 폴더가 존재한다면..
				FileUtils.deleteDirectory(targetDir);
			}
			response.sendRedirect(contextPath + "/board");
			return;
		}
		
		
		else {
			System.out.println("없는 페이지");
		}
		rd = request.getRequestDispatcher(PREFIX + nextPage + SUFFIX);
		rd.forward(request, response);
	}
	
	private Map<String, String> getMultipartRequest(HttpServletRequest request) {
		Map<String, String> boardMap = new HashMap<>();
		File currentDirPath = new File("c:/file_repo/temp");
		
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload repository = new ServletFileUpload(factory);
		repository.setFileSizeMax(1024 * 1024 * 10);
		
		try {
			List<FileItem> items = repository.parseRequest(request);
			for(FileItem item : items) {
				if(item.isFormField()) { // 파일이 아니면
					boardMap.put(item.getFieldName(), item.getString("utf-8"));
				} else { // 파일이면
					if(item.getSize() > 0) {
						String fileName = item.getName(); // 파일이름
						boardMap.put(item.getFieldName(), fileName);
						File uploadFile = new File(currentDirPath, fileName);
						item.write(uploadFile);
					}
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return boardMap;
	}
}

 

 

- service 패키지 BoardService 생성

 

- BoardService

package com.service;

import java.util.List;

import com.dao.BoardDao;
import com.domain.BoardVO;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class BoardService {

	private BoardDao dao;

	public List<BoardVO> boardList() {
		return dao.selectAll();
	}
	
	public BoardVO findBoard(int bno) {
		return dao.selectOne(bno);
		
	}

	public int addBoard(BoardVO vo) {
		return dao.insertBoard(vo);
	}
	
	public void modBoard(BoardVO vo) {
		dao.updateBoard(vo);
	}
	
	public void removeBoard(int bno) {
		dao.deleteBoard(bno);
	}
}

 

 

- dao 패키지 BoardDao 생성

 

- BoardDao

package com.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import com.common.ConnectionUtil;
import com.domain.BoardVO;

public class BoardDao {
	
	private DataSource dataSource;
	
	public BoardDao() {
		dataSource = ConnectionUtil.getDatasource();
	}

	// 글 목록
	public List<BoardVO> selectAll() {
		List<BoardVO> list = new ArrayList<>();
		String query = "SELECT * FROM board_tbl ORDER BY bno DESC";
		try (
			Connection conn = dataSource.getConnection();
			PreparedStatement pstmt = conn.prepareStatement(query);
			ResultSet rs = pstmt.executeQuery();
		){
			while (rs.next()) {
				BoardVO vo = BoardVO.builder()
						.bno(rs.getInt("bno"))
						.title(rs.getString("title"))
						.content(rs.getString("content"))
						.writer(rs.getString("writer"))
						.imageFileName(rs.getString("imageFileName"))
						.writeDate(rs.getDate("writeDate")).build();
				list.add(vo);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
	
	// 글 상세
	public BoardVO selectOne(int bno) {
		BoardVO vo = null;
		String query = "SELECT * FROM board_tbl WHERE bno=?";
		try (
			Connection conn = dataSource.getConnection();
			PreparedStatement pstmt = conn.prepareStatement(query);
		){
			pstmt.setInt(1, bno);
			try (ResultSet rs = pstmt.executeQuery();){
				if(rs.next()) {
					vo = BoardVO.builder()
							.bno(rs.getInt("bno"))
							.title(rs.getString("title"))
							.content(rs.getString("content"))
							.writer(rs.getString("writer"))
							.imageFileName(rs.getString("imageFileName"))
							.writeDate(rs.getDate("writeDate")).build();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return vo;
	}
	
	// 새로운 글번호 생성
		public int getNewBno() {
			int boardNo = 0;
			String query = "SELECT MAX(bno)+1 AS boardNo FROM board_tbl";
			try (
				Connection conn = dataSource.getConnection();
				PreparedStatement pstmt = conn.prepareStatement(query);
				ResultSet rs = pstmt.executeQuery();
			){
				if(rs.next()) {
					boardNo = rs.getInt("boardNo");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return boardNo;
		}

	// 글 쓰기
	public int insertBoard(BoardVO vo) {
		String query = "INSERT INTO board_tbl(bno, title, content, writer, imageFileName) VALUES(?, ?, ?, ?, ?)";
		int boardNo = getNewBno();
		try (
			Connection conn = dataSource.getConnection();
			PreparedStatement pstmt = conn.prepareStatement(query);
		){
			pstmt.setInt(1, boardNo);
			pstmt.setString(2, vo.getTitle());
			pstmt.setString(3, vo.getContent());
			pstmt.setString(4, vo.getWriter());
			pstmt.setString(5, vo.getImageFileName());
			pstmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return boardNo;
	}

	// 글 수정
	public void updateBoard(BoardVO vo) {
		String imageFileName = vo.getImageFileName();
		int bno = vo.getBno();
		String query = "UPDATE board_tbl SET title=?, content=?";
		
		if(imageFileName != null) { // 이미지 파일이 있을 때 
			query += ", imageFileName=? where bno=?";
		} else { // 이미지 파일이 없을 때
			query += " where bno=?";
		}
		try (
			Connection conn = dataSource.getConnection();
			PreparedStatement pstmt = conn.prepareStatement(query);
		){
			pstmt.setString(1, vo.getTitle());
			pstmt.setString(2, vo.getContent());
			if(imageFileName != null) { // 이미지 파일이 있을 때 
				pstmt.setString(3, imageFileName);
				pstmt.setInt(4, bno);
			} else { // 이미지 파일이 없을 때
				pstmt.setInt(3, bno);
			}
			pstmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	// 삭제 처리
	public void deleteBoard(int bno) {
		String query = "delete from board_tbl where bno=?";
		try (
			Connection conn = dataSource.getConnection();
			PreparedStatement pstmt = conn.prepareStatement(query);
		){
			pstmt.setInt(1, bno);
			pstmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
				
	}
}

 

 

 

- jsp 파일 트리

 

- webapp / WEB-INF / views / board / list.jsp, detail.jsp

 

- list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ include file="../layout/header.jsp"%>

<h1>게시물 목록</h1>
<div class="container my-3">
	<form id="listForm">
		<table class="table">
			<tr>
				<th>번호</th>
				<th>제목</th>
				<th>내용</th>
				<th>작성자</th>
				<th>파일명</th>
				<th>작성일</th>
			</tr>
		<c:forEach items="${list }" var="b">
			<tr>
				<td>${b.bno}</td>
				<td><a href="${b.bno}" class="title">${b.title}</a></td>
				<td>${b.content}</td>
				<td>${b.writer}</td>
				<td>${b.imageFileName }</td>
				<td>${b.writeDate }</td>
			</tr>
		</c:forEach>
		</table>
	</form>
	<a href="${contextPath}/board/writeForm" class="btn btn-primary">글쓰기로</a>
</div>
	
<%@ include file="../layout/footer.jsp"%>

<script>
	$(function() {
		let listForm = $('#listForm');
		$('.title').on('click', function(e){
			e.preventDefault();
			// let bnoData = "<input type='hidden' name='bno' value='"+$(this).data('bno')+"'/>";
			let bnoData = "<input type='hidden' name='bno' value='"+$(this).attr('href')+"'/>";
			listForm.append(bnoData)
					.attr('action', '${contextPath}/board/detail')
					.submit();
		});
	});
</script>

 

 

- detail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ include file="../layout/header.jsp"%>

<div class="container">
	<div class="jumbotron my-3">
		<h1>게시글조회</h1>
	</div>
	<form id="viewForm" enctype="multipart/form-data">
		<table class="table">
			<tr>
				<th>글번호</th>
				<td>${board.bno }
					<input type="hidden" name="bno" value="${board.bno}">
				</td>
				<th>조회수</th>
				<td>000</td>
			</tr>
			<tr>
				<th>작성자</th>
				<td>${board.writer}</td>
				<th>조회수</th>
				<td>${board.writeDate }</td>
			</tr>
			<tr>
				<th>제목</th>
				<td colspan="3">
					<input type="text" name="title" class="form-control" value="${board.title }" readonly="readonly">
				</td>
			</tr>
			<tr>
				<th>내용</th>
				<td colspan="3"><textarea rows="10" name="content" class="form-control" readonly="readonly">${board.content}</textarea></td>
			</tr>
			<tr>
				<th>첨부이미지</th>
				<td colspan="3">
					<input type="file" name="imageFileName" class="form-control viewMode">
					<div class="my-2">
						<c:if test="${not empty board.imageFileName }">
							<input type="hidden" name="originFileName" value="${board.imageFileName}">
							<div class="preview">
								<img class="originImg" src="${contextPath }/fileDownload?bno=${board.bno}&imageFileName=${board.imageFileName}" width="300px">
							</div>
						</c:if>
						<c:if test="${empty board.imageFileName }">
							<div class="preview">
								<p>등록된 이미지 없음</p>
							</div>
						</c:if>
					</div>
				</td>
			</tr>
			<tr>
				<td colspan="4">
					<button type="button" class="btn btn-info toModForm">수정하기</button>
					<button type="button" class="btn btn-danger remove">삭제</button>
					<button type="button" class="btn btn-secondary toList">목록</button>
				</td>
			</tr>
			<tr class="viewMode">
				<td colspan="4">
					<button type="button" class="btn btn-info modify">수정</button>
					<button type="button" class="btn btn-danger backViewMode">취소</button>
				</td>
			</tr>
			
		</table>
	</form>
</div>

<%@ include file="../layout/footer.jsp"%>

<script>
	$(function() {
		$('.viewMode').hide(); // 파일폼 숨김 / 수정, 취소 버튼 숨김

		let viewForm = $('#viewForm');
		let titleObj = $('input[name="title"]');
		let contentObj = $('textarea[name="content"]');
		let imageFile = "${board.imageFileName}";
		let pTag = $('.preview p').html;
		
		let originImg = $('.originImg').clone();
		let titleVal = titleObj.val();
		let contentVal = contentObj.val();
		
		$('.toModForm').on('click', function() {
			$('input[name="title"], textarea[name="content"]').attr("readonly", false);
			$('.viewMode').show(); // 파일폼 나타내기
			$(this).closest('tr').hide();
		});
		
		// 뷰모드
		$('.backViewMode').on('click', function() {
			$('input[name="title"], textarea[name="content"]').attr("readonly", true);
			$('.viewMode').hide(); // 파일폼 나타내기
			$(this).closest('tr').prev().show();
			$('.preview').html(originImg); // 수정전 이미지 복원
			$('input[type="file"]').val(''); // 파일폼 초기화
			titleObj.val(titleVal); // 수정전 제목 복원
			contentObj.val(contentVal); // 수정전 내용 복원
			if(imageFile == '' || imageFile == null) {
				$('.preview').html(pTag);
			}
		});
		
		// 목록으로
		$('.toList').on('click', function() {
			viewForm.attr({
				'action' : '${contextPath}/board',
				'method' : 'get'
			}).empty().submit(); // empty() 파라미터 정보 삭제
		});
		
		// 수정 처리
		$('.modify').on('click', function() {
			viewForm.attr({
				'action' : '${contextPath}/board/modBoard',
				'method' : 'post'
			}).submit();
		});
		
		// 삭제 처리
		$('.remove').on('click', function() {
			viewForm.attr({
				'action' : '${contextPath}/board/removeBoard',
				'method' : 'post'
			}).submit();
		});

		$('input[type="file"]').on('change', function(){
			if(this.files[0]) {
				let reader = new FileReader(); // 파일읽기 객체
				reader.onload = function(e) { // 파일을 읽으면 이벤트 발생
					let value = e.target.result;
					if(value.startsWith("data:image/")) {
						let imgTag = "<img src='"+value+"' width='200px'>";
						$('.preview').html(imgTag);
					} else { // 이미지 파일이 아닌 경우
						alert('이미지 파일만 등록됩니다.');
						$('input[name="imageFileName"]').val('');
						$('.preview').html('');	
					}
				}
				reader.readAsDataURL(this.files[0]); // 파일 읽기 메소드 호출
			}
		});
	});
</script>

 

- writeForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ include file="../layout/header.jsp"%>

<div class="container">
	<div class="jumbotron">
		<h1>글 작성</h1>
	</div>
	
	<form action="${contextPath}/board/write" method="post" enctype="multipart/form-data">
		<div class="form-group">
			제목 : <input type="text" class="form-control" name="title">
		</div>
		<div class="form-group">
			내용 : <textarea rows="10" class="form-control" name="content"></textarea>
		</div>
		<div class="form-group">
			작성자 : <input type="text" class="form-control" name="writer">
		</div>
		<div class="form-group">
			첨부파일 : <input type="file" class="form-control" name="imageFileName">
		</div>
		<button class="btn btn-primary">등록</button>
	</form>
	<div class="preview"></div>
</div>

<%@ include file="../layout/footer.jsp"%>

<script>
	$(function(){
		$('input[type="file"]').on('change', function(){
			if(this.files[0]) {
				let reader = new FileReader(); // 파일읽기 객체
				reader.onload = function(e) { // 파일을 읽으면 이벤트 발생
					let value = e.target.result;
					if(value.startsWith("data:image/")) {
						let imgTag = "<img src='"+value+"' width='200px'>";
						$('.preview').html(imgTag);
					} else { // 이미지 파일이 아닌 경우
						alert('이미지 파일만 등록됩니다.');
						$('input[name="imageFileName"]').val('');
						$('.preview').html('');	
					}
				}
				reader.readAsDataURL(this.files[0]); // 파일 읽기 메소드 호출
			}
		});
		
	});
</script>

 

 

 

- webapp / WEB-INF / views / layout / header.jsp, footer.jsp

 

- header.jsp

부트스트랩4 사용

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<c:set var="contextPath" value="${pageContext.request.contextPath }" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js" integrity="sha512-aVKKRRi/Q/YV+4mjoKBsE4x3H+BkegoM/em46NNlCqNTmUYADjBbeNefNxYV7giUp0VxICtqdrbqU7iVaeZNXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
	<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
	  <!-- Links -->
	  <ul class="navbar-nav">
	    <li class="nav-item">
	      <a class="nav-link" href="#">Link 1</a>
	    </li>
	    <li class="nav-item">
	      <a class="nav-link" href="#">Link 2</a>
	    </li>
	  </ul>
	  
	</nav>

 

 

- footer.jsp

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

<div class="jumbotron">
	푸터영역
</div>
</body>
</html>

 

 


실행

 

 

- 글쓰기

 

 

- 이미지 업로드 

이미지 업로드하면 파일 업로드 경로에 게시글 번호와 같은 폴더가 생기고

그 폴더안에 이미지가 들어감

 

 

- 등록된 상태

 

 

- 게시글 조회

조회시 제목 내용이 readonly로 바뀌었고 첨부 버튼은 숨겨짐

 

 

- 수정하기

readonly가 해제 되고 첨부 버튼이 나타남

기존 조회에 있던 |수정하기|삭제|목록| 버튼이 숨겨지고,

|수정|취소| 버튼이 보여짐

 

 

- 이미지 바꾸기

이미지를 다른 이미지로 바꾸고 수정 버튼을 눌러서 적용하면

기존 이미지는 삭제되고 새로운 파일이 업로드됨

 

 

- 삭제하기

삭제 버튼 누르면 글이 삭제된다

파일 경로로 가면 폴더도 삭제돼있음

 

반응형

댓글