Java - Spring &&n SpringBoot

Spring MVC 패턴 && dispatcher

TerianP 2022. 7. 18.
728x90

MVC 패턴이란?

  • MVC 패턴은 모델 2 방식이라고도 불림
  • Controller : 요청 request 가 들어온 후 Model 에서 만들어진 데이터를 다음에 어디로 넘길지 지정해주는 역할
  • View : Controller 를 통해 전달받아온 데이터를 클라이언트 화면에 보여주는 역할
  • Model : 데이터를 만들거나 데이터를 비교하거나 DB 에서 데이터를 가져오는 등 의 작업을 하는 역할

MVC 에 대해서 기억해야하는 것들

  • Model 과 controller 에서 페이지를 이동할때는 파라미터를 달아서 넘길 수 없음?
    • 따라서 파라미터 대신 setAttr 을 이용해서 내용을 담아서 값을 넘김
  • Model 은 execute 를 사용함. 이때 execute 는 HttpServletRequest, HttpServletResponse 를 매개변수로 받는다. 때문에 프론트 view 에서 Controller 로 넘어온 Request 와 Response 를 매개변수로 받아서 사용하는게 기본!
    • 이때 view 에서 넘어온 그대로를 갖기 때문에 execute 에서 Request 로 넘어온 파라미터 값을 그대로 사용할 수 있다.
    • 또한 view 로 넘어가야하는 데이터를 execute 메소드 안에서 request.setAttr 을 이용해 담는다.
  • Model 을 통해서 지정되는 경로는(return 값) Controller 에서 사용되는 경로의 방법을 적는다(아마도)
    • Controller 에서 파라미터를 사용해서 경로를 지정, 이동한다면 model 에서 return 되는 경로도 이와 동일하게 파라미터를 적어서 넘겨주어야 한다.
    • 만약 실제 경로에 있는 페이지를 사용한다면 마찬가지로 - html, jsp - 를 지정해주어야 함 ⇒ return "views/list.jsp";
    • 파라미터를 사용하여 페이지를 이동하는 예시, 그에 따른 model 구성

Controller

package kr.co.mvc.control;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
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 kr.co.mvc.action.Action;

// 
// mvcboard/board.html?cmd=list => 전체목록
@WebServlet("/board.html")
public class MyController extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 1. 한글처리
		req.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=UTF-8");
		
		String cmd = req.getParameter("cmd");
		String url = "";
		Action action = null;
		
		
		if(cmd == null || cmd.equals("list")) {
			// 전체 목록 보기
			action = new ListAction();
			url = action.execute(req, resp);
		}else if(cmd.equals("detail")) {
			// 상세보기			
			action = new DetailAction();
			url = action.execute(req, resp);
		}else if(cmd.equals("writeForm")) {
			// 글쓰기
			action = new WriteForm();
			url = action.execute(req, resp);
			
		}else if(cmd.equals("writeOk")) {
			// 글쓰기 완료
			action = new WriteOk();
			url = action.execute(req, resp);
		}else if(cmd.equals("modifyForm")) {
			// 수정하기
			action = new ModifyForm();
			url = action.execute(req, resp);
			
		}else if(cmd.equals("modifyOk")) {
			// 수정 완료
			action = new modifyOk();
			url = action.execute(req, resp);
			
		}else if(cmd.equals("delete")) {
			// 삭제
			action = new Delete();
			url = action.execute(req, resp);
		}
		
		RequestDispatcher rd = req.getRequestDispatcher(url);
		rd.forward(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
	}

}

Model - writeOk

controller 에서 /board.html 로 요청을 받고 cmd 라는 파라미터를 이용해 페이지를 이동함으로 이에 맞춰서 model 에서도 해당 페이지와 파라미터를 이용해서 작성한다

package kr.co.mvc.control;

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

import dao.BoardDAO;
import dto.BoardVO;
import kr.co.mvc.action.Action;

public class WriteOk implements Action {

	@Override
	public String execute(HttpServletRequest req, HttpServletResponse resp) {
		// TODO Auto-generated method stub
		String title = req.getParameter("title");
		String writer = req.getParameter("writer");
		String contents = req.getParameter("contents");
		
		System.out.println("title : "+title);
		System.out.println("writer : "+writer);
		System.out.println("contents : "+contents);
		
		BoardVO vo = new BoardVO();
		vo.setTitle(title);
		vo.setWriter(writer);
		vo.setContents(contents);
		vo.setIp(req.getRemoteAddr());
		
		new BoardDAO().insertBoard(vo);
		
		return "board.html?cmd=list";
	}

}
  • Controller 에서 request.getRequestDispatcher 의 매개변수로 이동할 페이지의 주소를 받는다. 이후 forward 메소드 안에 req 와 resp 를 담아서 view 로 전달한다.
    • 이때 req 안에는 Model 에서 넣어둔 데이터가 있다?
RequestDispatcher rd = req.getRequestDispatcher(url);
rd.forward(req, resp);

Servlet 과 Dispatcher 를 사용한 request

  • Servlet 은 WebServlet 어노테이션 안에 웹에서 요청 request 한 주소가 들어온다 ⇒ /board.html
  • RequestDispatcher 클래스는 서블릿 또는 JSP 에서 요청을 받은 후 다른 컴포넌트로 동일하게 위임 할 수 있다.
  • RequestDispatcher 클래스의 메소드인 forward 메소드를 사용해서 아래와 같은 기능을 할 수 있다.
    • forward 메소드는 요청 request 에 대한 추가 작업을 다른 서블릿이나 JSP 에게 수행하도록 한다.
    • 요청 request 에 포함된 정보를 다른 서블릿이나 JSP와 를 공유함
    • 요청에 정보를 포함시켜 다른 서블릿에 전달 할 수 있다 ⇒ 모델 2 개발시 서블릿에서 JSP 로 전달하는데 사용됨, 스프링의 경우 html 에 정보를 전달하는 것도 포함
  • 스프링에서는 forward 가 없이 이동하는데 이는 Controller 어노테이션에 기본적으로 달려있는게 아닌가 생각한다
  • request 객체에서 RemoteAddr 과 LocalAddr 두 가지가 있는데
    • Remote 는 원격(사용자) 의 ip 주소
    • Local 은 로컬(서버) 의 ip 주소라고 생각하면 됨

Dispatcher

JSP | RequestDispatcher 클래스 ☆☆☆ | Java Servlet Fowarding 서블릿 포워드 기능 | HttpServletResponse 클래스

 

JSP | RequestDispatcher 클래스 ☆☆☆ | Java Servlet Fowarding 서블릿 포워드 기능 | HttpServletResponse 클래스

RequestDispatcher 클래스 서블릿 포워드 기능 1. 포워드 기능 : 하나의 서블릿에서 다른 서블릿이나 JSP와 연동하는 방법 2. 포워드 용도 : -요청(request)에 대한 추가 작업을 다른 서블릿에게 수행하게

kjh95.tistory.com

  • Dispatcher 를 이용한 forward
package Controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 서블릿 작성 방법
// 1. HttpServlet 상속
// 2. doGet() or doPost() override
// 3. @WebServlet

/**
 * Servlet implementation class MyController
 */
@WebServlet("/MyController")
public class MyController extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1. 한글처리
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		
		// 2. cmd 파라미터 값 가져오기
		String cmd = request.getParameter("cmd");
		
		// 3. 찾아가야할 페이지 url 를 갖는 변수 && 전달 데이터를 담을 변수 msg
		String url = "";
		String msg = "";
		
		if(cmd == null || cmd.equals("hello")) 
		{
			msg = "안녕하세요"	;
			url = "day01/hello.jsp";
			request.setAttribute("msg", msg);
		}
		
		// 4. url 로 forward
		// dispatcher 에 넣어둔 url 로 페이지를 이동함
		RequestDispatcher rd = request.getRequestDispatcher(url);
		rd.forward(request, response);
	}
}

Controller 사용하기

  • 페이지 이동 담당
    • 말 그대로 어디에서 들어와서 들어와서 어디로 나갈껀지 정해주는 역할
    • 어디에서 부분은 WebServlet 어노테이션에서 정해지고
    • 어디로 나갈껀지는 url 과 getRequestDispatcher, forward 를 통해서 정한다
package controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.servlet.RequestDispatcher;
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 model.DeptCommand;
import model.IPCommand;
import model.InsertDeptCommand;
import model.InsertDeptOk;
import model.TimeCommand;

@WebServlet("/MyController2")
public class MyController2 extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 1. 한글처리
		req.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=UTF-8");
		
		// cmd=kr => korea.jsp
		
		String cmd = req.getParameter("cmd");
		String msg = "";
		String url = "";
		
		if(cmd == null || cmd.equals("hello")) 
		{
			// model 없이 사용하기
			url = "/day01/hello.jsp";
			msg = "안녕하세요 자바 월드";
			req.setAttribute("msg", msg);
			
		}else if(cmd.equals("ip")) { // model 포함해서 사용하기
			url = new IPCommand().execute(req, resp);
			
		}else if(cmd.equals("time")) {
			url = new TimeCommand().execute(req, resp);
		}else if(cmd.equals("dept")) {
			url = new DeptCommand().execute(req, resp);
		}else if(cmd.equals("insertDept")) {
			url = new InsertDeptCommand().execute(req, resp);
		}else if(cmd.equals("insertDeptOk")) {
			url = new InsertDeptOk().execute(req, resp);
		}
		
		// rd 에 req 와 resp 를 담아서 전달
		RequestDispatcher rd = req.getRequestDispatcher(url);
		rd.forward(req, resp);
	}
}

Model 사용하기

  • insert Dept
package model;

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

import dao.DeptDAO;

public class InsertDeptOk implements ActionCommand{
	
	@Override
	public String execute(HttpServletRequest req, HttpServletResponse resp) {
		// TODO Auto-generated method stub
		String dname = req.getParameter("dname");
		String loc = req.getParameter("loc");
		System.out.println(dname+" : "+loc);
		
		new DeptDAO().insertOne(dname, loc);
		
		// 어디로 이동할건지 지정
		return "day01/hello.jsp";
	}
}
  • Dept List
package model;

import java.util.ArrayList;

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

import dao.DeptDAO;
import vo.DeptVO;

public class DeptCommand implements ActionCommand{
	@Override
	public String execute(HttpServletRequest req, HttpServletResponse resp) {
		
		ArrayList<DeptVO> list = new DeptDAO().getAll();
		
		req.setAttribute("list", list);
		
		return "day02/dept.jsp";
	}
}

View 사용하기

  • view 단의 jsp 에서는 JSTL 을 사용해서 만든다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>list.jsp</title>
</head>
<body>
	<h1>게시판 목록</h1>
	<a href="board.html?cmd=writeForm"><input type="button" value="글쓰기" class="btn btn-outline-dark"></a>
	<div class="container">
	<table class="table">
		<tr>
			<th>제목</th>
			<th>내용</th>
			<th>작성자</th>
			<th>조회수</th>
			<th>IP</th>
		</tr>
// JSTL 반복문
	<c:forEach var="list" items="${list }">
		<tr>
			<th>${list.title }</th>
			<th><a href="?cmd=detail&bno=${list.bno}">${list.contents }</a></th>
			<th>${list.writer }</th>			
			<th>${list.hits }</th>			
			<th>${list.ip }</th>			
		</tr>
		</c:forEach>
	</table>
	</div>
</body>
</html>
         
         

- Reference

[개발자 면접준비]#1. MVC패턴이란

 

[개발자 면접준비]#1. MVC패턴이란

오늘은 개발자면접에 많이 나오기도 하는 MVC패턴에 대해서 알아보고자 합니다. 과연 MVC패턴이 무엇...

blog.naver.com

https://velog.io/@seongwon97/MVC-%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%9E%80

 

MVC 패턴이란?

모델-뷰-컨트롤러(model–view–controller, MVC)는 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴이다.

velog.io

 

댓글