게시글 작성하고, 읽기

최고고·2022년 3월 19일
0

게시글 작성 - 파일 업로드

  • writerBoard jsp

    폼태그안에 action = WriteBoardService.do -> FC로 가게됨
    post방식으로 데이터 보낼때 content type명시해줘야됨
  1. 기본값 : application/x-www-form-urlencoded -> key=value 방식 : 쿼리스트링
  2. text : text/plain
  3. 파일전송시 : enctype="multipart/form-data" 멀티미디어 같은 파일 보낼때 안에 무조건~!!
    => cos.jar 파일을 쉽게 넣고 꺼낼 때 쓰는 라이브러리--->클래스파일을 여러개로 압축해놈 webinf\lib 에 drag & drop
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
		<title>Forty by HTML5 UP</title>
		<meta charset="utf-8" />
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<!--[if lte IE 8]><script src="assets/js/ie/html5shiv.js"></script><![endif]-->
		<link rel="stylesheet" href="assetsBoard/css/main.css" />
		<link rel="stylesheet" href="assetsBoard/css/board.css" />
		<!--[if lte IE 9]><link rel="stylesheet" href="assets/css/ie9.css" /><![endif]-->
		<!--[if lte IE 8]><link rel="stylesheet" href="assets/css/ie8.css" /><![endif]-->
</head>.
<body>

			<div id = "board">
			<!-- post방식 데이터 보낼때 content type명시해줘야됨
				1. 기본값 : application/x-www-form-urlencoded -> key=value 방식 : 쿼리스트링 
				2. text : text/plain 
				3. 파일전송시 : multipart/form-data -->
				
				<form action="WriteBoardService.do" method="post" enctype="multipart/form-data">
				<table id="list">
					<tr>
						<td>제목</td>
						<td><input type="text" name="title" > </td>
					</tr>
					<tr>
						<td>작성자</td>
						<td><input  type="text" name="writer"> </td>
					</tr>
					<tr>
						<td colspan="2">내용</td>
					</tr>
					<tr>
						<td colspan="2">
							<input name="fileName" type="file" style="float: right;">
							<textarea  name="content" rows="10" style="resize: none;"></textarea>			
						</td>
					</tr>
					<tr>
						<td colspan="2">
							<input type="reset" value="초기화">
							<input type="submit" value="작성하기">
						</td>
					</tr>
				</table>
				</form>
			</div>
			<!-- Scripts -->
			<script src="assets/js/jquery.min.js"></script>
			<script src="assets/js/jquery.scrolly.min.js"></script>
			<script src="assets/js/jquery.scrollex.min.js"></script>
			<script src="assets/js/skel.min.js"></script>
			<script src="assets/js/util.js"></script>
			<!--[if lte IE 8]><script src="assets/js/ie/respond.min.js"></script><![endif]-->
			<script src="assets/js/main.js"></script>
</body>
</html>
  • FrontController에 추가된 내용

    else if (command.equals("WriteBoardService.do")) {
    com = new WriteBoardService();
    nextpage = com.execute(request, response);
    }
    command interface를 상속 받고 execute메소드 오버라이딩
    FC를 추가했으면, 그다음에 해야할 것 ==> WriteBoardService 클래스파일 생성하기
package Controller;

import java.io.IOException;
import java.io.PrintWriter;

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 javax.servlet.http.HttpSession;

import Model.MemberDAO;
import Model.MemberDTO;
import Model.MessageDAO;
import Model.MessageDTO;
import Service.DeleteService;
import Service.IdCheckService;
import Service.JoinService;
import Service.LoginService;
import Service.LogoutService;
import Service.MsgService;
import Service.UpdateService;
import Service.WriteBoardService;
import inter.command;

//.do로 끝나는 문자열 맵핑
@WebServlet("*.do")
public class FrontController extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("frontController 실행");
		// 프론트 컨트롤러 패턴 : 모든 요청을 하나의 서블릿으로 정의하는 패턴
		// 중복되는 코드를 줄일 수 있고 보안 적용할때 하나의 서블릿에서 적용할 수 있다!

		String nextpage = "";
		command com = null;
		// 여러객체 불러올 필요없이 부모클래스가 가지고있는 하위클래스가 재정의(오버라이딩)
		// com객체에 service 패키지의 각 객체 담아주기
		// com에있는 execute()메소드 호출해서 리턴값 nextpage담아주기

		// 어떤기능을 수행하는 문자열인지 판단
		String uri = request.getRequestURI();
		System.out.println(uri);
		String path = request.getContextPath();
		System.out.println(path);
		String command = uri.substring(path.length() + 1);  //0번째 인덱스부터 문자열이 시작되는 시작위치
		String servlet = request.getServletPath();
//		String command = servlet.substring(1);
		System.out.println(command);

		if (command.equals("LoginServiceCon.do")) {
			com = new LoginService();
			nextpage = com.execute(request, response);
		} else if (command.equals("JoinServiceCon.do")) {
			com = new JoinService();
			nextpage = com.execute(request, response);
		} else if (command.equals("MsgCon.do")) {
			com = new MsgService();
			nextpage = com.execute(request, response);
		} else if (command.equals("LogoutServiceCon.do")) {
			com = new LogoutService();
			nextpage = com.execute(request, response);
		} else if (command.equals("idCheckServiceCon.do")) {
			com = new IdCheckService();
			nextpage = com.execute(request, response);
		} else if (command.equals("UpdateServiceCon.do")) {
			com = new UpdateService();
			nextpage = com.execute(request, response);
		} else if (command.equals("DeleteServiceCon.do")) {
			com = new DeleteService();
			nextpage = com.execute(request, response);
		} else if (command.equals("WriteBoardService.do")) {
			com = new WriteBoardService();
			nextpage = com.execute(request, response);
			
		}
		if (nextpage != null) {
			response.sendRedirect(nextpage);
		}
	}

}
  • WriteBoardService 서비스패키지에 클래스파일 만들기

    자동 implements, override

  • MultipartRequest

    form에 enctype속성이 추가 되었기 때문에 MultipartRequest 객체의 getParameter 메소드를 사용해야됨
    -> 객체 생성과 동시에 form을 통해 받아온 파일이 업로드됨
  • MultipartRequest의 매개변수 : 각 변수에 담아주고 매개변수로 적어주기
    request, savePath, maxsize, encoding, filePolicy
    savePath : 파일의 저장경로
    ▶서블릿의 실행위치는 webapp or webcontent
    ▶getServletContext() : 요청이 들어온 서블릿 정보
    ▶getRealPath() : 서블릿의 절대경로 매개변수부분은 찾아가려는 상대경로
    String savePath = request.getServletContext().getRealPath("./file"); -> webcontent에 새file폴더 만들어줌
    maxsize : 이미지의 크기 지정
    encoding : 인코딩방식
    filepolicy : 파일이름중복제거 --- 파일명이 겹칠때 숫자를 증가하게 해서 파일이름이 겹치지 않게 중복을 제거해줌

DB에 저장하기 위해 DTO생성해 담아주고 DAO에서 메소드 호출

package Service;

import java.io.IOException;
import java.net.URLEncoder;
import java.rmi.ServerException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

import Model.BoardDAO;
import Model.BoardDTO;
import inter.command;

public class WriteBoardService implements command {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response)
			throws ServerException, IOException {
		try {
			request.setCharacterEncoding("UTF-8"); // POST방식인코딩
			// MultipartRequest 객체의 매개변수 정리

			// savePath : 파일의 저장경로 ---- > webcon\

			// 서블릿실행위치 : webContent
			// getServletContext() : 요청이 들어온 서블릿 정보
			// getRealPath : 서블릿의 절대경로 ()매개변수부분은 찾아가려는 상대경로 적어주기
			String savePath = request.getServletContext().getRealPath("./file");
			// 여기까지는 절대경로고, 안에 string으로들어가는 건 상대경로로 들어감
			System.out.println(savePath);

			// maxsize : 이미지의 크기 지정
			int maxsize = 10 * 1024 * 1024; // 10MB
			// 1mb = 1024kb
			// 1kb = 1024byte

			// encoding : 인코딩방식
			String encoding = "UTF-8";
			// filepolicy : 파일이름중복제거 --- 파일명이 겹칠때 숫자를 증가하게 해서 파일이름이 겹치지 않게 중복을 제거해줌
			DefaultFileRenamePolicy filePolicy = new DefaultFileRenamePolicy();

			MultipartRequest multi = new MultipartRequest(request, savePath, maxsize, encoding, filePolicy);
			// 데이터들이 서버 안에 담기게 됨

			// 데이터 꺼내오기 MultipartRequest객체로 파라미터 수집해야됨
			String title = multi.getParameter("title");
			String writer = multi.getParameter("writer");
			String fileName = "";
			// fileName은 getFilesystemName로 받아와야됨
			if (multi.getFilesystemName("fileName") != null) {
				fileName = URLEncoder.encode(multi.getFilesystemName("fileName"), "UTF-8");
				// 파일이름에 한글이 있다면 인코딩(문자를 코드화함) 해줘야됨 문자를코드화시켜서 DB에 저장
			}

			String content = multi.getParameter("content");

			System.out.println("title : " + title);
			System.out.println("writer : " + writer);
			System.out.println("fileName : " + fileName);
			System.out.println("content : " + content);

			BoardDTO dto = new BoardDTO(0, title, writer, fileName, content, ""); // 생성자안만들고 임의의값넣어줌 어차피 메소드호출해서
																					// 디비에서 입력됨
			int cnt = new BoardDAO().insertBoard(dto);

			if (cnt > 0) {
				System.out.println("파일업로드 성공");
			} else {
				System.out.println("파일업로드 실패");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return "boardMain.jsp";
	}

}

  • BoardDAO에서 게시글을 DB에 저장하는 insertBoard 메소드

    -매개변수는 폼에서 입력받은 BoardDTO dto
    -DB에서 게시글 테이블 web_board 만들기
    create table web_board (
    num number,
    title varchar2(200),
    writer varchar2(200),
    fileName varchar2(200),
    content varchar2(1000),
    b_day date,
    CONSTRAINT bd_pk_num primary key (num)
    );
    num 자리에 들어갈 시퀀스 생성
    create sequence board_num
    start with 1
    increment by 1
    maxvalue 9999
    minvalue 1
    nocycle nocache;
	public int insertBoard(BoardDTO dto) {
		dbconn();
		try {
			String sql = "insert into web_board values(board_num.nextval,?,?,?,?,sysdate)";
			psmt = conn.prepareStatement(sql);
			psmt.setString(1, dto.getTitle());
			psmt.setString(2, dto.getWriter());
			psmt.setString(3, dto.getFileName());
			psmt.setString(4, dto.getContent());
			cnt = psmt.executeUpdate();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			dbclose();

		}
		return cnt;
	}
  • 작성하기버튼을 누르고 전송에 성공한다면 boardMain.jsp로 가게됨

    main jsp에서 DB의 정보를 모두 가지고 오기 때문에 FC거치지 않고 바로 DAO에서 메소드 만들어주기 BoardDTO객체를 담는 ArrayList를 반환하게됨
	// 게시글 목록 조회 메소드
	public ArrayList<BoardDTO> showBoard() {
		ArrayList<BoardDTO> list = new ArrayList<BoardDTO>();
		// 여러개의 dto를 담기위해

		dbconn();
		try {
			String sql = "select * from web_board order by b_day desc";
			psmt = conn.prepareStatement(sql);
			rs = psmt.executeQuery();
			while (rs.next()) {
				int num = rs.getInt(1);
				String title = rs.getString(2);
				String writer = rs.getString(3);
				String fileName = rs.getString(4);
				String content = rs.getString(5);
				String b_day = rs.getString(6);
				BoardDTO dto = new BoardDTO(num, title, writer, fileName, content, b_day);

				list.add(dto);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			dbclose();

		}
		return list;
	}
  • boardMain.jsp
    제목을 클릭하면 해당 게시글을 볼 수 있게 ---> <td><a href="boardSelectOne.jsp?num=<%=list.get(i).getNum()%>"><%= list.get(i).getTitle() %></a>
    num컬럼을 pk로 지정을 했기 때문에 num값을 boardSelectOne.jsp에 넘겨보내야됨
    번호 열머리글은 화면에서 보여지는 순서이기 때문에 num컬럼이 아님 i+1 로해야됨!!!
<%@page import="Model.BoardDTO"%>
<%@page import="Model.BoardDAO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
		<title>Forty by HTML5 UP</title>
		<meta charset="utf-8" />
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<!--[if lte IE 8]><script src="assets/js/ie/html5shiv.js"></script><![endif]-->
		<link rel="stylesheet" href="assetsBoard/css/main.css" />
		<link rel="stylesheet" href="assetsBoard/css/board.css" />
		<!--[if lte IE 9]><link rel="stylesheet" href="assets/css/ie9.css" /><![endif]-->
		<!--[if lte IE 8]><link rel="stylesheet" href="assets/css/ie8.css" /><![endif]-->
		
</head>
<body>		
		<%
			ArrayList<BoardDTO> list = new BoardDAO().showBoard();
		%>
			<div id="board">
				<table id = "list">
					<tr>
						<td>번호</td>
						<td>제목</td>
						<td>작성자</td>
						<td>시간</td>
					</tr>
					
					<%
					for(int i=0 ; i<list.size(); i++){ %>
						<tr>
							<td><%= i+1 %></td>
							<td><a href="boardSelectOne.jsp?num=<%=list.get(i).getNum()%>"><%= list.get(i).getTitle() %></a></td>
							<td><%= list.get(i).getWriter() %></td>
							<td><%= list.get(i).getB_day() %></td>
						</tr>
					
					<%} %>
				
				</table>
				
				<a href="main.jsp"><button id="writer">홈으로가기</button></a>
				<a href="writerBoard.jsp"><button id="writer">작성하러가기</button></a>
			</div>


			<!-- Scripts -->
			<script src="assets/js/jquery.min.js"></script>
			<script src="assets/js/jquery.scrolly.min.js"></script>
			<script src="assets/js/jquery.scrollex.min.js"></script>
			<script src="assets/js/skel.min.js"></script>
			<script src="assets/js/util.js"></script>
			<!--[if lte IE 8]><script src="assets/js/ie/respond.min.js"></script><![endif]-->
			<script src="assets/js/main.js"></script>
</body>
</html>
  • dao에서 게시글 하나만 가져오는 메소드 생성
    매개변수는 쿼리스트링으로 넘어온 num
    리턴은 게시글을 보여줘야하기 때문에 BoardDTO
	public BoardDTO boardSelectOne(int num) {

		BoardDTO dto = null;
		dbconn();

		try {
			String sql = "select * from web_board where num = ?";
			psmt = conn.prepareStatement(sql);
			psmt.setInt(1, num);
			rs = psmt.executeQuery();

			if (rs.next()) {
				int cnum = rs.getInt(1);
				String title = rs.getString(2);
				String writer = rs.getString(3);
				String fileName = rs.getString(4);
				String content = rs.getString(5);
				String b_day = rs.getString(6);

				dto = new BoardDTO(cnum, title, writer, fileName, content, b_day);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			dbclose();
		}

		return dto;
	}
  • boardSelectOne.jsp
    게시글의 이미지파일을 보여줄 때 : <img alt="" src="file/<%= dto.getFileName()%>"> .getFileName은 상대경로를 저장하기 때문에 src에 경로로 지정해주면 된다.
<%@page import="Model.BoardDTO"%>
<%@page import="Model.BoardDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="assetsBoard/css/main.css" />
<link rel="stylesheet" href="assetsBoard/css/board.css" />

</head>
<body>
<%
	int num = Integer.parseInt(request.getParameter("num"));	//쿼리스트링으로 가져온값
	BoardDAO dao = new BoardDAO();
	BoardDTO dto = dao.boardSelectOne(num);		//특정게시글을 (num) 매개변수로
%>

	<table>
		<tr>
			<td>제목</td>
			<td><%= dto.getTitle()%></td>
		</tr>
		<tr>
			<td>작성자</td>
			<td><%= dto.getWriter() %></td>
		</tr>
		<tr>
			<td>내용</td>
			<td>
			<img alt="" src="file/<%= dto.getFileName()%>">
			<%= dto.getContent()%> 
			</td>
		</tr>
	</table>
</body>
</html>

0개의 댓글