[JSP/JAVA] MVC 패턴 2 게시판 만들기
안녕하세요 !
오늘은 MVC 패턴에 대해서 공부해볼건데요 !
JSP로 게시판을 만들면서 실질적인 코드도 함께 확인해보겠습니다 !
MVC패턴
- Model, View, Controller 로 구성되어있다.
- Model : 데이터 베이스와 연동하는 부분 등의 로직 부분
- View : 화면을 출력해주는 부분
- Controller : Model과 View 를 적절하게 연결시켜주는 역할
< 설명 >
User가 Controller에 요청하면 Controller는 Model에 접근합니다.
Model은 DB에 접근해서 User가 요청한 데이터를 전달하는데,
이때 Controller를 통해 View에 전달해서 User에게 보여주게됩니다.
그럼 이제 MVC 패턴 게시판을 만들어볼까요?
파일 구성은 다음과 같습니다.
( 파일 타입 참고 )
Java Resources > java
net.board.action : 패키지
Action : 인터페이스
ActionForward : 클래스
BoardFrontController : Servlet
net.board.db 패키지
( 클래스 )
src
webapp
board
( jsp 파일 )
boardUpload
META_INF
context.xml
WEB-INF
lib
cos, jstl, ojdbc6, servlet-api, standard, xalan
web.xml
sql파일
net.board.action 패키지 안에 Action Interface와 ActionForward를 생성해줍니다.
BoardFrontController는 Controller가 될겁니다.
net.board.action 안에 들어있는 클래스들은 데이터베이스에 접근하는 페이지들이 요구하는 데이터를 처리해주는 command Class 가 되겠습니다.
net.board.db 안에 있는 BoardDAO는 DAO ( Data Access Object ) 로 데이터 객체에 접근하는 클래스이며,
BoardBean은 DTO ( Data Transfer Object ) 로 계층 간 데이터 교환을 위한 Java Beans입니다.
( DTO는 로직을 가지고 있지 않은 데이터 객체이며, 객체 속성과 Getter & Setter 메소드를 가지고 있습니다. )
시작 전 lib에 필요한 jar 파일들을 받아주세요 !
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>
<display-name>1017Board</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>
BoardFrontController.java
package net.board.action;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BoardFrontController
extends javax.servlet.http.HttpServlet
implements javax.servlet.Servlet {
protected void doProcess(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String RequestURI=request.getRequestURI();
String contextPath=request.getContextPath();
String command=RequestURI.substring(contextPath.length());
ActionForward forward=null;
Action action=null;
if(command.equals("/BoardWrite.bo")){
forward=new ActionForward();
forward.setRedirect(false);
forward.setPath("./board/qna_board_write.jsp");
}else if(command.equals("/BoardReplyAction.bo")){
action = new BoardReplyView();
try{
forward=action.execute(request, response);
}catch(Exception e){
e.printStackTrace();
}
}else if(command.equals("/BoardDelete.bo")){
forward=new ActionForward();
forward.setRedirect(false);
forward.setPath("./board/qna_board_delete.jsp");
}else if(command.equals("/BoardModify.bo")){
action = new BoardModifyView();
try{
forward=action.execute(request, response);
}catch(Exception e){
e.printStackTrace();
}
}else if(command.equals("/BoardAddAction.bo")){
action = new BoardAddAction();
try {
forward=action.execute(request, response );
} catch (Exception e) {
e.printStackTrace();
}
}else if(command.equals("/BoardReplyView.bo")){
action = new BoardReplyAction();
try{
forward=action.execute(request, response);
}catch(Exception e){
e.printStackTrace();
}
}else if(command.equals("/BoardModifyAction.bo")){
action = new BoardModifyAction();
try{
forward=action.execute(request, response);
}catch(Exception e){
e.printStackTrace();
}
}else if(command.equals("/BoardDeleteAction.bo")){
action = new BoardDeleteAction();
try{
forward=action.execute(request, response);
}catch(Exception e){
e.printStackTrace();
}
}else if(command.equals("/BoardList.bo")){
action = new BoardListAction();
try{
forward=action.execute(request, response);
}catch(Exception e){
e.printStackTrace();
}
}else if(command.equals("/BoardDetailAction.bo")){
action = new BoardDetailAction();
try{
forward=action.execute(request, response);
}catch(Exception e){
e.printStackTrace();
}
}
if(forward.isRedirect()){
response.sendRedirect(forward.getPath());
}else{
RequestDispatcher dispatcher=
request.getRequestDispatcher(forward.getPath());
dispatcher.forward(request, response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doProcess(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doProcess(request,response);
}
}
Action.java
package net.board.action;
import javax.servlet.http.*;
public interface Action {
public ActionForward execute(HttpServletRequest request,HttpServletResponse response) throws Exception;
}
ActionForward.java
package net.board.action;
public class ActionForward {
// redirect를 할지 말지에 대한 여부 : true면 redirect
private boolean isRedirect=false;
// redirect 할 대상 url / 자원 경로
private String path=null;
public boolean isRedirect(){
return isRedirect;
}
public String getPath(){
return path;
}
public void setRedirect(boolean isRedirect){
this.isRedirect=isRedirect;
}
public void setPath(String string){
path=string;
}
}
< 코드 설명 >
BoardFrontController에서 url 요청을 받게됩니다.
Action Interface를 가져와서 null값을 할당하고
해당 url 요청에 걸렸을 때 action에 request와 response를 넣어주도록 합니다.
특정 url이 요청되면 해당 ActionClass(command Class, Controller)를 할당합니다.
페이지가 데이터를 요청한다면 DAO를 활용해서 DB에 접근합니다.
BoardBean(DTO)를 이용해서 DB에 데이터를 저장 / 삭제 / 조회 / 수정 하게됩니다.
로직을 다 수행한 뒤 포워딩을 수행하게됩니다.
( 포워딩 : 현재 요청을 다른 자원(jsp)으로 전달하고, 클라이언트에게는 새로운 URL로 이동했음을 알리지 않는다. )
jsp(View)를 보여주게되는데 이때 jsp로 Model에서 설정해준 데이터들을 보내줍니다.
파일이 꽤 많기 때문에 코드 대신 파일로 첨부하도록 하겠습니다 !
필요하신 분들은 다운로드 하여 확인해주시면 될 것 같습니다.
꽤 복잡하다보니 흐름도를 그리면서 이해하는 게 나중에 다시 볼 때도 좋을 것 같았습니다.
흐름도를 통해 어느 부분에서 데이터를 요청하고 요청받고 처리하는 과정을 쉽게 이해할 수 있었습니다.
MVC_BOARD | Figma Community
www.figma.com
위 링크에 작성해두었으니 대략적인 흐름도를 확인하고 싶으신 분들은 참고하시면 될 것 같습니다 !
오늘도 수고하셨습니다.
감사합니다 ! (´▽`ʃ♡ƪ)