본문 바로가기

Programming/국비학원

221101 - MVC - 글 상세 조회 기능

  • 글 상세 조회
  • ViewArticle.jsp
<%@ 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}"/>
<%
	request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 상세 보기</title>
<body>
	<form name="formArticle" action="post" enctype="multipart/form-data">
		<table align="center">
			<tr>
				<td width="150" align="center" bgcolor="beige">글번호</td>
				<td><input type="text" name="articleNo" 
				value="${article.articleNo}" disabled></td>
			</tr>
			<tr>
				<td width="150" align="center" bgcolor="beige">아이디</td>
				<td><input type="text" name="id" 
				value="${article.id}" disabled></td>
			</tr>
			<tr>
				<td width="150" align="center" bgcolor="beige">제목</td>
				<td><input type="text" name="title" value="${article.title}"></td>
			</tr>			
			<tr>
				<td width="150" align="center" bgcolor="beige">내용</td>
				<td><textarea name="content">${article.content}</textarea></td>
			</tr>	
			<c:if test="${not empty article.imageFileName}">
				<tr>
					<td width="150" align="center" bgcolor="beige">이미지</td>
					<td>
						<input type="hidden" name="original" value="${article.imageFileName}">
						<img src="${contextPath}/???"><br>
					</td>
				</tr>
				<tr>
					<td>
						<input type="file" name="imageFileName" disabled onchange="">
					</td>
				</tr>
			</c:if>
			<tr>
				<td width="150" align="center" bgcolor="beige">등록일자</td>
				<td>
					<input type="text" value="<fmt:formatDate value="${article.writeDate}"/>" disabled>
				</td>
			</tr>
		</table>
	</form>
</body>
</html>

 

 

 

  • BoardController
@WebServlet("/board/*")
public class BoardController extends HttpServlet {

	private static String ART_IMAGE_REPO="C:\\server\\upload_images";  //
	
	BoardService bs;
	ArticleVO vo;
	
	public void init(ServletConfig config) throws ServletException {
		bs= new BoardService();
		vo= new ArticleVO();
	}

	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 nextPage = "";
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		String action=request.getPathInfo(); 
		System.out.println("요청명 : "+action);
		
		List<ArticleVO> articleList = new ArrayList<ArticleVO>();
		
		if (action==null||action.equals("/listArticles.do")) { //글 목록 리스트
			
			articleList = bs.listArticles();
			request.setAttribute("articleList", articleList);
			
			nextPage="/boardView/listArticles.jsp"; 
			
		} else if (action.equals("/articleForm.do")) { //글쓰기 버튼 클릭
			
			nextPage="/boardView/articleForm.jsp";
			
		} else if (action.equals("/addArticle.do")) { //글쓰기 submit
			int articleNo=0; 
			
			Map<String, String> articleMap=upload(request,response);
			
			String title = articleMap.get("title");
			String content = articleMap.get("content");
			String imageFileName = articleMap.get("imageFileName");
			
			vo.setParentNo(0);
			vo.setId("hong");
			vo.setTitle(title);
			vo.setContent(content);
			vo.setImageFileName(imageFileName);
			
			articleNo=bs.addArticle(vo); 
			
			if (imageFileName != null && mageFileName.length() != 0) {
				File srcfile = new File(ART_IMAGE_REPO+"/temp/"+imageFileName); 
				File destDir = new File(ART_IMAGE_REPO+"/"+articleNo); 
				destDir.mkdir(); 
				FileUtils.moveFileToDirectory(srcfile, destDir, true); 
			}
			PrintWriter pw = response.getWriter();
			pw.print("<script>"
					+ "alert('새 글을 추가했습니다');"
					+ "location.href='"+request.getContextPath()+"/board/listArticles.do';"
					+ "</script>");
			return;
			//nextPage="/board/listArticles.do";
			
		} else if (action=="/viewArticle.do") { ////글 상세 보기
			
			String articleNo = request.getParameter("articleNo");
			vo = bs.viewArticle(Integer.parseInt(articleNo));
			
			request.setAttribute("article", vo); //세부 조회할 vo 객체 전달
			
			nextPage="/boardView/viewArticle.jsp";
			
		}
		
		
		RequestDispatcher rd = request.getRequestDispatcher(nextPage);
		rd.forward(request, response);
	}
	
    
	//자료,이미지 업로드 처리 메소드
	private Map<String, String> upload(HttpServletRequest request, HttpServletResponse response) {
		Map<String, String> articleMap = new HashMap<String, String>();
		String encoding = "utf-8";
		File currentDirPath = new File(ART_IMAGE_REPO); 
		
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setRepository(currentDirPath); 
		factory.setSizeThreshold(1024*1024); 
		
		ServletFileUpload upload = new ServletFileUpload(factory);
		
		
		try {
			List items = upload.parseRequest(request); 
			
			for (int i=0;i<items.size();i++) {
				FileItem fileItem = (FileItem) items.get(i);
			
				if (fileItem.isFormField()) { /
					System.out.println(fileItem.getFieldName()+" : "+fileItem.getString(encoding));
					articleMap.put(fileItem.getFieldName(), fileItem.getString(encoding));
				} else { 
					System.out.println("파라미터 이름 : "+fileItem.getFieldName());
					System.out.println("파일 이름 : "+fileItem.getName());
					System.out.println("파일 크기 : "+fileItem.getSize()+"바이트");
					
					if (fileItem.getSize()>0) {
						String separator=File.separator; 
						int index = fileItem.getName().lastIndexOf(separator); 
						String fileName = fileItem.getName().substring(index+1); 
						articleMap.put(fileItem.getFieldName(), fileName); 
						File uploadFile = new File(currentDirPath + "/temp/" + fileName);
						fileItem.write(uploadFile); 
					}
				}
			}
			
		} catch (Exception e) {
			System.out.println("업로드 중 에러");
		}
		
		return articleMap;
	}

}

 

 

 

  • BoardService
public class BoardService {

	BoardDAO dao;
	
	public BoardService() {
		dao = new BoardDAO();
	}
	
	public List<ArticleVO> listArticles(){
		List<ArticleVO> articleList = dao.selectAllArticles();
		return articleList;
	}
	
	public int addArticle(ArticleVO vo) { 
		return dao.insertNewArticle(vo);
	}
	
	public ArticleVO viewArticle(int articleNo) { ////
		ArticleVO article = null;
		
		article = dao.selectArticle(articleNo); ////
		
		return article;
	}
	
}

 

 

 

  • BoardDAO
public class BoardDAO {
	
	private DataSource dataFactory;
	private Connection con;
	private PreparedStatement ps;
	
	
	public BoardDAO() {
		
		try {
			Context ctx=new InitialContext();
			Context envContext=(Context)ctx.lookup("java:/comp/env");
			dataFactory=(DataSource) envContext.lookup("jdbc/oracle");
		}catch(Exception e){
			System.out.println("DB 연결 중 에러");
		}
		
	}
	
	
	//게시판 글 목록
	public List<ArticleVO> selectAllArticles(){
		List<ArticleVO> articleList = new ArrayList<ArticleVO>();
		
		try {
			
			con=dataFactory.getConnection();
			//오라클 - 계층형 쿼리
			String query="SELECT LEVEL, articleNo, parentNo, title, content, id, writeDate from board_qna"
					+ " START WITH parentNo=0 CONNECT BY PRIOR articleNo=parentNo"
					+ " ORDER SIBLINGS BY articleNo DESC";
			System.out.println(query);
			ps=con.prepareStatement(query);
			ResultSet rs = ps.executeQuery();
			while (rs.next()) {
				int level = rs.getInt(1);
				int articleNo = rs.getInt(2);
				int parentNo = rs.getInt(3);
				String title = rs.getString(4);
				String content = rs.getString(5);
				String id = rs.getString(6);
				Date writeDate = rs.getDate(7);
				
				ArticleVO article = new ArticleVO();
				article.setLevel(level);
				article.setArticleNo(articleNo);
				article.setParentNo(parentNo);
				article.setTitle(title);
				article.setContent(content);
				article.setId(id);
				article.setWriteDate(writeDate);

				articleList.add(article);
			}
			
			rs.close();
			ps.close();
			con.close();
			
		} catch(Exception e) {
			
			System.out.println("DB 글목록 조회 중 에러");
			
		}
		
		return articleList;
	}
	
	
	//글번호 생성 메소드
	private int getNewArticleNo() {
		try {
			con=dataFactory.getConnection();
			String query = "select max(articleNo) from board_qna";
			System.out.println(query);
			ps = con.prepareStatement(query);
			ResultSet rs = ps.executeQuery();
			
			if (rs.next()) {
				return rs.getInt(1)+1;
			} 
		}catch(Exception e) {
			System.out.println("글 번호 생성 중 에러");
		}
		return 1;
	}
	
	
	//글쓰기 저장 메소드
	public int insertNewArticle(ArticleVO vo) {
		int articleNo = getNewArticleNo(); 
		try {
			con=dataFactory.getConnection();
			
			
			int parentNo = vo.getParentNo();
			String title = vo.getTitle();
			String content = vo.getContent();
			String id = vo.getId();
			String imageFileName = vo.getImageFileName();
			
			String query = "insert into board_qna(articleno, parentno, title, content, id, imagefile)"
					+ "values(?,?,?,?,?,?)";
			System.out.println(query);
			
			ps=con.prepareStatement(query);
			ps.setInt(1, articleNo);
			ps.setInt(2, parentNo);
			ps.setString(3, title);
			ps.setString(4, content);
			ps.setString(5, id);
			ps.setString(6, imageFileName);
			ps.executeUpdate();
			
			ps.close();
			con.close();
		} catch (Exception e) {
			System.out.println("DB 글쓰기 저장 중 에러");
		}
		
		return articleNo; 
		
	}
	
	
	//글 상세 보기
	public ArticleVO selectArticle(int articleNo) { ////
		
		ArticleVO article = new ArticleVO();
		
		try {
			con=dataFactory.getConnection();
			
			String query="select articleno, parentno, title, content, imagefile, id, writedate"
					+ " from board_qna"
					+ " where articleno = ?";
			ps=con.prepareStatement(query);
			ps.setInt(1, articleNo);
			ResultSet rs=ps.executeQuery();
			rs.next();
			
			int _articleNo=rs.getInt(1);
			int parentNo = rs.getInt(2);
			String title = rs.getString(3);
			String content = rs.getString(4);
			String imageFileName = URLEncoder.encode(rs.getString(5),"utf-8");
;			String id = rs.getString(6);
			Date writeDate = rs.getDate(7);
			
			article.setArticleNo(_articleNo);
			article.setParentNo(parentNo);
			article.setTitle(title);
			article.setContent(content);
			article.setImageFileName(imageFileName);
			article.setId(id);
			article.setWriteDate(writeDate);
			
			rs.close();
			ps.close();
			con.close();
			
		} catch(Exception e) {
			System.out.println("글 상세 조회 중 에러");
		}
		
		return article;
		
	}

}

 

 

 

 

  • 이미지 프리뷰 기능 추가
  • viewArticle.jsp 
<%@ 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}"/>
<%
	request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 상세 보기</title>
<body>
	<form name="formArticle" action="post" enctype="multipart/form-data">
		<table align="center">
			<tr>
				<td width="150" align="center" bgcolor="beige">글번호</td>
				<td><input type="text" name="articleNo" 
				value="${article.articleNo}" disabled></td>
			</tr>
			<tr>
				<td width="150" align="center" bgcolor="beige">아이디</td>
				<td><input type="text" name="id" 
				value="${article.id}" disabled></td>
			</tr>
			<tr>
				<td width="150" align="center" bgcolor="beige">제목</td>
				<td><input type="text" name="title" value="${article.title}"></td>
			</tr>			
			<tr>
				<td width="150" align="center" bgcolor="beige">내용</td>
				<td><textarea name="content">${article.content}</textarea></td>
			</tr>	
			<c:if test="${not empty article.imageFileName}"> ////
				<tr>
					<td width="150" align="center" bgcolor="beige">이미지</td>
					<td>
						<input type="hidden" name="original" value="${article.imageFileName}"> 
						<img src="${contextPath}/download.do?articleNo=${article.articleNo}&
						imageFileName=${article.imageFileName}" id=preview><br> ////
					</td>
				</tr>
				<tr>
					<td>
						<input type="file" name="imageFileName" disabled onchange="">
					</td>
				</tr>
			</c:if>
			<tr>
				<td width="150" align="center" bgcolor="beige">등록일자</td>
				<td>
					<input type="text" value="<fmt:formatDate value="${article.writeDate}"/>" disabled>
				</td>
			</tr>
		</table>
	</form>
</body>
</html>

 

 

 

  • FileDownloadController
@WebServlet("/download.do") ////
public class FileDownloadController extends HttpServlet {
	private static String ART_IMAGE_REPO="C:\\server\\upload_images";  

	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 {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		String imageFileName = request.getParameter("imageFileName");
		String articleNo = request.getParameter("articleNo");
		System.out.println("이미지 이름 : "+imageFileName);
		
		//다운로드 기능
		OutputStream out = response.getOutputStream();  //출력 스트림
		
		String path = ART_IMAGE_REPO + "/" + articleNo + "/" + imageFileName;
		File imageFile = new File(path); //다운받을 파일 객체 생성
		
		response.setHeader("Cache-Control", "no-cache"); //캐시 속성 지정
		response.setHeader("Content-disposition", "attachment;fileName="+imageFileName); //다운로드시 파일명 지정
		
		FileInputStream in = new FileInputStream(imageFile); 
        //입력 스트림 생성 => 다운받을 객체를 스트림에 담음
		
        byte[] buffer = new byte[1024*8]; //한번에 읽을 바이트 수 : 8k
		
		while (true) {
			int count = in.read(buffer); //8k씩 읽기
			
			if (count==-1) { //읽을 바이트가 없다면
				break;
			}
			
			out.write(buffer,0,count); //buffer 배열 내에서 인덱스 0부터 count만큼 출력
		}
		
		in.close();
		out.close();
		
	}

}

 

 

 

 

이미지 없는 글 => 데이터 불러오기 오류

  • 수정
  • BoardDAO
public class BoardDAO {
	
    ...
	
	//글 상세 보기
	public ArticleVO selectArticle(int articleNo) { ////
		
		ArticleVO article = new ArticleVO();
		
		try {
			con=dataFactory.getConnection();
			
			String query="select articleno, parentno, title, content, nvl(imagefile,'null'), id, writedate"
					+ " from board_qna"
					+ " where articleno = ?"; ////
			ps=con.prepareStatement(query);
			ps.setInt(1, articleNo);
			ResultSet rs=ps.executeQuery();
			rs.next();
			
			int _articleNo=rs.getInt(1);
			int parentNo = rs.getInt(2);
			String title = rs.getString(3);
			String content = rs.getString(4);
			String imageFileName = URLEncoder.encode(rs.getString(5),"utf-8"); //
			String id = rs.getString(6);
			Date writeDate = rs.getDate(7);
			
			article.setArticleNo(_articleNo);
			article.setParentNo(parentNo);
			article.setTitle(title);
			article.setContent(content);
			if (imageFileName.equals("null")) { ////
				imageFileName=null;  ////
			}
			article.setImageFileName(imageFileName); ////

			article.setId(id);
			article.setWriteDate(writeDate);
			
			rs.close();
			ps.close();
			con.close();
			
		} catch(Exception e) {
			System.out.println("글 상세 조회 중 에러");
			e.printStackTrace();
		}
		
		return article;
		
	}

}

 

 

 

  • viewArticle.jsp
<%@ 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}"/>
<%
	request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 상세 보기</title>
<script type="text/javascript">
	function backToList(obj){ ////
		obj.action="${contextPath}/board/listArticles.do";
		obj.submit();
	}
</script>
<body>
	<form name="formArticle" action="post" enctype="multipart/form-data"> ////
		<table align="center">
			<tr>
				<td width="150" align="center" bgcolor="beige">글번호</td>
				<td><input type="text" name="articleNo" 
				value="${article.articleNo}" disabled></td>
			</tr>
			<tr>
				<td width="150" align="center" bgcolor="beige">아이디</td>
				<td><input type="text" name="id" 
				value="${article.id}" disabled></td>
			</tr>
			<tr>
				<td width="150" align="center" bgcolor="beige">제목</td>
				<td><input type="text" name="title" value="${article.title}"></td>
			</tr>			
			<tr>
				<td width="150" align="center" bgcolor="beige">내용</td>
				<td><textarea name="content">${article.content}</textarea></td>
			</tr>	
			<c:if test="${not empty article.imageFileName}"> ////
				<tr>
					<td width="150" align="center" bgcolor="beige">이미지</td>
					<td>
						<input type="hidden" name="original" value="${article.imageFileName}">
						<img src="${contextPath}/download.do?articleNo=${article.articleNo}&
						imageFileName=${article.imageFileName}" id=preview><br> ////
					</td>
				</tr>
				<tr>
					<td>
						<input colspan="2" type="file" name="imageFileName" disabled onchange="">
					</td>
				</tr>
			</c:if>
			<tr>
				<td width="150" align="center" bgcolor="beige">등록일자</td>
				<td>
					<input type="text" value="<fmt:formatDate value="${article.writeDate}"/>" disabled>
				</td>
			</tr>
			<tr>
				<td>
					<input colspan="2" type="button" value="수정하기" onclick="">
					<input colspan="2" type="button" value="삭제하기" onclick="">
					<input colspan="2" type="button" value="돌아가기" onclick="backToList(formArticle);">
					<input colspan="2" type="button" value="답글쓰기" onclick="">						
				</td>
			</tr>
		</table>
	</form>
</body>
</html>