[Servlet 5-4] 방명록

임승현·2022년 12월 2일
0

Servlet

목록 보기
14/14

🎨 1. Guest 테이블 생성

SQL Develope 실행

create table GUEST(no number(10) primary key,
		name varchar2(40),
		regdate date,
		title varchar2(100),
		content varchar2(4000));
//
create sequence guest_seq;
//
desc guest;
//
select * from guest;

🎨 2. DTO 클래스 생성

📃GuestDTO.java

package xyz.itwill.dto;
//
/*
이름      널?       유형             
------- -------- -------------- 
NO      NOT NULL NUMBER(10)      - 글번호 : 시퀀스의 자동 증가값
NAME             VARCHAR2(40)    - 작성자 : 사용자 입력값
REGDATE          DATE            - 작성일자 : 시스템의 현재 날짜(시간)
TITLE            VARCHAR2(100)   - 제목 : 사용자 입력값
CONTENT          VARCHAR2(4000)  - 내용 : 사용자 입력값
*/
//
public class GuestDTO {
	private int no;
	private String name;
	private String regdate;
	private String title;
	private String content;
	//
	public GuestDTO() {
		// TODO Auto-generated constructor stub
	}
	public int getNo() {
		return no;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getRegdate() {
		return regdate;
	}
	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}
	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;
	}
}

🎨 3. DAO 클래스 생성

📌 게시글을 전달받아 GUEST 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드

📃GuestDAO.java

package xyz.itwill.dao;
//
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
//
import xyz.itwill.dto.GuestDTO;
//
public class GuestDAO extends JdbcDAO {
	private static GuestDAO _dao;
	//
	public GuestDAO() {
		// TODO Auto-generated constructor stub
	}
	static {
		_dao=new GuestDAO();
	}
	public static GuestDAO getDAO() {
		return _dao;
	}
	//게시글을 전달받아 GUEST 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
	public int insertGuest(GuestDTO guest) {
		Connection con=null;
		PreparedStatement pstmt=null;
		int rows=0;
		try {
			con=getConnection();
			//
			String sql="insert into guest values(guest_seq.nextval, ?, sysdate, ?, ?)";
			pstmt=con.prepareStatement(sql);
			pstmt.setString(1, guest.getName());
			pstmt.setString(2, guest.getTitle());
			pstmt.setString(3, guest.getContent());
			//
			rows=pstmt.executeUpdate();
		} catch (SQLException e) {
			System.out.println("[에러]insertGuest() 메소드의 SQL 오류 = "+e.getMessage());
		} finally {
			close(con, pstmt);
		}
		return rows;
	}
	//게시글의 글번호를 전달받아 GUEST 테이블에 저장된 해당 글번호의 게시글을 삭제하고 삭제행의 갯수를 반환하는 메소드
	public int deleteGuest(int no) {
		Connection con=null;
		PreparedStatement pstmt=null;
		int rows=0;
		//
		try {
			con=getConnection();
			//
			String sql="delete from guest where no=?";
			pstmt=con.prepareStatement(sql);
			pstmt.setInt(1, no);
			//
			rows=pstmt.executeUpdate();
		} catch (SQLException e) {
			System.out.println("[에러]insertGuest() 메소드의 SQL 오류 = "+e.getMessage());
		} finally {
			close(con, pstmt);
		}
		return rows;
	}
	//GUEST 테이블에 저장된 모든 게시글을 검색하여 반환하는 메소드
	public List<GuestDTO> selectGuestList() {
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		List<GuestDTO> guestList=new ArrayList<>();
		//
		try {
			con=getConnection();
			//
			String sql="select * from guest order by no desc";
			pstmt=con.prepareStatement(sql);
			//
			rs=pstmt.executeQuery();
			//
			while(rs.next()) {
				GuestDTO guest=new GuestDTO();
				guest.setNo(rs.getInt("no"));
				guest.setName(rs.getString("name"));
				guest.setRegdate(rs.getString("regdate"));
				guest.setTitle(rs.getString("title"));
				guest.setContent(rs.getString("content"));
				guestList.add(guest);
			}
		} catch (SQLException e) {
			System.out.println("[에러]insertGuest() 메소드의 SQL 오류 = "+e.getMessage());
		} finally {
			close(con, pstmt, rs);
		}
		return guestList;
	}
}

🎨 4. select.itwill 만들기(실행 페이지)

📌 GUEST 테이블에 저장된 모든 게시글을 검색하여 클라이언트에게 전달하는 서블릿

📃GuestSelectServlet.java

package xyz.itwill.servlet;
//
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
//
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 xyz.itwill.dao.GuestDAO;
import xyz.itwill.dto.GuestDTO;
//
//GUEST 테이블에 저장된 모든 게시글을 검색하여 클라이언트에게 전달하는 서블릿
//→ [방명록 쓰기]를 클릭한 경우 입력페이지(insert.html)로 이동
@WebServlet("/select.itwill")
public class GuestSelectServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	//
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		//
		//GUEST 테이블에 저장된 모든 게시글을 검색하여 반환하는 DAO 클래스의 메소드 호출
		List<GuestDTO> guestList=GuestDAO.getDAO().selectGuestList();
		//
		//처리결과를 웹문서로 생성하여 클라이언트에게 전달 - 응답
		out.println("<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta http-equiv='Content-Type' content='ext/html; charset=UTF-8'>");
		out.println("<title>Servelt</title>");
		out.println("<link rel='stylesheet' type='text/css' href='css/common.css'>");
		out.println("</head>");
		out.println("<body>");
		out.println("<table width='80%' align='center' border='0' cellspacing='0' cellpadding='0'>");
		out.println("<tr bgcolor='#000080' valign='middle'>");
		out.println("<td height='25' class='t1' align='center'>");
		out.println("<b><font color='#FFFFFF'>:::방명록 읽기 :::</font></b>");
		out.println("</td>");
		out.println("</tr>");
		//
		out.println("<tr>");
		out.println("<td height='30' align='right' valign='bottom' class='t1'>");
		out.println("<a href='insert.html'>방명록 쓰기</a></td>");
		out.println("</tr>");
		//
		if (guestList.isEmpty()) {// 검색된 게시글이 없는 경우
			out.println("<tr align='center'>");
			out.println("<td>방명록에 저장된 게시글이 하나도 없습니다.</td>");
			out.println("</tr>");
		} else {// 검색된 게시글이 있는 경우
			// List 객체에 저장된 요소값(DTO 객체)를 반복적으로 제공받아 응답 처리
			for (GuestDTO guest : guestList) {
				out.println("<tr>");
				out.println("<td>");
				out.println("<table width='100%' align='center' border='1' cellspacing='0' bgcolor='#f5f5f5'>");
				out.println("<tr>");
				out.println("<td>");
				out.println("<table width='100%' align='center' border='0' cellspacing='0'>");
				out.println("<tr>");
				out.println("<td bgcolor='#808000' align='center' height='20' width='20%' class='t1'>");
				out.println("<font color='#FFFFFF'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font></td>");
				out.println("<td height='20' width='80%' class='t1'>");
				out.println("<b><font color='#0000FF'>&nbsp;&nbsp;" + guest.getTitle() + "</font></b></td>");
				out.println("</tr>");
				out.println("</table>");
				out.println("</td>");
				out.println("</tr>");
				//
				out.println("<tr>");
				out.println("<td>");
				out.println("<table width='100%' align='center' border='0' cellspacing='0'>");
				out.println("<tr>");
				out.println("<td bgcolor='#808000' align='center' height='20' width='20%' class='t1'>");
				out.println("<font color='#FFFFFF'>작 성 자</font></td>");
				out.println("<td align='center' height='20' width='30%' class='t1'>" + guest.getName() + "</td>");
				out.println("<td bgcolor='#808000' align='center' height='20' width='20%' class='t1'>");
				out.println("<font color='#FFFFFF'>작 성 일</font></td>");
				out.println("<td align='center' height='20' width='30%' class='t1'>" + guest.getRegdate() + "</td>");
				out.println("</tr>");
				out.println("</table>");
				out.println("</td>");
				out.println("</tr>");
				//
				out.println("<tr>");
				out.println("<td>");
				out.println("<table width='100%' align='center' border='0' cellspacing='10'>");
				out.println("<tr>");
				out.println("<td height='50' width='100%' class='t1'>");
				out.println(guest.getContent().replace("\n", "<br>"));
				out.println("</td>");
				out.println("</tr>");
				out.println("</table>");
				out.println("</td>");
				out.println("</tr>");
				out.println("</table>");
				out.println("</td>");
				out.println("</tr>");
				//
				out.println("<tr>");
				out.println("<td height='20'>");
				out.println("<hr color='#000077'>");
				out.println("</td>");
				out.println("</tr>");
			}
		}
		out.println("</table>");
		out.println("</body>");
		out.println("</html>");
	}
}


🎨 5. insert.html 만들기(강사님 파일 참고)


📃insert.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- GUEST 테이블에 저장될 방명록 게시글을 사용자에게 입력받기 위한 문서 - 입력페이지 -->
<!-- => [방명록 쓰기]를 클릭하면 게시글 저장페이지(insert.itwill)로 이동 - 웹프로그램 요청하여 사용자 입력값(방명록 게시글) 전달 -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Servlet</title>
<link rel="stylesheet" type="text/css" href="css/common.css">
<SCRIPT LANGUAGE="JavaScript" SRC="js/common.js">
</SCRIPT>
<SCRIPT language="JavaScript">
function loading(form)
{
	form.name.focus();
}
function form_submit(form, action, method)
{
	if(is_null_field(form)) return;
	form.action=action;
	form.method=method;
	form.submit();
}
function is_null_field(form)
{
	if(is_null(form.name.value) || is_space(form.name.value))
	{
		alert("이름을 입력해요.");
		form.name.focus();
		return true;
	}
	if(is_null(form.title.value) || is_space(form.title.value))
	{
		alert("제목을 입력해요.");
		form.title.focus();
		return true;
	}
	if(is_null(form.content.value) || is_space(form.content.value))
	{
		alert("내용을 입력해요.");
		form.content.focus();
		return true;
	}
}
</SCRIPT>
</head>
<body onLoad="loading(guest);">
<form name="guest">
<table width="80%" align="center" border="0" cellspacing="0" cellpadding="0">
	<tr bgcolor="#556b2f" valign="middle">
		<td height="25" class="t1" align="center">
		<b><font color="#FFFFFF">::: 방명록 쓰기 :::</font></b>
		</td>
	</tr>	
	<tr>
		<td height="20" >&nbsp;</td>
	</tr>	
	<tr>
		<td>
			<table width="100%" align="center" border=1 cellspacing=0>
				<tr>
					<td>
						<table width="100%" align="center" border="0" cellspacing="0">
							<tr>
								<td bgcolor="#808000" align="center" height="20" width="20%" class="t1">
								<font color="#FFFFFF">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
								</td>
								<td height="20" width="80%" class="t1">&nbsp;
								<input type="text" name="name"  maxlength="24" size="24" class="TXTFLD">
								</td>
							</tr>
						</table>
					</td>
				</tr>	
				<tr>
					<td>
						<table width="100%" align="center" border="0" cellspacing="0">
							<tr>
								<td bgcolor="#808000" align="center" height="20" width="20%" class="t1">
									<font color="#FFFFFF">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
								</td>
								<td height="20" width="80%" class="t1">&nbsp;
								<input type="text" name="title"  maxlength="80" size="80" class="TXTFLD">
								</td>
							</tr>
						</table>
					</td>
				</tr>	
				<tr>
					<td>
						<table width="100%" align="center" border="0" cellspacing="10">
							<tr>
								<td height="50" width="1000%" class="t1">
								<textarea cols="98" name="content" rows="10" class="TXTFLD"></textarea>
								</td>
							</tr>
						</table>
					</td>
				</tr>
			</table>
		</td>
	</tr>
	<tr>
		<td height="50" align="center">
		<input type="button" value="방명록 쓰기" class="TXTFLD" onclick="form_submit(guest,'insert.itwill','POST');">&nbsp;
		<input type="reset" value="다시 작성하기"  class="TXTFLD">
		</td>
	</tr>
</table>
</form>
</body>
</html>

🎨 6.select.itwill로 이동하기 위한 URL 주소를 전달

📌 입력페이지(insert.htmle)에서 전달된 게시글을 반환받아 GUEST 테이블에 삽입하고 클라이언트에게 게시글목록 출력페이지(select.itwill)로 이동하기 위한 URL 주소를 전달 - 처리페이지

📃GuestInsertServlet.java

package xyz.itwill.servlet;
//
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 xyz.itwill.dao.GuestDAO;
import xyz.itwill.dto.GuestDTO;
//
//입력페이지(insert.htmle)에서 전달된 게시글을 반환받아 GUEST 테이블에 삽입하고 클라이언트에게 
//게시글목록 출력페이지(select.itwill)로 이동하기 위한 URL 주소를 전달 - 처리페이지
@WebServlet("/insert.itwill")
public class GuestInsertServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	//
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//response.setContentType("text/html;charset=utf-8");
		//PrintWriter out=response.getWriter();//출력페이지를 만드는게 아니라서 필요없음
		//비정상적인 요청에 대한 처리
		if(request.getMethod().equals("GET")) {//클라이언트가 서블릿을 [GET] 방식으로 요청한 경우
			//클라이언트에게 에러코드 전달
			response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);//405 에러코드
			return;
		}
		//리퀘스트 메세지의 몸체부에 저장되어 전달되는 값(POST)에 대한 캐릭터셋 변경
		request.setCharacterEncoding("utf-8");
		//
		//전달값(게시글)을 반환받아 저장
		//→ String.trim() 메소드를 호출하여 전달값의 앞 또는 뒤에 존재하는 모든 공백 제거
		//→ String.replace() 메소드를 호출하여 XSS 공격에 대한 방어를 위해 태그 관련 기호를 회피문자(Escape Charter)로 변환
		//XSS(Cross Site Scripting) : 입력태그에 악의적인 스트립트를 입력하여 출력페이지를 파괴시키거나 개인정보를 특정 사이트로 유출하는 웹사이트 공격 방법 
		String name=request.getParameter("name").trim().replace("<", "&lt;").replace(">", "&gt;");
		String title=request.getParameter("title").trim().replace("<", "&lt;").replace(">", "&gt;");
		String content=request.getParameter("content").trim().replace("<", "&lt;").replace(">", "&gt;");
		//
		//DTO 객체를 생성하여 전달값으로 필드값 변경
		GuestDTO guest=new GuestDTO();
		guest.setName(name);
		guest.setTitle(title);
		guest.setContent(content);
		//
		//게시글(GuestDTO 객체)을 전달받아 GUEST 테이블에 삽입하는 DAO 클래스의 메소드 호출
		GuestDAO.getDAO().insertGuest(guest);
		//
		//클라이언트에게 301 상태코드와 URL 주소 전달
		response.sendRedirect("select.itwill");//리다이렉트 이동
	}
}

🎨 6.delete.itwill 만들기

📌 게시글목록 출력페이지(select.itwill)에서 전달된 글번호를 반환받아 GUEST 테이블에 저장된 해당 글번호의 게시글을 삭제하고 게시글목록 출력페이지(select.itwill)로 이동하기 위한 URL 주소 전달하는 서블릿 - 글번호 전달

📃GuestDeleteServlet.java

package xyz.itwill.servlet;
//
import java.io.IOException;
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 xyz.itwill.dao.GuestDAO;
//
//게시글목록 출력페이지(select.itwill)에서  전달된 글번호를 반환받아 GUEST 테이블에 저장된 해당
//글번호의 게시글을 삭제하고 게시글목록 출력페이지(select.itwill)로 이동하기 위한 URL 주소 전달하는 서블릿 - 글번호 전달
@WebServlet("/delete.itwill")
public class GuestDeleteServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	//
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//비정상적인 요청에 대한 처리
		if(request.getParameter("no")==null) {//전달값이 없는 경우
			response.sendError(HttpServletResponse.SC_BAD_REQUEST);//400 에러코드
			return;
		}
		//
		//전달값(글번호)을 반환받아 저장 - 문자열 >> 정수값
		int no=Integer.parseInt(request.getParameter("no"));
		//
		//글번호를 전달받아 GUEST 테이블에 저장된 해당 글번호의 게시글을 삭제하는 DAO 클래스의 메소드 호출
		int rows=GuestDAO.getDAO().deleteGuest(no);
		//
		if(rows>0) {//삭제행이 있는 경우
			response.sendRedirect("select.itwill");
		} else {//삭제행이 없는 경우 - 비정상적인 요청
			response.sendError(HttpServletResponse.SC_BAD_REQUEST);
		}
	}
}

0개의 댓글