Spring MVC

zihooy·2023년 6월 14일
0

Spring

목록 보기
2/3
post-thumbnail

Spring MVC에 대해서 알아보자.

🏹 Spring MVC란

Spring MVC는 Spring 프레임워크에서 제공하는 웹 애플리케이션 개발을 위한 모듈이다. MVC는 Model-View-Controller의 약자로, 소프트웨어를 구성하는 주요 요소를 세 가지 역할로 나눈 아키텍처 패턴이다. Spring MVC는 이 패턴을 기반으로 웹 애플리케이션을 개발할 수 있도록 지원한다.

Controller, Model, View

Controller

사용자 요청을 처리하고 적절한 응답을 생성하는 역할을 담당한다. 컨트롤러는 사용자와의 상호작용을 처리하고 비즈니스 로직을 호출하여 데이터를 처리한다.

Model

비즈니스 로직에서 사용되는 데이터이다. 컨트롤러는 모델을 업데이트하고 뷰에 전달하여 화면에 표시할 데이터를 제공한다.

View

사용자에게 데이터를 시각적으로 표시하는 역할을 담당한다. 뷰는 보통 HTML, JSP, Thymeleaf 등의 템플릿 엔진을 사용하여 동적으로 생성된 HTML 페이지를 생성한다.

🏹 코드로 이해하는 Spring MVC (1)

프로젝트 생성

Project Explorer에서 우클릭 > New > Maven 검색 > Maven Projcet 클릭

아래 화면처럼, Catalog에서 Internal 선택 후 org.apache.maven...-webapp 선택


프로젝트 더블 클릭 > JRE System Library > Properties > Java version 선택

pom.xml 수정

spring-core, maven-compiler-plugin 등의 dependency를 추가한다.

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>Spring02</groupId>
    <artifactId>Spring02</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>Spring01 Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
            </plugin>
        </plugins>
    </build>
</project>

web.xml

web.xml은 Java 웹 애플리케이션의 배포 서술자(Deployment Descriptor), 웹 애플리케이션의 구성 및 동작 방식을 설정한다. 웹 애플리케이션은 웹 컨테이너(예: Apache Tomcat)에서 실행되며, 웹 애플리케이션의 배포 서술자는 웹 컨테이너에게 애플리케이션의 구조와 설정 정보를 제공한다.

아래의 코드를 통해 이해해보자.

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">
    <display-name>Archetype Created Web Application</display-name>
    
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <!--dispatcher 설정 -->
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <!--한글 설정 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

<servlet>

서블릿 설정을 정의하는 부분으로, <servlet-name> 요소에는 서블릿의 이름을, <servlet-class> 요소에는 해당 서블릿의 클래스 경로를 지정한다. 이 예시에서는 스프링의 DispatcherServlet을 사용한다.

<servlet-mapping>

서블릿과 URL 패턴 간의 매핑을 설정하는 부분으로, <servlet-name> 요소에는 매핑할 서블릿의 이름을, <url-pattern> 요소에는 해당 서블릿과 매핑될 URL 패턴을 지정한다. 이 예시에서는 모든 요청에 대해 dispatcher 서블릿으로 매핑한다.

<filter><filter-mapping>

필터 설정을 정의하는 부분으로, 필터는 요청과 응답을 가로채서 처리하는 역할을 수행한다. 이 예시에서는 인코딩 필터(CharacterEncodingFilter)를 설정하여 모든 요청과 응답의 문자 인코딩을 UTF-8로 설정한다.

dispatcher-servlet 생성

dispatcher-servlet은 Spring MVC에서 중요한 구성 요소 중 하나로,
웹 애플리케이션의 요청을 받아들이고 적절한 컨트롤러로 전달하는 역할을 수행하는 서블릿이다.

Spring MVC는 web.xml 파일에서 설정된 서블릿 매핑을 통해 dispatcher-servlet을 등록한다. 일반적으로 "dispatcher-servlet"이라는 이름으로 설정되지만, 이름은 사용자 정의할 수도 있다.

MVC 아키텍처에서 dispatcher-servlet은 아래와 같은 과정으로 동작한다.

Client의 요청
-> dispatcher-servlet이 등록된 Controller에게 전달
-> Controller가 요청 처리
-> 결과를 Model에 담아 dispactcher-servlet으로 반환
-> dispatcher-servlet이 View에게 전달

이를 통해 알 수 있듯이, dispatcher-servlet은 Spring MVC의 핵심이며, 웹 애플리케이션의 요청 처리 흐름을 제어한다.

dispatcher-servlet.xml

src/main/webapp/WEB-INF/ 폴더 아래에 dispatcher-servlet.xml 을 생성한다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<!-- 컨트롤러 위치 설정 -->
	<context:component-scan base-package="Pack01" />

	<mvc:annotation-driven />
	<mvc:default-servlet-handler />

	<!-- 뷰 위치 설정 -->
	<mvc:view-resolvers>
		<mvc:jsp prefix="/WEB-INF/Views/" />
	</mvc:view-resolvers>

	<!-- 추가 코드: 바로 뷰로 이동 -->
	<mvc:view-controller path="/t10" view-name="DogView"/>

</beans>

<context:component-scan>

컨트롤러와 같은 구성 요소를 스캔하여 자동으로 빈으로 등록한다. base-package 속성은 스캔할 패키지를 지정한다.

<mvc:annotation-driven>

스프링 MVC 어노테이션 기반의 설정을 활성화한다. 예를 들어, @RequestMapping과 같은 어노테이션을 사용하여 URL 매핑을 처리할 수 있다.

<mvc:default-servlet-handler>

default-servlet-handler를 등록하여 정적 리소스에 대한 처리를 위임한다. 이를 통해 스프링 MVC 컨트롤러가 정적 리소스 요청을 처리하지 않고 서블릿 컨테이너의 디폴트 서블릿으로 전달한다.

<mvc:view-resolvers>

뷰 리졸버를 설정한다. <mvc:jsp> 요소를 사용하여 JSP 뷰 리졸버를 등록하고, prefix 속성을 통해 JSP 파일의 경로를 설정한다.

<mvc:view-controller>

특정 URL 경로에 대한 뷰 컨트롤러를 등록한다. path 속성은 URL 경로를 지정하고, view-name 속성은 해당 URL에 대한 뷰 이름을 설정한다. 이를 통해 컨트롤러 클래스 없이 바로 뷰로 이동할 수 있다.

🏹 코드로 이해하는 Spring MVC (2)

Controller

이제 Controller를 만들어보자.
src/main/java/ 폴더 아래에 class를 하나 생성하고, Package 명은 dispatcher-servlet에서 설정한 Pack01, Class 명은 Tiger로 하자.

@Controller를 사용하여 클래스를 지정하면 스프링 프레임워크는 해당 클래스를 컨트롤러로 인식하고, 요청과 관련된 처리를 위해 적절한 메서드를 호출한다. 이렇게 Controller는 사용자의 요청을 받아 처리하고, 비즈니스 로직을 수행하여 데이터를 가공하거나 필요한 서비스를 호출한 뒤, 결과를 View에 전달한다.

컨트롤러 클래스는 주로 @RequestMapping 어노테이션을 사용하여 특정 URL 패턴에 대한 요청을 처리하는 메서드를 지정한다. 이 메서드들은 사용자의 요청을 받아와서 해당 요청에 대한 처리를 수행한 뒤, 결과 데이터를 Model 객체에 추가하거나 ModelAndView 객체를 반환하여 뷰에 전달한다.

아래 코드의 예시를 살펴보자.

Tiger.java

package Pack01;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class Tiger {
	@RequestMapping("/t1")
	public String func01() {
		System.out.println("func01 call");
		return "TigerView"; 	// View로 이동
	}
	@RequestMapping("/t2")
	public String func02() {
		System.out.println("func02 call");
		return "TigerView"; 	// View로 이동
	}
	// RequestParam을 통한 인수 전달
	@RequestMapping("/t3")
	public String func03(
			@RequestParam(value="name") String name
			) {
		System.out.println("func03 call");
		System.out.println(name);
		return "TigerView"; 	// View로 이동
	}
	// RequestParam을 통한 인수 여러개 전달
	@RequestMapping("/t4")
	public String func04(
			@RequestParam(value="name") String name,
			@RequestParam(value="age") Integer age
			) {
		System.out.println("func04 call");
		System.out.println(name + " " + age);
		return "TigerView"; 	// View로 이동
	}
	// HttpServletRequest를 통한 인수 여러개 전달
	@RequestMapping("/t5")
	public String func05(
			HttpServletRequest request
			) {
		System.out.println("func05 call");
		String name = request.getParameter("name");
		String age = request.getParameter("age");
		return "TigerView"; 	// View로 이동
	}
	// Model을 통한 인수 전달
	@RequestMapping("/t6")
	public String func06(Model model) {
		System.out.println("func06 call");
		model.addAttribute("name", "호랑이");
		model.addAttribute("age", "50");
		return "TigerView"; 	// View로 이동
	}
	// RequestParam, Model을 통한 인수 여러개 전달
	@RequestMapping("/t7")
	public String func07(
			Model model,
			@RequestParam(value="name") String name,
			@RequestParam(value="age") Integer age
			) {
		System.out.println("func07 call");
		System.out.println(name + " " + age);
		model.addAttribute("name", name);
		model.addAttribute("age", age);
		return "TigerView"; 	// View로 이동
	}
	// ModelAndView를 통한 페이지 이동
	@RequestMapping("/t8")
	public ModelAndView func08() {
		System.out.println("func08 call");
		ModelAndView mv = new ModelAndView("TigerView");	// 이동할 위치
		mv.addObject("name", "독수리");
		mv.addObject("age", 80);
		return mv; 	// View로 이동
	}
	// ModelAndView를 통한 페이지 이동
	@RequestMapping("/t9")
	public ModelAndView func09(
			@RequestParam(value="select") Boolean select
			) {
		System.out.println("func09 call");
		ModelAndView mv = new ModelAndView(select ? "TigerView" : "LionView"); // 이동할 위치
		mv.addObject("name", "독수리");
		mv.addObject("age", 80);
		return mv; 	// View로 이동
	}
	// Form 전송
	@RequestMapping("/t11")
	public String func11(Person person) {	//person 객체 = command 객체 or bean 객체
		System.out.println("func11 call");
		System.out.println(person.getId() + " " + person.getPw());
		return "DogView"; 	// View로 이동
	}
}

위의 코드에서는 다양한 방법으로 URL에 대한 요청을 처리하고 View로 이동한다.

View

index.jsp

사용자가 가장 먼저 보게 되는 페이지다. 각 링크를 클릭할 때마다 해당되는 Controller로 URL을 요청하게 된다.
사용자는 링크를 클릭하거나 폼을 제출하여 다른 페이지로 이동하거나 서버에 데이터를 전송할 수 있다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.util.*, java.text.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<head>
<title>메인 페이지</title>
</head>

<body>
	<%=new Date()%>
	<h2>Hello World</h2>
	<a href="t1">링크1</a> <br />
	<a href="t2">링크2</a> <br />
	<a href="t3?name=apple">링크3</a> <br />
	<a href="t4?name=apple&age=30">링크4</a> <br />
	<a href="t5?name=apple&age=40">링크5</a> <br />
	<a href="t6">링크6</a> <br />
	<a href="t7?name=banana&age=60">링크7</a> <br />
	<a href="t8">링크8</a> <br />
	<a href="t9?select=false">링크9</a> <br />
	<!-- dispatcher-servlet에서 설정 -->
	<a href="t10">링크10</a>
	<br />
	<FORM METHOD=POST action="t11">
		<INPUT TYPE="text" NAME="id" VALUE="tiger"><br /> 
		<INPUT TYPE="number" NAME="pw" VALUE=23><br /> 
		<INPUT TYPE="submit" VALUE="전송">
	</FORM>

</body>

TigerView.jsp

src/main/webapp/WEB-INF/ 폴더 아래에 Views 폴더를 생성한 후, 그 안에 TigerView.jsp 를 생성한다.

View 페이지는 ${name}과 ${age}를 사용하여 서버에서 전달된 데이터를 동적으로 출력한다.

<%@ 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>
<%-- 	<%
		String name1 = (String)request.getAttribute("name");
		Integer age1 = (Integer)request.getAttribute("age");
	%> --%>
	<h1>Tiger View.jsp</h1>
	<!-- ${name} : JSP의 EL식 -->
	<h1> ${name} </h1>
	<h1> ${age} </h1>
<%-- 	<h1> <%=name1%> </h1>
	<h1> <%=age1%> </h1> --%>
</body>
</html>

LionView.jsp

src/main/webapp/WEB-INF/Views/ 폴더 아래에 LionView.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>

	<h1>Lion View.jsp</h1>
	<!-- ${name} : JSP의 EL식 -->
	<h1> ${name} </h1>
	<h1> ${age} </h1>

</body>
</html>

DogView.jsp

src/main/webapp/WEB-INF/Views/ 폴더 아래에 DogView.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>
	<h1>Dog View.jsp</h1>
</body>
</html>
profile
thisIsZihooLog

0개의 댓글