티스토리 뷰

 

CHAPTER 18. 웹 MVC : 게시판 만들기

 

 

 

 

 

 

 

1. MVC 개요 

 

MVC는 Model, View, Controller의 약자이다.

MVC는 웹 애플리케이션을 비즈니스 로직, 프레젠테이션 로직, 데이터로 분리하는 디자인 패턴이다.

웹 애플리케이션에서는 보통 비즈니스 로직, 프레젠테이션, 요청 처리 데이터로 분류하고

비즈니스 로직은 애플리케이션의 데이터, 고객, 제품, 주문 정보의 조작에 사용되는 용어이다.

마지막으로 프레젠테이션은 애플리케이션이 사용자에게 어떻게 표시되는지 위치, 폰트, 크기를 나타낸다.

 

 

- 모델(model) : 애플리케이션의 데이터와 비즈니스 로직(=특정함수)을 담는 객체이다. (DB, DAO)

 

- 뷰(view) : 사용자에게 모델의 정보(데이터)를 보여주는 역할을 한다. 비즈니스 로직을 포함하지 않으며, 하나의 모델을 다양한 뷰에서 사용할 수 있다.

 

- 컨트롤러(controller) : 모델과 뷰 사이에 어떤 동작이 있을 때 조정하는 역할을 한다. 웹으로부터 받은 요청에 가장 적합한 모델을 생성하는 것을 처리하는 역할과 사용자에게 응답하는 적절한 뷰를 선택해 해당 모델을 전달하는 역할을 한다.

 

 

 

 

 

 

2. MVC 패턴 구조

 

요청처리 방식에 따라 MVC의 모델은 두가지가 있다.

 

2-1. 모델 1

 

기존의 JSP로만 구현한 웹 애플리케이션이다.

지금까지 우리가 실습하고 배운 방식들이 모델 1에 해당한다.

웹 브라우저의 요청을 JSP 페이지가 받아서 처리하는 구조로 JSP페이지에 비즈니스 로직을 처리하는 코드와 웹 브라우저애 결과를 출력하는 코드가 섞인다.

 

JSP가 핵심 역할을 수행하고 웹 브라우저가 요청한 작업을 자바빈즈나 서비스 클래스를 사용하여 처리한다.

웹 브라우저의 요청을 수행하고 JSP에 응답을 전달하는 자바빈즈 객체를 생성한 후 클라이언트에 응답을 보낸다.

과정들을 보아 대부분 처리가 JSP 자체에 의해 수행된다.

 

복잡한 설정이 없어 배우기 쉽지만 코드가 섞여 있어 복잡하고 유지 보수가 어렵다는 단점이 있다.

 

 

 

 

 

2-2. 모델 2

 

클라이언트의 요청 처리, 응답 처리, 비즈니스 로직 처리 부분을 모듈화한 구조이다.

웹 브라우저의 요청이 들어오면 요청에 대한 로직을 처리할 자바빈즈 혹은 자바 클래스인 모델, 요청 결과를 출력하는 JSP 페이지인 뷰, 모든 흐름 제어는 서블릿인 컨트롤러로 나뉘어 웹 브라우저가 요청한 작업을 처리한다.

 

모델 2는 1과 달리 서블릿이 중요한 역할을 하는데 하나의 서블릿이 요청한 모든 작업을 처리하기 때문이다.

요청에 맞게 처리한 후 그 결과를 보여줄 JSP 페이지로 포워딩하고 이것을 통해 요청 흐름을 받은 JSP 페이지는 결과 화면을 웹 브라우저에 전송한다.

(서블릿이 비즈니스 로직 부분을 처리한다.)

 

 

 

 

 

 

 

 

 

 

3. MVC 패턴 구현 방법

 

 

 

3-1. web.xml 파일에 서블릿 구성하기

 

웹 MVC에서는 클라이언트로부터 컨트롤러인 서블릿을 통해 요청을 받아야 한다.

요청을 받기 위해 web.xml에 서블릿 클래스와 웹 브라우저의 요청 URL 패턴을 등록해야 한다.

 

 

<servlet> 요소로 서블릿 클래스 등록하기

웹 애플리케이션에서 사용될 기본 서블릿 객체와 매개변수를 설정하는 요소이다.

 <servlet>
  	<servlet-name>서블릿 이름</servlet-name>
  	<servlet-class>서블릿 클래스(패키지 이름.클래스)</servlet-class>
    [<init-param>
    	<param-name>매개변수 이름</param-name>
        <param-value>매개변수 값</param-value>
	</init-param>]
  </servlet>

 

 

 

 

<servlet-mapping> 요소로 요청 URL 패턴 설정하기

 

웹 브라우저에 요청되는 URL과 서블릿 클래스를 매핑하기 위해 URL 패턴을 설정하는 요소이다.

  <servlet-mapping>
  	<servlet-name>서블릿 이름</servlet-name>
  	<url-pattern>요청할 URL 패턴</url-pattern>
  </servlet-mapping>

 

웹 브라우저의 모든 요청 URL과 서블릿 클래스를 매핑하도록 URL 패턴을 설정하는 것이다.

설정된 패턴으로 요청을 하면 servlet-class에 작성되어진 서블릿 클래스도 이동을 한다.

 

웹 브라우저의  요청은 http://localhost:8080/mvc_1/first 일때 URL패턴은 프로젝트 명인 mvc_1/ 이후부터 해당된다.

이를 서블릿 클래스가 처리한다.

 

 

 

 

 

 

3-2. 컨트롤러 생성하기

 

컨트롤러는 뷰와 모델 간의 인터페이스 역할을 한다.

웹 브라우저의 모든 요청 URL을 받아들이고 요청 URL과 함께 전달되는 파라미터를 받아 처리하는 서블릿 클래스이다.

컨트롤러는 요청된 데이터를 처리하기 위해 모델로 보내고 처리된 결과를 받아서 응답할 JSP 페이지로 이동한다.

 

- 서블릿 클래스 생성하기 

서블릿 클래스는 HttpServlet 클래스를 확장해 생성한다.

생성된 서블릿 클래스는 웹 브라우저에서 전송되는 Get 방식과 Post 방식에 따라 각 각 doGet(), doPost() 메소드를 통해 요청 작업을 수행한 후 웹 브라우저에 응답한다.

 

public class test1 extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//get방식
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//post방식
	}

}

 

 

 

 

 

 

 

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" version="4.0">
  <display-name>mvc_1</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>mycontroller</servlet-name>
  	<servlet-class>controller.test_controller</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>mycontroller</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>
  
</web-app>

 

web.xml에 서블릿을 구성했다.

name은 두개를 통일 시키고 url 패턴을 /로 설정해주었다.

url패턴을 통해 이동할 서블릿 클래스를 작성해주었다.

 

 

 

test_controller

package controller;

import java.io.IOException;

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

public class test_controller extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request,response); 
		//get방식으로 해도 doPost에서 다 실행됨
		//dopost로 이동하도록 설정했기때문에 get방식으로 들어와도 post로 이동한다.
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("test_controller 입니다.");
	}

}

 

서블릿 클래스는 HttpServlet 클래스를 확장해 생성했다.

doGet()을 실행하면 doPost()로 이동하여 실행하도록 하여 어떠한 방식을 사용하든지 doPost()를 사용하도록 해주었다.

 

 

 

 

 

서버를 실행하면 나타나는 URL 주소 창이다.

패턴을 /로 설정했기 때문에 제대로 설정이되어 있다는 것을 볼 수 있다.

 

 

 

doPost()가 실행되어 콘솔에 입력한 문자가 출력된 것을 볼 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

test_controller_abc

package controller;

import java.io.IOException;

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

public class test_controller_abc extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req,resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("abc입니다.");
	}

}

 

 

web.xml

 <servlet>
  	<servlet-name>mycontroller_1</servlet-name>
  	<servlet-class>controller.test_controller_abc</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>mycontroller_1</servlet-name>
  	<url-pattern>/abc</url-pattern>
  </servlet-mapping>

 

url 패턴을 /abc로 설정해주었기 때문에 프로젝트명/abc 가 존재해야 매핑이 되어 클래스로 이동한다.

 

 

 

설정한 패턴과 일치하지않기 때문에 404 오류가 뜨는 것을 확인할 수 있다.

 

 

 

제대로된 페이지가 실행되지 않았기 때문에 콘솔에도 출력된 문자를 볼 수 없다.

 

 

 

 

 

 

URL 주소창에 이전에 설정해둔 URL 패턴을 작성해주었다.

그러니 이전에 발생했던 오류가 발생하지 않는 것을 볼 수 있었다.

 

 

 

 

또한, 콘솔에도 문자가 출력된 것을 볼 수 있다.

 

 

 

 

 

 

 

 

 

abc.java

 

package controller;

import java.io.IOException;

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

public class abc extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req,resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("abc");
	}

}

 

 

web.xml

  <servlet>
  	<servlet-name>abc_1</servlet-name>
  	<servlet-class>controller.abc</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>abc_1</servlet-name>
  	<url-pattern>*.do</url-pattern>
  </servlet-mapping>

 

 

 

 

 

 

 

 

 

 

 

 

- 자동으로 생성하는 방법

 

test_controller_annotaion.java

package controller;

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;

@WebServlet("/ano")  //클래스에대해 서블렛을 붙여버림 ano로 매핑(자동으로하는법)
public class test_controller_annotation extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req,resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("출력");
	}
	
}

 

자동으로 생성하는 방법을 사용해보았다.

이전에서는 web.xml에서 모두 작성한 후 실행을 해주었지만 자동 생성은 java 코드 위에 @WebServlet("/ano")를 작성해 자동으로 생성해주었다.

이러한 방법을 사용하면 xml에 작성한 것과 같이 url패턴을 /ano로 설정하고 설정 값에 맞는 url 일 경우 클래스를 생성하고 실행하도록 해준다.

자동화 방식은 간단하지만 수동으로 작성하는 방법을 더 추천한다.

많은 것을 축약하고 있기 때문에 구조를 이해하지 못할 수 있기 때문이다.

 

 

 

 

 

url 주소에 ano가 작성되어 실행되는 것을 볼 수 있다.

 

 

 

 

 

 

 

 

- 페이지 이동하기

서블릿 클래스에서 웹 브라우저로부터 요청된 처리 결과를 보여줄 응답 페이지로 이동하는 것이다.

현재 뷰 페이지에서 이동할 뷰 페이지에 요청 정보를 그대로 전달하고 뷰 페이지가 이동해도 처음에 요청된URL을 계속 유지하기 위해 포워딩 방식을 사용한다.

 

 

		RequestDispatcher dispatcher = req.getRequestDispatcher("/first/one/one.jsp");
		dispatcher.forward(req,resp);

 

 

 

 

 

 

test1.java

package class_first;

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;

@WebServlet("/first")
public class test1 extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("퍼스트입니다.");
		RequestDispatcher dispatcher = req.getRequestDispatcher("/first/one/one.jsp");
		dispatcher.forward(req,resp);
	}

}

 

 

one.jsp

<%@ 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>
</head>
<body>
원 입니다.
<a href="/mvc_1/first/two/two.jsp">two 페이지로 이동하기</a>  
<!--a태그에서는 절대경로 지정시 프로젝트 이름 써야함  -->
</body>
</html>

 

 

 

 

two.jsp

 

<%@ 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>
</head>
<body>
투 입니다.
</body>
</html>

 

 

 

 

 

 

 

 

3-4. 뷰 생성하기

뷰는 웹 브라우저의 요청을 처리한 결과를 사용자에게 보여주는 JSP 페이지를 의미한다.

JSP가 제공하는 태그를 사용하여 컨트롤러가 전송한 모델 데이터를 웹 브라웆에 출력한다.

 

 

MVC를 적용한 로그인 인증하기

예제 18-1

 

web.xml

   <servlet>
	   <servlet-name>mycontroller</servlet-name>
	   <servlet-class>controller.controllerservlet</servlet-class>
   </servlet>
   <servlet-mapping>
	   <servlet-name>mycontroller</servlet-name>
	   <url-pattern>/controllerservlet</url-pattern>
   </servlet-mapping>

 

url 주소가 /controllerservlet 으로 끝나면 controller.controllerservlet 클래스를 가져온다.

 

 

 

loginbean.java

package controller;

public class loginbean {
	private String id;
	private String password;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	public boolean validate() {
		if(password.equals("admin")) {
			return true;
		}
		else {
			return false;
		}
	}
	
}

 

 

 

 

 

controllerservlet.java

package controller;

import java.io.IOException;

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

public class controllerservlet extends HttpServlet{
	
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		doPost(request, response);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html; charset=utf-8");
		
		String id = request.getParameter("id");
		String password=request.getParameter("passwd");
		
		loginbean bean = new loginbean();
		bean.setId(id);
		bean.setPassword(password);
		request.setAttribute("bean",bean);
		
		boolean status = bean.validate();
		
		if(status) {
			RequestDispatcher rd = request.getRequestDispatcher("mvc_success.jsp");
			rd.forward(request, response);
		}else {
			RequestDispatcher rd = request.getRequestDispatcher("mvc_error.jsp");
			rd.forward(request,response);
		}
	}
	
	
}

 

 

mvc.jsp

<%@ 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>
</head>
<body>
	<form action="/mvc_1/controllerservlet" method="post">
		<p> 아이디 : <input type="text" name="id">
		<p> 비밀번호 : <input type="password" name="passwd">
		<p> <input type="submit" value="전송">
	</form>
</body>
</html>

 

form 을 제출하면 url 주소가 /mvc_1/controllerservlet이 되어 이동한다.

 

 

mvc_success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="controller.loginbean" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<p> 로그인 성공했습니다.
	<p> <%
		loginbean bean = (loginbean) request.getAttribute("bean");
		out.println("아이디 : " +bean.getId());
	%>
</body>
</html>

 

 

mvc_error.jsp

<%@ 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>
</head>
<body>
	<p> 아이디와 비밀번호를 확인해주세요.
	<%@include file="mvc.jsp" %>
</body>
</html>

 

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday