Spring MVC (23.08.10)

·2023년 8월 10일
0

Spring

목록 보기
2/36
post-thumbnail

🌷 Spring MVC

  • Spring Framework 에서는 클라이언트의 화면을 표현하기 위한 View와 서비스를 수행하기 위한 개발 로직 부분을 나누는 MVC2 패턴을 지원한다.
  • Model, View, Controller 사이의 의존 관계를 DI 컨테이너에서 관리하여 유연한 웹 애플리케이션을 쉽게 구현 및 개발할 수 있다.

🌼 구성 요소

구성 요소설명
DispatcherServlet
(발송자 서블릿)
요청을 컨트롤러로 전달하고 응답하는 역할
HandlerMapping
(매핑 처리)
어떤 요청을 어떤 클래스/메소드로 연결하는지 제어하는 객체
Controller클라이언트의 요청을 처리한 뒤, 결과를 DispatcherServlet에게 리턴
ModelAndView컨트롤러가 처리한 결과 정보 및 뷰 선택에 필요한 정보를 담음
ViewResolver
(뷰 해결사)
Controller에서 반환된 문자열("common/main") 앞, 뒤에 경로(/WEB-INF/views), 확장자(.jsp)를 붙여 jsp 파일의 경로를 지정한 후 forward(요청 위임)을 하는 객체
View컨트롤러의 처리 결과 화면을 생성, JSP나 Velocity 템플릿 파일 등을 View로 사용

🌱 Spring MVC 요청 처리 과정


🌼 @Annotation

XML 파일에는 구동시킬 필수 요소만 작성하고 소스코드에 Annotation으로 표시하여 구동하는 방식

🌱 종류

@Component

객체(컴포넌트)를 나타내는 일반적인 타입으로 bean 태그와 동일한 역할

@Repository

퍼시스턴스(persistence) 레이어, 영속성을 가지는 속성(파일, 데이터베이스)를 가진 클래스
(ex: DAO)

@Service

서비스 레이어, 비즈니스 로직을 가진 클래스

@Controller

현재 클래스가 컨트롤러임을 명시하고, 요청 및 응답을 처리하는 클래스
-> bean 등록도 함

@RequestMapping

요청 주소에 맞는 클래스 또는 메소드 연결

  • 📝 작성 방법 📝
  1. @RequestMapping("요청 주소")
    GET / POST 구분 X(모두 받음, 주소만 맞으면 연결)

  2. @RequestMapping(value="요청 주소", method=RequestMethod.GET/POST)
    GET / POST 방식을 구분

    이때 요청 주소는 공통된 주소 앞부분을 작성한다.
    요청 주소로 시작하는 요청은 해당 컨트롤러에서 처리하게 된다.


여기서 파라미터 전달 방법은 세 가지가 있다. 하나씩 살펴보도록 하자.

🌼 파라미터 전달 방법

🌱 HttpServletRequest 이용

Controller 메소드에 매개변수로 HttpServletRequest 작성

🔎 예시

	// 로그인(/member/login), POST 방식 처리
	// Class에 작성한 /member를 제외한 나머지 부분을 주소로 작성
	// @RequestMapping(value="/login", method=RequestMethod.POST)
	public String login(HttpServletRequest req) {

		String inputEmail = req.getParameter("inputEmail");
		
		System.out.println("inputEmail : " + inputEmail);
		
		// ** redirect 방법! **
		
		// "redirect:요청주소"
		return "redirect:/";
	}

💭 매개변수에 적으면 왜 사용이 가능할까?

Spring Framework가 제공하는 Argument Resolver(매개변수 해결사)가 해결해 주기 때문이다.


🌱 @RequestParam 어노테이션 이용

request 객체를 이용한 파라미터 전달 어노테이션

  • 매개변수 앞에 해당 어노테이션을 작성하면, 매개변수에 값이 주입됨
    -> 파라미터의 name 속성 값과 매개 변수명이 같으면 @RequestParam 생략 가능 🙌

  • 사용 방법

@RequestParam(value="name", required="false", defaultValue="1")

	[속성]
	value : 전달 받은 input 태그의 name 속성값
		  
	required : 입력된 name 속성값 파라미터 필수 여부 지정(기본값 true)
	-> required = true인 파라미터가 존재하지 않는다면 400 Bad Request 에러 발생
	-> required = true인 파라미터가 null인 경우에도 400 Bad Request
		
	defaultValue : 파라미터 중 일치하는 name 속성 값이 없을 경우에 대입할 값 지정.
	-> required = false인 경우 사용

🔎 예시

	// @PostMapping
	// -> @RequestMapping의 자식으로
	//	  POST 방식 요청을 연결하는 어노테이션
	// @PostMapping("/login")
	public String login(/*@RequestParam("inputEmail")*/ String inputEmail,
						/*@RequestParam("inputPw")*/ String inputPw) {
                        
		// 메인 페이지 리다이렉트(재요청)
		return "redirect:/";
	}

🌱 @ModelAttribute 이용

DTO(또는 VO)와 같이 사용하는 어노테이션

  • 전달받은 파라미터의 name 속성값이 같이 사용되는 DTO의 필드명과 같다면 자동으로 setter를 호출해서 필드에 값을 세팅함

  • @ModelAttribute 어노테이션은 생략이 가능함

  • 커맨드 객체 : @ModelAttribute를 이용해서 값이 필드에 세팅된 객체

  • 🙅‍♀️ 사용 시 주의사항! 🙅‍♀️
    - DTO에 기본 생성자setter가 필수로 존재해야 한다.

🔎 예시

	@PostMapping("/login")
	public String login(/*@ModelAttribute*/ Member inputMember) {
		
		return "redirect:/";
	}

자, 준비는 끝났다.
이제 코드로 한번 자세히 살펴보도록 하자.

👀 코드로 살펴보기 (1)

📁 구조

Package Explorer로 살펴본 구조이다.
서버를 실행했을 때 해석 순서는 아래와 같다.

서버 실행web.xml 해석 ➡ root-context.xml / servlet-context.xml 해석 ➡ ...

🌱 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion> <!-- Maven 2 버전 이후 POM의 경우 항상 4.0.0 -->
	<groupId>edu.kh</groupId> <!-- 최상위 패키지 1, 2레벨 -->
	<artifactId>project</artifactId> <!-- 최상위 패키지 3레벨 == context-path -->
	<name>boardProject</name> <!-- 프로젝트 명 -->
	<packaging>war</packaging>  <!-- 배포 형식 -->
	<version>1.0.0--BUILD-SNAPSHOT</version>

	<!-- properties : 메이븐이 적용된 프로젝트에서 공통적으로 사용할 값을 작성하는 태그(전연 변수) -->
	<properties>
		<java-version>11</java-version>
		<org.springframework-version>5.3.14</org.springframework-version>
		<org.aspectj-version>1.9.9.1</org.aspectj-version>
		<org.slf4j-version>1.7.25</org.slf4j-version>
	</properties>

	<!-- dependencies : Maven 프로젝트는 외부 저장소와 의존 관계를 맺고 있어 프로젝트에 필요한 파일을(라이브러리) 
		사용자가 직접 받을 필요 없이 해당 태그 내에 지정된 형식으로 작성하면 네트워크를 통해 외부 저장소에서 자동으로 얻어와 세팅함. -->
	<dependencies>

		<!-- lombok 라이브러리 -->
		<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.24</version>
			<scope>provided</scope>
		</dependency>

		<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc11 -->
		<dependency>
			<groupId>com.oracle.database.jdbc</groupId>
			<artifactId>ojdbc11</artifactId>
			<version>21.5.0.0</version>
		</dependency>

		<!-- Spring 모듈 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

		<!-- AspectJ : AOP 기능을 사용하기 위한 언어 문법 -->
		<!-- aspectjrt : AspectJ 런타임 프로그램 -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>

		<!-- AspectJ Weaver : aspect의 정보를 바탕으로 aspect를 구성한 코드를 생성하는데 필요한 유틸리티 프로그램 -->
		<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>

		<!-- Log4j (Logging) -->
		<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.17.1</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>

		<!-- Servlet -->
		<!-- Servlet 버전을 4.0으로 변경 -->
		<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.1</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>


		<!-- 단위 테스트 도구 (JUnit) -->
		<!-- https://mvnrepository.com/artifact/junit/junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.13.2</version>
			<scope>test</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${org.springframework-version}</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<!-- build : 프로젝트 빌드 시 사용되는 플러그인 추가 및 버전 정보 설정 -->
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-eclipse-plugin</artifactId>
				<version>2.9</version>
				<configuration>
					<additionalProjectnatures>
						<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
					</additionalProjectnatures>
					<additionalBuildcommands>
						<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
					</additionalBuildcommands>
					<downloadSources>true</downloadSources>
					<downloadJavadocs>true</downloadJavadocs>
				</configuration>
			</plugin>

			<!-- 컴파일러 플러그인은 프로젝트의 소스(자바코드)를 컴파일하는 데 사용 jdk 1.6 이상 사용 시 3.0 이상 버전을 
				사용, source, taget에는 사용하는 jdk 버전을 작성 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<source>11</source>
					<target>11</target>
					<compilerArgument>-Xlint:all</compilerArgument>
					<showWarnings>true</showWarnings>
					<showDeprecation>true</showDeprecation>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>exec-maven-plugin</artifactId>
				<version>1.2.1</version>
				<configuration>
					<mainClass>org.test.int1.Main</mainClass>
				</configuration>
			</plugin>

			<!-- Could not initialize class org.apache.maven.plugin.war.util.WebappStructureSerializer -->
			<!-- 메이븐 구성 문제로 인한 pom.xml 오류 발생 시 해결 -->
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>3.2.2</version>
			</plugin>
		</plugins>
	</build>
</project>

🌱 web.xml

(배포 서술자 / 설명서)
서버가 켜질 때(배포가 시작될 때) 가장 먼저 읽어들이는 설정 파일

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="4.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://JAVA.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_4_0.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets 
		and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/root-context.xml</param-value>
	</context-param>

	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

	<!-- Processes application requests -->
	
	<!-- 
		DispatcherServlet(Spring에서 제공) 객체 생성 시
		servlet-context.xml 파일을 이용해서 만든다.
	 -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring/appServlet/servlet-context.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<!-- 한글 깨짐 방지를 위한 Filter 추가 -->
	<!-- 별도의 filter 클래스를 만들지 않고 스프링에서 제공하는 filter를 사용 -->
	<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>

🌱 root-context.xml

서버가 켜질 때 web.xml이 가장 먼저 읽어들이는 설정 파일

프로젝트 전반적으로 사용될 설정, 객체(Bean)를 생성하는 용도의 파일
(DB 연결 관련 내용(JDBC, MyBatis, DBCP) AOP, 트랜잭션 처리, 파일 업로드 등)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
	
</beans>

🌱 servlet-context.xml

DispatcherServlet 생성 시 필요한 내용을 정의하는 파일

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

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- 
		HandlerMapping :
		어떤 요청을 어떤 클래스/메소드로 연결하는지 제어하는 객체
		<annotation-driven /> 이
		@RequestMapping, @GetMapping, @PostMapping을 활성화해서
		HandlerMapping을 대체
		
		ViewResolver :
		Controller에서 반환된 문자열("common/main")
		앞, 뒤에 경로(/WEB-INF/views), 확장자(.jsp)를 붙여
		jsp 파일의 경로를 지정한 후 forward(요청 위임)을 하는 객체
						
	 	component-scan : @Component와 자식 어노테이션을 Bean으로 등록하는 태그

		트랜잭션 관리자, 웹소켓, 인터셉터, 스케쥴러
	 -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- webapp/resources 폴더를 HTTP GET방식 요청으로 접근할 수 있다. -->
	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- ViewResolver -->
	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
	
	<!-- 
		base-package 이하에 작성된
		@Component와
		자식 어노테이션(@Controller, @Service, @Repository)이 붙은
		클래스를 찾아서 Bean(Spring이 관리하는 객체)으로 등록
	 -->
	<context:component-scan base-package="edu.kh.project" />

</beans:beans>

🌱 Member.java

package edu.kh.project.member.model.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@NoArgsConstructor
public class Member {
	private int memberNo;
	private String memberEmail;
	private String memberPw;
	private String memberNickname;
	private String memberTel;
	private String memberAddress;
	private String profileImage;
	private String enrollDate;
	private String memberDeleteFlag;
	private int authority;
}

🌱 MainController.java

package edu.kh.project.main.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

// @Controller : 현재 클래스가 컨트롤러임을 명시
//	  			 -> 요청, 응답 처리
//				 + bean 등록

// instance : 클래스 -> 객체
//  --> new 클래스명(); 객체 생성을 개발자가 직접 함

// IOC(Inversion Of Control, 제어의 역전)
// -> 프레임워크(Spring Container)가 객체를 생성하고 관리
// --> 이때 생성된 객체 == Bean


@Controller
public class MainController {

	// tip : spring에서 controller 메소드 작성 시
	// 반환 값을 모르겠으면 일단 String으로 작성!
	
//	@RequestMapping("/") : 요청 주소가 "/"인 경우 해당 메소드와 연결
	
	@RequestMapping("/")
	public String mainForward() {
		// main.jsp로 화면 전환
		
		// <beans:property name="prefix" value="/WEB-INF/views/" />
		// <beans:property name="suffix" value=".jsp" />
		
		// Spring에서 forward 하는 방법
		//  -> webapp 폴더를 기준으로
		//	   요청 위임할 JSP 파일 경로를 리턴하면 된다.
		
		// 단, servlet-context.xml에 작성된
		// prefix, suffix 부분을 제외하고 작성!
		// -> prefix + 리턴 값 + suffix로 경로 완성!
		// ** View Resolver **
		
		return "common/main";
	}
	
}

🌱 MemberController.java

package edu.kh.project.member.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import edu.kh.project.member.model.dto.Member;


// @RequestMapping : 요청 주소에 맞는 클래스/메소드 연결

// [작성 방법 2가지]
// @RequestMapping("요청 주소")
// -> GET / POST 구분 X(모두 받음, 주소만 맞으면 연결)

// @RequestMapping(value="요청 주소", method=RequestMethod.GET/POST)
//	-> GET / POST 방식을 구분

@Controller // 요청/응답 클래스 + bean 등록(Spring이 관리하는 객체)
@RequestMapping("/member") // 공통된 주소 앞부분 작성
						   // member로 시작하는 요청은 해당 컨트롤러에서 처리
public class MemberController {

	// 로그인		: /member/login
	// 로그아웃	: /member/logout
	
	// 로그인(/member/login), POST 방식 처리
	// Class에 작성한 /member를 제외한 나머지 부분을 주소로 작성
	// @RequestMapping(value="/login", method=RequestMethod.POST)
	public String login(HttpServletRequest req) {
		
		// 파라미터 전달 방법 1 : HttpServletRequest를 이용하는 방법
		// -> Controller 메소드에 매개변수로 HttpServletRequest 작성
		
		// 매개변수에 적으면 왜 사용이 가능할까?
		// Spring Framework가 제공하는
		// Argument Resolver(매개변수 해결사)가 해결해 줘서
		
		String inputEmail = req.getParameter("inputEmail");
		
		System.out.println("inputEmail : " + inputEmail);
		
		// ** redirect 방법! **
		
		// "redirect:요청주소"
		return "redirect:/";
	}

	// @PostMapping
	// -> @RequestMapping의 자식으로
	//	  POST 방식 요청을 연결하는 어노테이션
	// @PostMapping("/login")
	public String login(/*@RequestParam("inputEmail")*/ String inputEmail,
						/*@RequestParam("inputPw")*/ String inputPw) {
		
		// 파라미터 전달 방법 2 : @RequestParam 어노테이션 이용(+생략 방법)

		// @ RequestParam 어노테이션
		
		// - request객체를 이용한 파라미터 전달 어노테이션
		// - 매개변수 앞에 해당 어노테이션을 작성하면, 매개변수에 값이 주입됨
		
		// ** 파라미터의 name 속성 값과
		//	  매개 변수명이 같으면 @RequestParam 생략 가능!! **
		
		// @RequestParam(value="name", required="fasle", defaultValue="1")
		// [속성]
		// value : 전달 받은 input 태그의 name 속성값
		  
		// required : 입력된 name 속성값 파라미터 필수 여부 지정(기본값 true)
		// -> required = true인 파라미터가 존재하지 않는다면 400 Bad Request 에러 발생
		// -> required = true인 파라미터가 null인 경우에도 400 Bad Request
		
		// defaultValue : 파라미터 중 일치하는 name 속성 값이 없을 경우에 대입할 값 지정.
		// -> required = false인 경우 사용
	
		System.out.println("inputEmail : " + inputEmail);
		System.out.println("inputPw : " + inputPw);

		// 메인 페이지 리다이렉트(재요청)
		return "redirect:/";
	}
	
	@PostMapping("/login")
	public String login(/*@ModelAttribute*/ Member inputMember) {

		// 파라미터 전달 방법 3 : @ModelAttribute를 이용한 방법
		
		// - DTO(또는 VO)와 같이 사용하는 어노테이션
		
		// - 전달받은 파라미터의 name 속성값이
		//	 같이 사용되는 DTO의 필드명과 같다면
		//	 자동으로 setter를 호출해서 필드에 값을 세팅
		
		// *** @ModelAttribute 사용 시 주의사항 ***
		// - DTO에 기본 생성자가 필수로 존재해야 한다!
		// - DTO에 setter가 필수로 존재해야 한다!
		
		// *** @ModelAttribute 어노테이션은 생략이 가능하다! ***
		
		// *** @ModelAttribute를 이용해서 값이 필드에 세팅된 객체를
		//	   "커맨드 객체"라고 한다. ***
		
		System.out.println(inputMember);
		
		return "redirect:/";
	}
	
}

다음 포스팅에 계속 :)

🔎 다음 포스팅 바로 가기 - MyBatis

profile
풀스택 개발자 기록집 📁

0개의 댓글