본문 바로가기

Programming/국비학원

221031 - MVC - 글 작성 기능

  • 글 작성
  • articleForm.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 src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
	//글쓰기 완료 => 목록으로 돌아가기
	function listView(obj){
		obj.action="${contextPath}/board/listArticles.do";
		obj.submit();
	}
	
	//이미지파일 첨부시 미리보기 기능 구현
	function readURL(input){
		if (input.files && input.files[0]){ //파일 리스트 존재하는지 & 0 인덱스에 파일 존재하는지 검사
			let reader=new FileReader(); ////
			reader.onload=function(e){ //onload : FileReader가 읽기 성공했을 때 트리거됨 //e : 파일 읽는 event (readAsDataURL)
				$('#preview').attr('src',e.target.result); //e.target.result => readAsDataURL로 얻은 파일 경로
			}
			reader.readAsDataURL(input.files[0]); //reader가 파일 url 읽어옴 => onload 트리거
		}
	}
</script>
</head>
<body>
	<h2 align="center">새글 쓰기</h2>
	<form name="articleForm" action="${contextPath}/board/addArticle.do" 
	method="post" enctype="multipart/form-data">
		<table align="center">
			<tr>
				<td align="right">글 제목 : </td>
				<td colspan="2"><input type="text" size="50" name="title"></td>
			</tr>
			<tr>
				<td align="right">글 내용 : </td>
				<td colspan="2">
					<textarea rows="10" cols="50" maxlength="4000" name="content"></textarea>
				</td>
			</tr>
			<tr>
				<td align="right">이미지파일 첨부 : </td>
				<td colspan="2"><input type="file" name="imageFileName" onchange="readURL(this);"></td> ////
				<td><img id="preview" src="#" width="200" height="200"></td> ////
			</tr>
			<tr>
				<td colspan="3" align="center">
					<input type="submit" value="글쓰기">
					<input type="button" value="목록보기" onclick="listView(this.form);"> ////
				</td>
			</tr>
		</table>
	</form>
</body>
</html>

 

 

 

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

	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
			
			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);
			
			bs.addArticle(vo);
			
			nextPage="/board/listArticles.do"; 
			
		}
		
		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("C:\\server\\upload_images");
		
		DiskFileItemFactory factory = new DiskFileItemFactory(); //파일 업로드, 저장할 저장소
		factory.setRepository(currentDirPath); //저장소 위치 설정
		factory.setSizeThreshold(1024*1024); //저장할 최대 크기
		
		ServletFileUpload upload = new ServletFileUpload(factory); //요청 객체 parse 돕는 객체
		
		try {
			List items = upload.parseRequest(request); //요청 객체가 전달한 HTTP Body 변환 => List 반환
			
			for (int i=0;i<items.size();i++) {
				FileItem fileItem = (FileItem) items.get(i); //List -> FileItem
				//fileitem : 업로드한 파일 & input에 입력된 텍스트
			
				if (fileItem.isFormField()) { //파일 형식 X (텍스트 등)
					System.out.println(fileItem.getFieldName()+" : "+fileItem.getString(encoding));
					articleMap.put(fileItem.getFieldName(), fileItem.getString(encoding));
                    //글 관련 매개변수-인풋내용 저장 (title, content, ..) 
				} else { //파일 형식 O
					System.out.println("파라미터 이름 : "+fileItem.getFieldName()); //ex. imageFileName
					System.out.println("파일 이름 : "+fileItem.getName()); //ex. a.PNG
					System.out.println("파일 크기 : "+fileItem.getSize()+"바이트"); //ex. 65927바이트
					
					if (fileItem.getSize()>0) {
						//String separator=File.separator; //OS별 구분자
						//int index = fileItem.getName().lastIndexOf(separator); //마지막에 위치한 구분자 인덱스						
						String fileName = fileItem.getName();
                        //.substring(index+1); //구분자 뒤 텍스트 가져옴 (파일명) 
                        ////=> getName()만 해도 파일명 불러올 수 있어 이전 코드 주석 처리
						
                        articleMap.put(fileItem.getFieldName(), fileName); // ex. imageFileName, a.PNG
						
                        File uploadFile = new File(currentDirPath + separator + fileName); //파일 객체 생성
						fileItem.write(uploadFile); //실제로 저장소에 파일 생성, 저장
					}
				}
			}
			
		} catch (Exception e) {
			System.out.println("업로드 중 에러");
		}
		
		return articleMap;
        
	}//upload()

}

 

 

 

  • BoardService
public class BoardService {

	BoardDAO dao;
	
	public BoardService() {
		dao = new BoardDAO();
	}
	
	public List<ArticleVO> listArticles(){
		List<ArticleVO> articleList = dao.selectAllArticles();
		return articleList;
	}
	
	public void addArticle(ArticleVO vo) { ////
		dao.insertNewArticle(vo);
	}
	
}

 

 

 

  • ArticleVO
public class ArticleVO {

	private int level;
	private int articleNo;
	private int parentNo;
	private String title;
	private String content;
	private String imageFileName;
	private String id;
	private Date writeDate;
	
	public ArticleVO() {
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public int getArticleNo() {
		return articleNo;
	}

	public void setArticleNo(int articleNo) {
		this.articleNo = articleNo;
	}

	public int getParentNo() {
		return parentNo;
	}

	public void setParentNo(int parentNo) {
		this.parentNo = parentNo;
	}

	public String getTitle() {
		return title;
	}

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

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getImageFileName() {
		
		try {
			if (imageFileName != null && imageFileName.length()!=0) {
				imageFileName = URLDecoder.decode(imageFileName,"utf-8");
			}
		} catch(UnsupportedEncodingException e) {
			System.out.println("이미지 파일 이름 불러오는 중 에러");
		}
		
		return imageFileName;
	}

	public void setImageFileName(String imageFileName) {
		try {
			if (imageFileName != null && imageFileName.length()!=0) { ////
				this.imageFileName=URLEncoder.encode(imageFileName,"utf-8"); 
			}
		} catch(UnsupportedEncodingException e) {
			System.out.println("이미지 파일 이름 저장 중 에러");
		}
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Date getWriteDate() {
		return writeDate;
	}

	public void setWriteDate(Date writeDate) {
		this.writeDate = writeDate;
	}
	
}

 

 

 

  • 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; //마지막 글번호 + 1
			} 
		}catch(Exception e) {
			System.out.println("글 번호 생성 중 에러");
		}
		return 1; //글번호 없으면 1 부여
	}
	
	
	////글쓰기 저장 메소드
	public void insertNewArticle(ArticleVO vo) {
		try {
			con=dataFactory.getConnection();
			
			int articleNo = getNewArticleNo(); //
			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 글쓰기 저장 중 에러");
		}
	}
	
}

 

 

 

 

중복된 이름 파일은 저장 안 되는 오류 => 

  • 글 작성 기능 수정

저장소 안에 temp 폴더 생성

1 글 submit 시 파일을 임시 temp 폴더에 업로드
2 서비스 클래스에서 addArticle() 호출 
=> 새 글 정보를 파라미터로 받아 db에 전송, 새 글 번호 리턴
3 리턴받은 글번호를 이용해 저장소에 글번호 폴더 생성
4 temp에 저장됐던 파일을 해당 폴더로 이동

 

 

 

  • BoardController
		} 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 | imageFileName.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); //src 파일을 dest 디렉토리로 이동
			}
			PrintWriter pw = response.getWriter();
			pw.print("<script>"
					+ "alert('새 글을 추가했습니다');"
					+ "location.href='"+request.getContextPath()+"/board/listArticles.do';"
					+ "</script>");
			return;
			//nextPage="/board/listArticles.do"; 
			
		}
		
		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 { //파일 형식 O
					System.out.println("파라미터 이름 : "+fileItem.getFieldName());
					System.out.println("파일 이름 : "+fileItem.getName());
					System.out.println("파일 크기 : "+fileItem.getSize()+"바이트");
					
					if (fileItem.getSize()>0) {
						String fileName = fileItem.getName(); 
						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 int addArticle(ArticleVO vo) {  ////void->int
		
		return dao.insertNewArticle(vo);

	}

 

 

 

  • BoardDAO
//글쓰기 저장 메소드
	public int insertNewArticle(ArticleVO vo) { ////void->int
		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; ////
		
	}