지난 시간에 MVC Model2로 게시판을 만들어 보았습니다.
못 보신 분들을 위해 아래에 링크 첨부하겠습니다.
[JSP] MVC Model2 게시판 만들기 ①
Servlet, JSP, JavaBeans, JDBC를 활용하여 게시판을 구현해 보겠습니다. Model2에 대해 모르시는 분들을 위해 아래에 지난 포스팅 글 첨부하겠습니다. [JSP] MVC 패턴이란? Model1과 Model2 비교 1. MVC 패턴이란?
recordevelop.tistory.com
이번 시간에는 게시판 기능을 구현해 보겠습니다.
1. View
사용자에게 처음 보이는 화면입니다.
회원가입을 누르면
회원가입이 가능한 페이지로 이동합니다.
유효성 검사도 되어 있는 것을 확인할 수 있습니다.
일반 유저, admin 계정 둘 다 회원가입을 해보겠습니다.
회원가입을 하면 연동했던 Oracle DB에 데이터가 잘 들어간 것을 확인할 수 있습니다.
▶ 일반 유저 접속
일반 유저로 접속하면 게시판이 나오고 글쓰기를 누르면 글을 쓸 수 있습니다.
이렇게 글을 쓰고 등록을 누르면
글이 성공적으로 등록된 것을 확인할 수 있습니다.
글 번호와 제목, 작성자, 날짜, 조회수까지 확인할 수 있고 게시판 글 개수를 나타내는 기능도 있습니다.
제목을 클릭하면
본인이 쓴 글에 대해 답변, 수정, 삭제, 목록 기능이 있습니다.
● 답변
기존에 썼던 글에 답변을 달아보겠습니다.
답변이 성공적으로 달아지는 것을 확인할 수 있습니다.
● 수정
수정 버튼을 누르면 수정할 수 있습니다.
수정 버튼을 누르면
수정이 되는 것을 확인할 수 있습니다.
● 삭제
삭제를 누르면 글 비밀번호를 입력하게 됩니다.
글이 지워지고 글에 대한 답변 글만 남아 있는 것을 확인할 수 있습니다.
이제 admin 계정으로 로그인 해보겠습니다.
▶ admin 계정 접속
admin 계정으로 로그인하면 일반 유저가 쓴 글을 확인할 수 있고
관리자모드로 회원 목록 조회 기능도 있습니다.
관리자모드를 클릭해 보겠습니다.
현재 회원목록이 나오고 삭제가 가능합니다.
삭제를 누르면 일반 유저가 삭제가 되고
Member 테이블에 있던 일반 유저가 삭제가 된 것을 확인할 수 있습니다.
● 기능 설명
- admin 계정으로 로그인하면 관리자 페이지가 나옵니다.
- admin 계정이 아닌 일반 계정이면 게시판으로 들어갑니다.
- 회원가입, 글 쓰기, 글 수정, 글 삭제 등 기능이 구현되어 있습니다.
● 디렉토리 구성
▶ net.board.action
- BoardAddAction : 새 게시글 작성을 위한 액션 클래스
- BoardDeleteAction : 게시글 삭제를 위한 액션 클래스
- BoardDetailAction : 게시글 상세 내용 표시 액션 클래스
- BoardFrontController(*.bo) : 매핑된 url request를 Model과 연결시켜주기 위한 Servlet
(request에 대한 response를 할 때 forward 방식인지 sendRedirect 방식인지도 결정)
- BoardListAction : 게시글 목록을 표시하기 위한 액션 클래스
- BoardModifyAction : 수정할 내용 입력 후에 수정 버튼을 눌렀을 때 처리하는 액션 클래스
- BoardModifyView : 게시글 상세 내용에서 수정을 눌렀을 때 이전의 값들이 불러와지는지 판단하는 액션 클래스
- BoardReplyAction : 게시글 답변 내용 입력 후 답변 완료 버튼을 눌렀을 때 처리되는 액션 클래스
- BoardRelyView : 게시글 상세 내용에서 답변을 눌렀을 때 이전 값들이 불러와지는지 판단하는 액션 클래스
▶ net.board.db
- BoardBean : 게시판 데이터 클래스
- BoardDAO : 비즈니스 로직과 쿼리문을 보내기 위한 클래스
▶ net.member.action
- MemberDeleteAction : 회원 삭제를 위한 액션 클래스
- MemberFrontController(*.me) : 매핑된 url request를 Model과 연결시켜주기 위한 Servlet
(request에 대한 response를 할 때 forward 방식인지 sendRedirect 방식인지도 결정)
- MemberInfoAction : 회원 정보를 보기 위한 액션 클래스
- MemberJoinAction : 회원가입 처리를 위한 액션 클래스
- MemberListAction : 회원 목록을 조회를 위한 액션 클래스
- MemberLoginAction : 로그인 판단을 위한 액션 클래스
▶ board
- qna_board_delete : 게시글 삭제를 위한 페이지
- qna_board_list : 게시글 목록이 출력되는 페이지
- qna_board_modify : 게시글 수정을 위한 페이지
- qna_board_reply : 게시글에 대한 답변을 작성하는 페이지
- qna_board_view : 게시판 상세 내용을 표시하기 위한 페이지
- qna_board_write : 새 글을 작성하기 위한 페이지
▶ db
- sqlplus : 쿼리문을 날리기 위한 페이지 (테이블 생성)
▶ error
- registrationFail.jsp : 회원가입 실패 페이지
▶ js
reg.js : 유효성 검사 페이지
▶ member
joinForm.jsp : 회원가입 페이지
main.jsp : 로그인과 회원가입 페이지(메인페이지)
memberInfo.jsp : 관리자로 로그인 시 회원 정보를 보기 위한 페이지
memberList.jsp : 관리자로 로그인 시 회원 목록을 출력하기 위한 페이지
코드가 길어서 war 파일로 첨부하고, 클래스 몇 개만 쓰겠습니다.
● 테이블 생성
CREATE TABLE MEMBER(
MEMBER_NUM NUMBER PRIMARY KEY,
ID VARCHAR2(20) UNIQUE,
PW VARCHAR2(30),
MAIL VARCHAR2(100),
NAME VARCHAR2(30),
ZIPCODE VARCHAR2(10),
ROADADDRESS VARCHAR2(150),
JIBUNADDRESS VARCHAR2(150),
DETAILADDRESS VARCHAR2(150),
YEAR NUMBER,
MONTH NUMBER,
DAY NUMBER,T
INTEREST VARCHAR2(100),
MYSELF VARCHAR2(1000)
);
CREATE TABLE BOARD(
BOARD_NUM INT,
BOARD_NAME VARCHAR(20),
BOARD_PASS VARCHAR(50),
BOARD_SUBJECT VARCHAR(50),
BOARD_CONTENT VARCHAR(2000),
BOARD_FILE VARCHAR(50),
BOARD_RE_REF INT,
BOARD_RE_LEV INT,
BOARD_RE_SEQ INT,
BOARD_READCOUNT INT,
BOARD_DATE DATE,
PRIMARY KEY(BOARD_NUM)
);
코드를 작성하기 전에 테이블 생성을 해줍니다.
● web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
id="WebApp_ID" version="4.0">
<servlet>
<servlet-name>BoardFrontController</servlet-name>
<servlet-class>net.board.action.BoardFrontController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BoardFrontController</servlet-name>
<url-pattern>*.bo</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>MemberFrontController</servlet-name>
<servlet-class>net.member.action.MemberFrontController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MemberFrontController</servlet-name>
<url-pattern>*.me</url-pattern>
</servlet-mapping>
<display-name>Model2-Board</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
<resource-ref>
<description>Connection</description>
<res-ref-name>jdbc/OracleDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
매핑할 내용을 코드로 작성합니다.
● MemberDeleteAction
package net.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.member.db.MemberDAO;
public class MemberDeleteAction implements Action {
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
MemberDAO memberdao = new MemberDAO();
ActionForward forward = new ActionForward();
boolean result = false;
try {
String id = (String)request.getParameter("id");
result = memberdao.memberDelete(id);
if(result == false) {
System.out.println("회원 삭제에 실패하였습니다.");
return null;
}
System.out.println("회원 삭제에 성공하였습니다.");
forward.setRedirect(true);
forward.setPath("./MemberList.me");
return forward;
}catch(Exception e) {
System.out.println("회원 삭제 과정에서 예외가 발생하였습니다.");
e.printStackTrace();
}
return null;
}
}
회원 삭제를 위한 액션 클래스 코드입니다.
● MemberInfoAction
package net.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.member.db.MemberBean;
import net.member.db.MemberDAO;
public class MemberInfoAction implements Action {
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
MemberDAO memberdao = new MemberDAO();
MemberBean memberdata = new MemberBean();
ActionForward forward = new ActionForward();
try {
memberdata.setId(request.getParameter("id"));
MemberBean member = memberdao.memberInfo(memberdata);
request.setAttribute("member", member);
forward.setRedirect(false);
forward.setPath("./member/memberInfo.jsp");
return forward;
}catch(Exception e) {
System.out.println("정보를 가져오는데 예외가 발생했습니다.");
e.printStackTrace();
}
return null;
}
}
회원 정보를 조회하는 액션 클래스 코드입니다.
● MemberJoinAction
package net.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.member.db.MemberDAO;
import net.member.db.MemberBean;
public class MemberJoinAction implements Action {
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) {
MemberDAO memberdao = new MemberDAO();
MemberBean memberdata = new MemberBean();
ActionForward forward = new ActionForward();
memberdata.setId(request.getParameter("id"));
memberdata.setPw(request.getParameter("pw"));
memberdata.setMail(request.getParameter("mail"));
memberdata.setName(request.getParameter("name"));
memberdata.setZipCode(request.getParameter("zipCode"));
memberdata.setRoadAddress(request.getParameter("roadAddress"));
memberdata.setJibunAddress(request.getParameter("jibunAddress"));
memberdata.setDetailAddress(request.getParameter("detailAddress"));
memberdata.setYear(request.getParameter("year"));
memberdata.setMonth(request.getParameter("month"));
memberdata.setDay(request.getParameter("day"));
String[] interests = request.getParameterValues("interest");
if (interests != null) {
memberdata.setInterest(String.join(",", interests));
}
memberdata.setMyself(request.getParameter("myself"));
//주의
boolean result = memberdao.memberInsert(memberdata);
if (!result) {
System.out.println("등록 실패");
forward.setRedirect(true);
forward.setPath("./error/registrationFail.jsp");
return forward;
}
System.out.println("등록 성공");
forward.setRedirect(true);
forward.setPath("./MemberLogin.me");
return forward;
}
}
회원가입 처리를 위한 액션 클래스 코드입니다.
● MemberListAction
package net.member.action;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.member.db.MemberBean;
import net.member.db.MemberDAO;
public class MemberListAction implements Action {
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
MemberDAO memberdao = new MemberDAO();
ActionForward forward = new ActionForward();
// Change this line to use List<MemberBean> type
List<MemberBean> memberlist = memberdao.memberList();
request.setAttribute("memberlist", memberlist);
forward.setRedirect(false);
forward.setPath("./member/memberList.jsp");
return forward;
}
}
회원 목록을 보기 위한 액션 클래스 코드입니다.
● MemberLoginAction
package net.member.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import net.member.db.MemberBean;
import net.member.db.MemberDAO;
public class MemberLoginAction implements Action {
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession();
MemberDAO memberdao = new MemberDAO();
MemberBean memberdata = new MemberBean();
ActionForward forward = new ActionForward();
boolean result = false;
try {
String ID = (String)request.getParameter("id");
String PW = (String)request.getParameter("pw");
result = memberdao.memberLogin(ID, PW);
if(result == false) {
System.out.println("Action : 로그인 실패");
forward.setRedirect(false);
forward.setPath("./member/main.jsp");
return forward;
}
System.out.println("Action : 로그인 성공");
session.setAttribute("id", memberdata.getId());
session.setAttribute("id", ID);
forward.setRedirect(true);
forward.setPath("./BoardList.bo");
return forward;
}catch(Exception e) {
System.out.println("로그인 예외가 발생했습니다.");
e.printStackTrace();
}
return null;
}
}
로그인 판단을 위한 액션 클래스 코드입니다.
나머지 코드도 첨부하면 많이 길어져서
위에 WAR 파일을 Import 해서 실행하시면 다 볼 수 있으니 참고하시면 됩니다.