관리 메뉴

거니의 velog

231123_SPRING 2 (2-1) 본문

대덕인재개발원_웹기반 애플리케이션

231123_SPRING 2 (2-1)

Unlimited00 2023. 11. 23. 08:32

[pom.xml]

		<!--  
			lombok 라이브러리
			- 자바빈 클래스(VO)의 getter/setter 메소드, toString() 자동처리
			- log.info()와 같은 로깅 메소드로 syso 대신 로그를 console에 출력할 수 있다.
		-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.22</version>
		</dependency>

[HomeController.java]

package kr.or.ddit;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
}

[goHome0101.jsp]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>HOME</title>
	</head>
	<body>
		<h3>goHome0101</h3>
	</body>
</html>

[goHome0102.jsp]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>HOME</title>
	</head>
	<body>
		<h3>goHome0102</h3>
	</body>
</html>

- http://localhost/goHome0101

- http://localhost/sub/goHome0102


[home0201.jsp]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>HOME</title>
	</head>
	<body>
		<h3>home0201</h3>
	</body>
</html>

[home0203.jsp]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>HOME</title>
	</head>
	<body>
		<h3>home0203</h3>
	</body>
</html>
package kr.or.ddit;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
}

- http://localhost/goHome0201

- http://localhost/sub/goHome0203


package kr.or.ddit;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
}

[home0205.jsp]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>HOME</title>
	</head>
	<body>
		<h3>home0205</h3>
	</body>
</html>

- http://localhost/sub/goHome0204

리다이렉트로 넘어감

- http://localhost/sub/goHome0205

* 앞에 / 가 붙어도 정확하게 home0205 를 찾아낸다.


[Member.java]

package kr.or.ddit.vo;

import lombok.Data;

@Data
public class Member {

	private String userName = "hongkd";
	private String password = "1234";
	
}
package kr.or.ddit;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
}

[pom.xml]

		<!-- json 데이터 바인딩을 위한 의존 라이브러리 -->	
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.5</version>
		</dependency>
		
		<!-- xml 데이터 바인딩을 위한 의존 라이브러리 -->
		<!-- <dependency>
			<groupId>com.fasterxml.jackson.dataformat</groupId>
			<artifactId>jackson-dataformat-xml</artifactId>
			<version>2.9.5</version>
		</dependency> -->

- http://localhost/goHome0301



[RestHomeController.java]

package kr.or.ddit;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class RestHomeController {

	@RequestMapping(value = "/goRestHome0301", method = RequestMethod.GET)
	public Member goRestHome0301() {
		log.info("goRestHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
}

- http://localhost/goRestHome0301


	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}

package kr.or.ddit;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}
	
	/*
	 * 		4. 컬렉션 List 타입
	 * 
	 * 			- JSON 객체 배열 타입의 데이터를 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 List 타입이면 JSON 객체 배열 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0401", method = RequestMethod.GET)
	public List<Member> goHome0401(){
		log.info("goHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
}

- http://localhost/goHome0401


package kr.or.ddit;

import java.util.ArrayList;
import java.util.List;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class RestHomeController {

	@RequestMapping(value = "/goRestHome0301", method = RequestMethod.GET)
	public Member goRestHome0301() {
		log.info("goRestHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
	@RequestMapping(value = "/goRestHome0401", method = RequestMethod.GET)
	public List<Member> goRestHome0401(){
		log.info("goRestHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
}

- http://localhost/goRestHome0401


package kr.or.ddit;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}
	
	/*
	 * 		4. 컬렉션 List 타입
	 * 
	 * 			- JSON 객체 배열 타입의 데이터를 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 List 타입이면 JSON 객체 배열 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0401", method = RequestMethod.GET)
	public List<Member> goHome0401(){
		log.info("goHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	/*
	 * 		5. 컬렉션 Map 타입
	 * 
	 * 			- Map 형태의 컬렉션 자료를 JSON 객체 타입의 데이터로 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 Map 타입이면 JSON 객체 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0501", method = RequestMethod.GET)
	public Map<String, Member> goHome0501(){
		log.info("goHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
}

- http://localhost/goHome0501


package kr.or.ddit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class RestHomeController {

	@RequestMapping(value = "/goRestHome0301", method = RequestMethod.GET)
	public Member goRestHome0301() {
		log.info("goRestHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
	@RequestMapping(value = "/goRestHome0401", method = RequestMethod.GET)
	public List<Member> goRestHome0401(){
		log.info("goRestHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	@RequestMapping(value = "/goRestHome0501", method = RequestMethod.GET)
	public Map<String, Member> goRestHome0501(){
		log.info("goRestHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
}


package kr.or.ddit;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}
	
	/*
	 * 		4. 컬렉션 List 타입
	 * 
	 * 			- JSON 객체 배열 타입의 데이터를 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 List 타입이면 JSON 객체 배열 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0401", method = RequestMethod.GET)
	public List<Member> goHome0401(){
		log.info("goHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	/*
	 * 		5. 컬렉션 Map 타입
	 * 
	 * 			- Map 형태의 컬렉션 자료를 JSON 객체 타입의 데이터로 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 Map 타입이면 JSON 객체 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0501", method = RequestMethod.GET)
	public Map<String, Member> goHome0501(){
		log.info("goHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	/*
	 * 		6. ResponseEntity<Void> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 내용을 가공하는 용도로 사용한다.
	 */
	
	@ResponseBody
	@RequestMapping(value = "/goHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goHome0601(){
		log.info("goHome0601() 실행...!");
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
}

- http://localhost/goHome0601

* 클라이언트와 서버 사이에 요청과 응답 과정 중에 status의 목적은 클라이언트의 비동기 처리에서
앞 단에서 데이터 처리를 확인하는 도중에
백단에서 비동기로 헤더 정보를 수정하고 싶을 때,
                               서버에 응답 데이터가 없이 기능 또는 데이터를 수정하고 싶을 때

즉, 별개의 기능이 백단에서 따로 돌아가고 있는 것.


	/*
	 * 		6. ResponseEntity<Void> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 내용을 가공하는 용도로 사용한다.
	 */
	
	// 200 OK 상태코드를 전송한다.
	// Void 타입은 아무런 상태가 아닌데 제네릭 타입의 뭔가는 채워야 겠어서 채우는 placeholder같은 느낌이랄까?
	@ResponseBody
	@RequestMapping(value = "/goHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goHome0601(){
		log.info("goHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}

package kr.or.ddit;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}
	
	/*
	 * 		4. 컬렉션 List 타입
	 * 
	 * 			- JSON 객체 배열 타입의 데이터를 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 List 타입이면 JSON 객체 배열 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0401", method = RequestMethod.GET)
	public List<Member> goHome0401(){
		log.info("goHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	/*
	 * 		5. 컬렉션 Map 타입
	 * 
	 * 			- Map 형태의 컬렉션 자료를 JSON 객체 타입의 데이터로 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 Map 타입이면 JSON 객체 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0501", method = RequestMethod.GET)
	public Map<String, Member> goHome0501(){
		log.info("goHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	/*
	 * 		6. ResponseEntity<Void> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 내용을 가공하는 용도로 사용한다.
	 */
	
	// 200 OK 상태코드를 전송한다.
	// Void 타입은 아무런 상태가 아닌데 제네릭 타입의 뭔가는 채워야 겠어서 채우는 placeholder같은 느낌이랄까?
	@ResponseBody
	@RequestMapping(value = "/goHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goHome0601(){
		log.info("goHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	/*
	 * 		7. ResponseEntity<String> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 문자열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// "SUCCESS" 메세지와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goHome0701(){
		log.info("goHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
}

- http://localhost/goHome0701


package kr.or.ddit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class RestHomeController {

	@RequestMapping(value = "/goRestHome0301", method = RequestMethod.GET)
	public Member goRestHome0301() {
		log.info("goRestHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
	@RequestMapping(value = "/goRestHome0401", method = RequestMethod.GET)
	public List<Member> goRestHome0401(){
		log.info("goRestHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	@RequestMapping(value = "/goRestHome0501", method = RequestMethod.GET)
	public Map<String, Member> goRestHome0501(){
		log.info("goRestHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	@RequestMapping(value = "/goRestHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goRestHome0601(){
		log.info("goRestHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goRestHome0701(){
		log.info("goRestHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
}

package kr.or.ddit;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}
	
	/*
	 * 		4. 컬렉션 List 타입
	 * 
	 * 			- JSON 객체 배열 타입의 데이터를 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 List 타입이면 JSON 객체 배열 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0401", method = RequestMethod.GET)
	public List<Member> goHome0401(){
		log.info("goHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	/*
	 * 		5. 컬렉션 Map 타입
	 * 
	 * 			- Map 형태의 컬렉션 자료를 JSON 객체 타입의 데이터로 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 Map 타입이면 JSON 객체 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0501", method = RequestMethod.GET)
	public Map<String, Member> goHome0501(){
		log.info("goHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	/*
	 * 		6. ResponseEntity<Void> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 내용을 가공하는 용도로 사용한다.
	 */
	
	// 200 OK 상태코드를 전송한다.
	// Void 타입은 아무런 상태가 아닌데 제네릭 타입의 뭔가는 채워야 겠어서 채우는 placeholder같은 느낌이랄까?
	@ResponseBody
	@RequestMapping(value = "/goHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goHome0601(){
		log.info("goHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	/*
	 * 		7. ResponseEntity<String> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 문자열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// "SUCCESS" 메세지와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goHome0701(){
		log.info("goHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	/*
	 * 		8. ResponseEntity<자바빈즈> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 데이터를 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goHome0801(){
		log.info("goHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
}

- http://localhost/goHome0801


package kr.or.ddit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class RestHomeController {

	@RequestMapping(value = "/goRestHome0301", method = RequestMethod.GET)
	public Member goRestHome0301() {
		log.info("goRestHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
	@RequestMapping(value = "/goRestHome0401", method = RequestMethod.GET)
	public List<Member> goRestHome0401(){
		log.info("goRestHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	@RequestMapping(value = "/goRestHome0501", method = RequestMethod.GET)
	public Map<String, Member> goRestHome0501(){
		log.info("goRestHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	@RequestMapping(value = "/goRestHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goRestHome0601(){
		log.info("goRestHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goRestHome0701(){
		log.info("goRestHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goRestHome0801(){
		log.info("goRestHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
}

package kr.or.ddit;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}
	
	/*
	 * 		4. 컬렉션 List 타입
	 * 
	 * 			- JSON 객체 배열 타입의 데이터를 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 List 타입이면 JSON 객체 배열 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0401", method = RequestMethod.GET)
	public List<Member> goHome0401(){
		log.info("goHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	/*
	 * 		5. 컬렉션 Map 타입
	 * 
	 * 			- Map 형태의 컬렉션 자료를 JSON 객체 타입의 데이터로 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 Map 타입이면 JSON 객체 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0501", method = RequestMethod.GET)
	public Map<String, Member> goHome0501(){
		log.info("goHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	/*
	 * 		6. ResponseEntity<Void> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 내용을 가공하는 용도로 사용한다.
	 */
	
	// 200 OK 상태코드를 전송한다.
	// Void 타입은 아무런 상태가 아닌데 제네릭 타입의 뭔가는 채워야 겠어서 채우는 placeholder같은 느낌이랄까?
	@ResponseBody
	@RequestMapping(value = "/goHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goHome0601(){
		log.info("goHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	/*
	 * 		7. ResponseEntity<String> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 문자열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// "SUCCESS" 메세지와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goHome0701(){
		log.info("goHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	/*
	 * 		8. ResponseEntity<자바빈즈> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 데이터를 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goHome0801(){
		log.info("goHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
	/*
	 * 		9. ResponseEntity<List> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 배열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 객체 배열 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0901", method = RequestMethod.GET)
	public ResponseEntity<List<Member>> goHome0901(){
		log.info("goHome0901() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		return new ResponseEntity<List<Member>>(list, HttpStatus.OK);
	}
	
}

- http://localhost/goHome0901


package kr.or.ddit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class RestHomeController {

	@RequestMapping(value = "/goRestHome0301", method = RequestMethod.GET)
	public Member goRestHome0301() {
		log.info("goRestHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
	@RequestMapping(value = "/goRestHome0401", method = RequestMethod.GET)
	public List<Member> goRestHome0401(){
		log.info("goRestHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	@RequestMapping(value = "/goRestHome0501", method = RequestMethod.GET)
	public Map<String, Member> goRestHome0501(){
		log.info("goRestHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	@RequestMapping(value = "/goRestHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goRestHome0601(){
		log.info("goRestHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goRestHome0701(){
		log.info("goRestHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goRestHome0801(){
		log.info("goRestHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0901", method = RequestMethod.GET)
	public ResponseEntity<List<Member>> goRestHome0901(){
		log.info("goRestHome0901() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		return new ResponseEntity<List<Member>>(list, HttpStatus.OK);
	}
	
}

package kr.or.ddit;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}
	
	/*
	 * 		4. 컬렉션 List 타입
	 * 
	 * 			- JSON 객체 배열 타입의 데이터를 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 List 타입이면 JSON 객체 배열 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0401", method = RequestMethod.GET)
	public List<Member> goHome0401(){
		log.info("goHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	/*
	 * 		5. 컬렉션 Map 타입
	 * 
	 * 			- Map 형태의 컬렉션 자료를 JSON 객체 타입의 데이터로 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 Map 타입이면 JSON 객체 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0501", method = RequestMethod.GET)
	public Map<String, Member> goHome0501(){
		log.info("goHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	/*
	 * 		6. ResponseEntity<Void> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 내용을 가공하는 용도로 사용한다.
	 */
	
	// 200 OK 상태코드를 전송한다.
	// Void 타입은 아무런 상태가 아닌데 제네릭 타입의 뭔가는 채워야 겠어서 채우는 placeholder같은 느낌이랄까?
	@ResponseBody
	@RequestMapping(value = "/goHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goHome0601(){
		log.info("goHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	/*
	 * 		7. ResponseEntity<String> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 문자열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// "SUCCESS" 메세지와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goHome0701(){
		log.info("goHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	/*
	 * 		8. ResponseEntity<자바빈즈> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 데이터를 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goHome0801(){
		log.info("goHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
	/*
	 * 		9. ResponseEntity<List> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 배열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 객체 배열 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0901", method = RequestMethod.GET)
	public ResponseEntity<List<Member>> goHome0901(){
		log.info("goHome0901() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		return new ResponseEntity<List<Member>>(list, HttpStatus.OK);
	}
	
	/*
	 * 		10. ResponseEntity<Map> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 데이터를 Map 형태로 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 객체 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome1001", method = RequestMethod.GET)
	public ResponseEntity<Map<String, Member>> goHome1001(){
		log.info("goHome1001() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return new ResponseEntity<Map<String, Member>>(map, HttpStatus.OK);
	}
	
}

- http://localhost/goHome1001


package kr.or.ddit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class RestHomeController {

	@RequestMapping(value = "/goRestHome0301", method = RequestMethod.GET)
	public Member goRestHome0301() {
		log.info("goRestHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
	@RequestMapping(value = "/goRestHome0401", method = RequestMethod.GET)
	public List<Member> goRestHome0401(){
		log.info("goRestHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	@RequestMapping(value = "/goRestHome0501", method = RequestMethod.GET)
	public Map<String, Member> goRestHome0501(){
		log.info("goRestHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	@RequestMapping(value = "/goRestHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goRestHome0601(){
		log.info("goRestHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goRestHome0701(){
		log.info("goRestHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goRestHome0801(){
		log.info("goRestHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0901", method = RequestMethod.GET)
	public ResponseEntity<List<Member>> goRestHome0901(){
		log.info("goRestHome0901() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		return new ResponseEntity<List<Member>>(list, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome1001", method = RequestMethod.GET)
	public ResponseEntity<Map<String, Member>> goRestHome1001(){
		log.info("goRestHome1001() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return new ResponseEntity<Map<String, Member>>(map, HttpStatus.OK);
	}
	
}

[pom.xml]

		<!--  
			파일을 처리하기 위한 라이브러리 의존 관계 정의
		-->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.6</version>
		</dependency>

package kr.or.ddit;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}
	
	/*
	 * 		4. 컬렉션 List 타입
	 * 
	 * 			- JSON 객체 배열 타입의 데이터를 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 List 타입이면 JSON 객체 배열 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0401", method = RequestMethod.GET)
	public List<Member> goHome0401(){
		log.info("goHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	/*
	 * 		5. 컬렉션 Map 타입
	 * 
	 * 			- Map 형태의 컬렉션 자료를 JSON 객체 타입의 데이터로 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 Map 타입이면 JSON 객체 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0501", method = RequestMethod.GET)
	public Map<String, Member> goHome0501(){
		log.info("goHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	/*
	 * 		6. ResponseEntity<Void> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 내용을 가공하는 용도로 사용한다.
	 */
	
	// 200 OK 상태코드를 전송한다.
	// Void 타입은 아무런 상태가 아닌데 제네릭 타입의 뭔가는 채워야 겠어서 채우는 placeholder같은 느낌이랄까?
	@ResponseBody
	@RequestMapping(value = "/goHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goHome0601(){
		log.info("goHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	/*
	 * 		7. ResponseEntity<String> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 문자열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// "SUCCESS" 메세지와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goHome0701(){
		log.info("goHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	/*
	 * 		8. ResponseEntity<자바빈즈> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 데이터를 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goHome0801(){
		log.info("goHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
	/*
	 * 		9. ResponseEntity<List> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 배열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 객체 배열 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0901", method = RequestMethod.GET)
	public ResponseEntity<List<Member>> goHome0901(){
		log.info("goHome0901() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		return new ResponseEntity<List<Member>>(list, HttpStatus.OK);
	}
	
	/*
	 * 		10. ResponseEntity<Map> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 데이터를 Map 형태로 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 객체 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome1001", method = RequestMethod.GET)
	public ResponseEntity<Map<String, Member>> goHome1001(){
		log.info("goHome1001() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return new ResponseEntity<Map<String, Member>>(map, HttpStatus.OK);
	}
	
	/*
	 * 		11. ResponseEntity<byte[]> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 바이너리 파일 데이터를 전달하는 용도로 사용한다.
	 * 			- 파일을 처리하기 위해서 의존 라이브러리 commons-io를 추가한다. (pom.xml)
	 */
	
	@ResponseBody
	@RequestMapping(value = "/goHome1101", method = RequestMethod.GET)
	public ResponseEntity<byte[]> goHome1101(){
		log.info("goHome1101() 실행...!");
		ResponseEntity<byte[]> entity = null;
		
		// C:\Users\PC_23\Pictures\Saved Pictures\spring.png
		InputStream in = null;
		HttpHeaders headers = new HttpHeaders();
		try {
			in = new FileInputStream("C:\\Users\\PC_23\\Pictures\\Saved Pictures\\spring.png");
			headers.setContentType(MediaType.IMAGE_PNG);
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return entity;
	}
	
}

- http://localhost/goHome1101


package kr.or.ddit;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class RestHomeController {

	@RequestMapping(value = "/goRestHome0301", method = RequestMethod.GET)
	public Member goRestHome0301() {
		log.info("goRestHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
	@RequestMapping(value = "/goRestHome0401", method = RequestMethod.GET)
	public List<Member> goRestHome0401(){
		log.info("goRestHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	@RequestMapping(value = "/goRestHome0501", method = RequestMethod.GET)
	public Map<String, Member> goRestHome0501(){
		log.info("goRestHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	@RequestMapping(value = "/goRestHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goRestHome0601(){
		log.info("goRestHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goRestHome0701(){
		log.info("goRestHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goRestHome0801(){
		log.info("goRestHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0901", method = RequestMethod.GET)
	public ResponseEntity<List<Member>> goRestHome0901(){
		log.info("goRestHome0901() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		return new ResponseEntity<List<Member>>(list, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome1001", method = RequestMethod.GET)
	public ResponseEntity<Map<String, Member>> goRestHome1001(){
		log.info("goRestHome1001() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return new ResponseEntity<Map<String, Member>>(map, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome1101", method = RequestMethod.GET)
	public ResponseEntity<byte[]> goRestHome1101(){
		log.info("goRestHome1101() 실행...!");
		ResponseEntity<byte[]> entity = null;
		
		// C:\Users\PC_23\Pictures\Saved Pictures\spring.png
		InputStream in = null;
		HttpHeaders headers = new HttpHeaders();
		try {
			in = new FileInputStream("C:\\Users\\PC_23\\Pictures\\Saved Pictures\\spring.png");
			headers.setContentType(MediaType.IMAGE_PNG);
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return entity;
	}
	
}

package kr.or.ddit;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	/*
	 * [ 4장 : 컨트롤러 응답 ]
	 * 
	 * 		1. void 타입
	 * 
	 * 			- 호출하는 URL과 동일한 뷰 이름을 나타내가 위해 사용한다.
	 */
	
	// 요청 경로(/goHome0101)와 동일한 뷰(/goHome0101.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0101", method = RequestMethod.GET)
	public void goHome0101() {
		log.info("goHome0101() 실행...!");
	}
	
	// 요청 경로(/sub/goHome0102)와 동일한 뷰(/sub/goHome0102.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0102", method = RequestMethod.GET)
	public void goHome0102() {
		log.info("goHome0102() 실행...!");
	}
	
	/*
	 * 		2. String 타입
	 * 
	 * 			- 뷰 파일의 경로와 파일 이름을 나타내기 위해 사용한다.
	 */
	
	// 반환값이 home0201이므로 뷰(/home0201.jsp)를 가리킨다.
	@RequestMapping(value = "/goHome0201", method = RequestMethod.GET)
	public String goHome0201() {
		log.info("goHome0201() 실행...!");
		return "home0201";
	}
	
	// 반환값이 sub/home0203이므로 뷰(/sub/home0203.jsp)를 가리킨다.
	@RequestMapping(value = "/sub/goHome0203", method = RequestMethod.GET)
	public String goHome0203() {
		log.info("goHome0203() 실행...!");
		return "sub/home0203";
	}
	
	// 반환값이 "redirect:/"로 시작하면 리다이렉트 방식으로 처리한다.
	@RequestMapping(value = "/sub/goHome0204", method = RequestMethod.GET)
	public String goHome0204() {
		log.info("goHome0204() 실행...!");
		return "redirect:/sub/goHome0203";
	}
	
	// '/'로 시작하면 웹 애플리케이션의 컨텍스트 경로에 영향을 받지 않는 절대경로를 의미한다.
	// 해당경로 : D드라이브 > workspace > .metadata > .plugins > ... > Spring2Project > WEB-INF > views > sub > ... .jsp
	@RequestMapping(value = "/sub/goHome0205", method = RequestMethod.GET)
	public String goHome0205() {
		log.info("goHome0205() 실행...!");
		return "/sub/home0205";
	}
	
	/*
	 * 		3. 자바빈즈 클래스 타입(VO)
	 * 
	 * 			- JSON 객체 타입을 만들어서 반환하는 용도로 사용한다.
	 * 
	 * 			@ResponseBody를 지정하지 않으면 HTTP 404 에러가 발생한다.
	 * 			@ResponseBody가 객체를 리턴하여 객체를 응답 데이터로 보내는 역할을 한다.
	 * 			@ResponseBody의 리턴 default 데이터 형식은 json이다.
	 * 			@ResponseBody 대신에 @RestController를 이용하여 대체할 수 있다.
	 */
	
	@ResponseBody // 내보내고 있는 정보가 페이지 정보가 아닌 데이터 정보임을 인식시킴
	@RequestMapping(value = "/goHome0301", method = RequestMethod.GET)
	public Member goHome0301() {
		log.info("goHome0301() 실행...!");
		
		/*
		 * 객체를 응답으로 내보낼 때, @ResponseBody에 의한 데이터 형식은 json이다.
		 * 이 때, jackson-databind 라이브러리가 설정되어 있지 않은 상태에서 요청 시, 406 에러가 발생한다.
		 * 또, lombok 또는 VO에 getter/setter가 정상적으로 설정되어 있지 않은 경우에도 406 에러가 발생할 수 있다.
		 * @ResponseBody를 설정하지 않고 객체를 응답으로 내보낼 시, 데이터로 인식되는 것이 아닌 페이지로 인식되므로 404 에러가 발생한다.
		 */
		
		Member member = new Member();
		
		// 객체를 리턴하여 데이터를 확인하기 때문에 페이지 정보가 없다.
		return member;
	}
	
	/*
	 * 		4. 컬렉션 List 타입
	 * 
	 * 			- JSON 객체 배열 타입의 데이터를 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 List 타입이면 JSON 객체 배열 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0401", method = RequestMethod.GET)
	public List<Member> goHome0401(){
		log.info("goHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	/*
	 * 		5. 컬렉션 Map 타입
	 * 
	 * 			- Map 형태의 컬렉션 자료를 JSON 객체 타입의 데이터로 만들어서 반환하는 용도로 사용한다.
	 */
	
	// 반환값이 컬렉션 Map 타입이면 JSON 객체 타입으로 자동 변환된다.
	@ResponseBody
	@RequestMapping(value = "/goHome0501", method = RequestMethod.GET)
	public Map<String, Member> goHome0501(){
		log.info("goHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	/*
	 * 		6. ResponseEntity<Void> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 내용을 가공하는 용도로 사용한다.
	 */
	
	// 200 OK 상태코드를 전송한다.
	// Void 타입은 아무런 상태가 아닌데 제네릭 타입의 뭔가는 채워야 겠어서 채우는 placeholder같은 느낌이랄까?
	@ResponseBody
	@RequestMapping(value = "/goHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goHome0601(){
		log.info("goHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	/*
	 * 		7. ResponseEntity<String> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 문자열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// "SUCCESS" 메세지와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goHome0701(){
		log.info("goHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	/*
	 * 		8. ResponseEntity<자바빈즈> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 데이터를 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goHome0801(){
		log.info("goHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
	/*
	 * 		9. ResponseEntity<List> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 배열 데이터를 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 객체 배열 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome0901", method = RequestMethod.GET)
	public ResponseEntity<List<Member>> goHome0901(){
		log.info("goHome0901() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		return new ResponseEntity<List<Member>>(list, HttpStatus.OK);
	}
	
	/*
	 * 		10. ResponseEntity<Map> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 객체 데이터를 Map 형태로 전달하는 용도로 사용한다.
	 */
	
	// 객체의 JSON 객체 타입의 데이터와 200 OK 상태코드를 전송한다.
	@ResponseBody
	@RequestMapping(value = "/goHome1001", method = RequestMethod.GET)
	public ResponseEntity<Map<String, Member>> goHome1001(){
		log.info("goHome1001() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return new ResponseEntity<Map<String, Member>>(map, HttpStatus.OK);
	}
	
	/*
	 * 		11. ResponseEntity<byte[]> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 바이너리 파일 데이터를 전달하는 용도로 사용한다.
	 * 			- 파일을 처리하기 위해서 의존 라이브러리 commons-io를 추가한다. (pom.xml)
	 */
	
	@ResponseBody
	@RequestMapping(value = "/goHome1101", method = RequestMethod.GET)
	public ResponseEntity<byte[]> goHome1101(){
		log.info("goHome1101() 실행...!");
		ResponseEntity<byte[]> entity = null;
		
		// C:\Users\PC_23\Pictures\Saved Pictures\spring.png
		InputStream in = null;
		HttpHeaders headers = new HttpHeaders();
		try {
			in = new FileInputStream("C:\\Users\\PC_23\\Pictures\\Saved Pictures\\spring.png");
			headers.setContentType(MediaType.IMAGE_PNG);
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return entity;
	}
	
	@ResponseBody
	@RequestMapping(value = "/goHome1102", method = RequestMethod.GET)
	public ResponseEntity<byte[]> goHome1102() throws IOException{
		log.info("goHome1102() 실행...!");
		ResponseEntity<byte[]> entity = null;
		InputStream in = null;
		
		String fileName = "DDIT_Spring2_goHome1102.png";
		HttpHeaders header = new HttpHeaders();
		try {
			in = new FileInputStream("C:\\Users\\PC_23\\Pictures\\Saved Pictures\\spring.png");
			header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			header.add("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"");
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), header, HttpStatus.CREATED);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
		} finally {
			in.close();
		}
		
		return entity;
	}
	
}

- http://localhost/goHome1102


package kr.or.ddit;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class RestHomeController {

	@RequestMapping(value = "/goRestHome0301", method = RequestMethod.GET)
	public Member goRestHome0301() {
		log.info("goRestHome0301() 실행...!");
		Member member = new Member();
		return member;
	}
	
	@RequestMapping(value = "/goRestHome0401", method = RequestMethod.GET)
	public List<Member> goRestHome0401(){
		log.info("goRestHome0401() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		
		return list;
	}
	
	@RequestMapping(value = "/goRestHome0501", method = RequestMethod.GET)
	public Map<String, Member> goRestHome0501(){
		log.info("goRestHome0501() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return map;
	} 
	
	@RequestMapping(value = "/goRestHome0601", method = RequestMethod.GET)
	public ResponseEntity<Void> goRestHome0601(){
		log.info("goRestHome0601() 실행...!");
		/*
		 * 내가 요청한 url로 응답이 나가면서 응답데이터로 아무런 값이 전달되지 않는다.
		 * 해당 URL 요청 후, 브라우저에서 개발자 도구를 이용해서 네트워크 탭의 내역을 확인해보면 응답으로 URL이 나간걸 확인할 수 있는데,
		 * 이 때, 상태코드 200으로 정상 응답이 나간걸 확인할 수 있다.
		 * 그리고, 다른 기능으로 아무런 형태 없이 응답으로 나가지만 응답에 대한 header 정보를 변경하고자 할 때 사용할 수 있다.
		 */
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0701", method = RequestMethod.GET)
	public ResponseEntity<String> goRestHome0701(){
		log.info("goRestHome0701() 실행...!");
		return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0801", method = RequestMethod.GET)
	public ResponseEntity<Member> goRestHome0801(){
		log.info("goRestHome0801() 실행...!");
		Member member = new Member();
		return new ResponseEntity<Member>(member, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome0901", method = RequestMethod.GET)
	public ResponseEntity<List<Member>> goRestHome0901(){
		log.info("goRestHome0901() 실행...!");
		List<Member> list = new ArrayList<Member>();
		Member member = new Member();
		Member member2 = new Member();
		list.add(member);
		list.add(member2);
		return new ResponseEntity<List<Member>>(list, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome1001", method = RequestMethod.GET)
	public ResponseEntity<Map<String, Member>> goRestHome1001(){
		log.info("goRestHome1001() 실행...!");
		Map<String, Member> map = new HashMap<String, Member>();
		Member member = new Member();
		Member member2 = new Member();
		map.put("key1", member);
		map.put("key2", member2);
		return new ResponseEntity<Map<String, Member>>(map, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/goRestHome1101", method = RequestMethod.GET)
	public ResponseEntity<byte[]> goRestHome1101(){
		log.info("goRestHome1101() 실행...!");
		ResponseEntity<byte[]> entity = null;
		
		// C:\Users\PC_23\Pictures\Saved Pictures\spring.png
		InputStream in = null;
		HttpHeaders headers = new HttpHeaders();
		try {
			in = new FileInputStream("C:\\Users\\PC_23\\Pictures\\Saved Pictures\\spring.png");
			headers.setContentType(MediaType.IMAGE_PNG);
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return entity;
	}
	
	@RequestMapping(value = "/goRestHome1102", method = RequestMethod.GET)
	public ResponseEntity<byte[]> goRestHome1102() throws IOException{
		log.info("goRestHome1102() 실행...!");
		ResponseEntity<byte[]> entity = null;
		InputStream in = null;
		
		String fileName = "DDIT_Spring2_goHome1102.png";
		HttpHeaders header = new HttpHeaders();
		try {
			in = new FileInputStream("C:\\Users\\PC_23\\Pictures\\Saved Pictures\\spring.png");
			header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			header.add("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"");
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), header, HttpStatus.CREATED);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
		} finally {
			in.close();
		}
		
		return entity;
	}
	
}
	/*
	 * 		11. ResponseEntity<byte[]> 타입
	 * 
	 * 			- response 할 때 HTTP 헤더 정보와 바이너리 파일 데이터를 전달하는 용도로 사용한다.
	 * 			- 파일을 처리하기 위해서 의존 라이브러리 commons-io를 추가한다. (pom.xml)
	 * 
	 * 			무료/유료 이미지 다운로드 홈페이지를 사용해보면 이미지 미리보기 또는 미리보기 후 다운로드를 할 수 있는 기능이 제공된다.
	 * 			이와 같은 리턴타입의 형태를 설정해서 내보내는 것과 같다.
	 */
	
	@ResponseBody
	@RequestMapping(value = "/goHome1101", method = RequestMethod.GET)
	public ResponseEntity<byte[]> goHome1101(){
		log.info("goHome1101() 실행...!");
		ResponseEntity<byte[]> entity = null;
		
		// C:\Users\PC_23\Pictures\Saved Pictures\spring.png
		InputStream in = null;
		HttpHeaders headers = new HttpHeaders();
		try {
			// 파일 경로를 나타내는 방법 2가지
			// 방법 1 ('\\'), 방법 2 ('/')
			in = new FileInputStream("C:\\Users\\PC_23\\Pictures\\Saved Pictures\\spring.png");
			headers.setContentType(MediaType.IMAGE_PNG);
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return entity;
	}
	
	// 파일 데이터를 브라우저로 다운로드 받도록 한다.
	@ResponseBody
	@RequestMapping(value = "/goHome1102", method = RequestMethod.GET)
	public ResponseEntity<byte[]> goHome1102() throws IOException{
		log.info("goHome1102() 실행...!");
		ResponseEntity<byte[]> entity = null;
		InputStream in = null;
		
		String fileName = "DDIT_Spring2_goHome1102.png";
		HttpHeaders header = new HttpHeaders();
		try {
			in = new FileInputStream("C:\\Users\\PC_23\\Pictures\\Saved Pictures\\spring.png");
			// MediaType.APPLICATION_OCTET_STREAM은 이진 파일을 위한 기본값이다.
			header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			header.add("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"");
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), header, HttpStatus.CREATED);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
		} finally {
			in.close();
		}
		
		return entity;
	}

[MemberController.java]

package kr.or.ddit.controller.member;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class MemberController {

	/*
	 * [ 5장 : 컨트롤러 요청 처리 ]
	 * 
	 * 		1. 컨트롤러 메서드 매개변수
	 * 
	 * 			- Model : 이동 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- RedirectAttributes : 리다이렉트 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- 자바빈즈 클래스 : 요청 파라미터를 가지고 있는 자바빈즈 클래스
	 * 			- MultipartFile : 멀티파트 요청을 사용해 업로드된 파일 정보를 가지고 있는 인터페이스
	 * 			- BindingResult : 도메인 클래스의 입력값 검증 결과를 가지고 있는 인터페이스
	 * 			- Locale : 클라이언트 Locale
	 * 			- Principal : 클라이언트 인증을 위한 사용자 정보를 가지고 있는 인터페이스
	 */
	
	// 요청 처리 페이지
	@RequestMapping(value = "/registerForm", method = RequestMethod.GET)
	public String registerForm() {
		log.info("registerForm() 실행...!");
		return "member/registerForm";
	}
	
}

[registerForm.jsp]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>RegisterForm</title>
	</head>
	<body>
		<h3>REGISTER FORM</h3>
		<hr /><br />
		
		<h4>2. 요청 처리</h4>
		<hr />
	</body>
</html>

- http://localhost/registerForm


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>RegisterForm</title>
	</head>
	<body>
		<h3>REGISTER FORM</h3>
		<hr /><br />
		
		<h4>2. 요청 처리</h4>
		<hr />
		
		<p>1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register?userId=hongkd&password=1234">Button1</a>
		<br />
		
	</body>
</html>
package kr.or.ddit.controller.member;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class MemberController {

	/*
	 * [ 5장 : 컨트롤러 요청 처리 ]
	 * 
	 * 		1. 컨트롤러 메서드 매개변수
	 * 
	 * 			- Model : 이동 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- RedirectAttributes : 리다이렉트 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- 자바빈즈 클래스 : 요청 파라미터를 가지고 있는 자바빈즈 클래스
	 * 			- MultipartFile : 멀티파트 요청을 사용해 업로드된 파일 정보를 가지고 있는 인터페이스
	 * 			- BindingResult : 도메인 클래스의 입력값 검증 결과를 가지고 있는 인터페이스
	 * 			- Locale : 클라이언트 Locale
	 * 			- Principal : 클라이언트 인증을 위한 사용자 정보를 가지고 있는 인터페이스
	 */
	
	// 요청 처리 페이지
	@RequestMapping(value = "/registerForm", method = RequestMethod.GET)
	public String registerForm() {
		log.info("registerForm() 실행...!");
		return "member/registerForm";
	}
	
	// 1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public String registerByParameter(String userId, String password) {
		log.info("registerByParameter() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
}

- http://localhost/registerForm


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>RegisterForm</title>
	</head>
	<body>
		<h3>REGISTER FORM</h3>
		<hr /><br />
		
		<h4>2. 요청 처리</h4>
		<hr />
		
		<p>1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register?userId=hongkd&password=1234">Button1</a>
		<br />
		
		<p>2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register/hongkd">Button2</a>
		<br />
	</body>
</html>
package kr.or.ddit.controller.member;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class MemberController {

	/*
	 * [ 5장 : 컨트롤러 요청 처리 ]
	 * 
	 * 		1. 컨트롤러 메서드 매개변수
	 * 
	 * 			- Model : 이동 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- RedirectAttributes : 리다이렉트 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- 자바빈즈 클래스 : 요청 파라미터를 가지고 있는 자바빈즈 클래스
	 * 			- MultipartFile : 멀티파트 요청을 사용해 업로드된 파일 정보를 가지고 있는 인터페이스
	 * 			- BindingResult : 도메인 클래스의 입력값 검증 결과를 가지고 있는 인터페이스
	 * 			- Locale : 클라이언트 Locale
	 * 			- Principal : 클라이언트 인증을 위한 사용자 정보를 가지고 있는 인터페이스
	 */
	
	// 요청 처리 페이지
	@RequestMapping(value = "/registerForm", method = RequestMethod.GET)
	public String registerForm() {
		log.info("registerForm() 실행...!");
		return "member/registerForm";
	}
	
	// 1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public String registerByParameter(String userId, String password) {
		log.info("registerByParameter() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
	// 2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register/{userId}", method = RequestMethod.GET)
	public String registerByPath(@PathVariable String userId) {
		// 넘겨 받은 userId를 경로상에서 꺼낼 때, @PathVariable를 이용한다.
		log.info("registerByPath() 실행...!");
		log.info("userId : " + userId);
		return "success";
	}
	
}

- http://localhost/registerForm


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>RegisterForm</title>
	</head>
	<body>
		<h3>REGISTER FORM</h3>
		<hr /><br />
		
		<h4>2. 요청 처리</h4>
		<hr />
		
		<p>1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register?userId=hongkd&password=1234">Button1</a>
		<br />
		
		<p>2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register/hongkd">Button2</a>
		<br />
		
		<p>
			3) HTML Form 필드명과 컨트롤러 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.<br />
		</p>
		<form action="/register01" method="post">
			userId : <input type="text" name="userId" /><br />
			password : <input type="text" name="password" /><br />
			coin : <input type="text" name="coin" /><br />
			<button type="submit">전송</button>
		</form>
		<br />
	</body>
</html>
package kr.or.ddit.controller.member;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class MemberController {

	/*
	 * [ 5장 : 컨트롤러 요청 처리 ]
	 * 
	 * 		1. 컨트롤러 메서드 매개변수
	 * 
	 * 			- Model : 이동 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- RedirectAttributes : 리다이렉트 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- 자바빈즈 클래스 : 요청 파라미터를 가지고 있는 자바빈즈 클래스
	 * 			- MultipartFile : 멀티파트 요청을 사용해 업로드된 파일 정보를 가지고 있는 인터페이스
	 * 			- BindingResult : 도메인 클래스의 입력값 검증 결과를 가지고 있는 인터페이스
	 * 			- Locale : 클라이언트 Locale
	 * 			- Principal : 클라이언트 인증을 위한 사용자 정보를 가지고 있는 인터페이스
	 */
	
	// 요청 처리 페이지
	@RequestMapping(value = "/registerForm", method = RequestMethod.GET)
	public String registerForm() {
		log.info("registerForm() 실행...!");
		return "member/registerForm";
	}
	
	// 1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public String registerByParameter(String userId, String password) {
		log.info("registerByParameter() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
	// 2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register/{userId}", method = RequestMethod.GET)
	public String registerByPath(@PathVariable String userId) {
		// 넘겨 받은 userId를 경로상에서 꺼낼 때, @PathVariable를 이용한다.
		log.info("registerByPath() 실행...!");
		log.info("userId : " + userId);
		return "success";
	}
	
	// 3) HTML Form 필드명과 컨트롤러 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register01", method = RequestMethod.POST)
	public String register01(String userId, String password) {
		log.info("register01() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
}

- http://localhost/registerForm


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>RegisterForm</title>
	</head>
	<body>
		<h3>REGISTER FORM</h3>
		<hr /><br />
		
		<h4>2. 요청 처리</h4>
		<hr />
		
		<p>1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register?userId=hongkd&password=1234">Button1</a>
		<br />
		
		<p>2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register/hongkd">Button2</a>
		<br />
		
		<p>
			3) HTML Form 필드명과 컨트롤러 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.<br />
		</p>
		<form action="/register01" method="post">
			userId : <input type="text" name="userId" /><br />
			password : <input type="text" name="password" /><br />
			coin : <input type="text" name="coin" /><br />
			<button type="submit">전송</button>
		</form>
		<br />
		
		<p>
			4) HTML Form 필드 값이 숫자일 경우에는 숫자로 타입 변환되어 데이터를 취득할 수 있다.<br />
		</p>
		<form action="/register02" method="post">
			userId : <input type="text" name="userId" /><br />
			password : <input type="text" name="password" /><br />
			coin : <input type="text" name="coin" /><br />
			<button type="submit">전송</button>
		</form>
		<br />
	</body>
</html>
package kr.or.ddit.controller.member;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class MemberController {

	/*
	 * [ 5장 : 컨트롤러 요청 처리 ]
	 * 
	 * 		1. 컨트롤러 메서드 매개변수
	 * 
	 * 			- Model : 이동 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- RedirectAttributes : 리다이렉트 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- 자바빈즈 클래스 : 요청 파라미터를 가지고 있는 자바빈즈 클래스
	 * 			- MultipartFile : 멀티파트 요청을 사용해 업로드된 파일 정보를 가지고 있는 인터페이스
	 * 			- BindingResult : 도메인 클래스의 입력값 검증 결과를 가지고 있는 인터페이스
	 * 			- Locale : 클라이언트 Locale
	 * 			- Principal : 클라이언트 인증을 위한 사용자 정보를 가지고 있는 인터페이스
	 */
	
	// 요청 처리 페이지
	@RequestMapping(value = "/registerForm", method = RequestMethod.GET)
	public String registerForm() {
		log.info("registerForm() 실행...!");
		return "member/registerForm";
	}
	
	// 1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public String registerByParameter(String userId, String password) {
		log.info("registerByParameter() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
	// 2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register/{userId}", method = RequestMethod.GET)
	public String registerByPath(@PathVariable String userId) {
		// 넘겨 받은 userId를 경로상에서 꺼낼 때, @PathVariable를 이용한다.
		log.info("registerByPath() 실행...!");
		log.info("userId : " + userId);
		return "success";
	}
	
	// 3) HTML Form 필드명과 컨트롤러 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register01", method = RequestMethod.POST)
	public String register01(String userId, String password) {
		log.info("register01() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
	// 4) HTML Form 필드 값이 숫자일 경우에는 숫자로 타입 변환되어 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register02", method = RequestMethod.POST)
	public String register02(String userId, String password, int coin) {
		log.info("register02() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		log.info("coin : " + coin);
		return "success";
	}
	
}

- http://localhost/registerForm


	// 3) HTML Form 필드명과 컨트롤러 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.
	//		그리고, 매개변수의 위치는 순서에 상관없고 오직 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register01", method = RequestMethod.POST)
	public String register01(String userId, String password) {
		log.info("register01() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
	// 4) HTML Form 필드 값이 숫자일 경우에는 숫자로 타입 변환되어 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register02", method = RequestMethod.POST)
	public String register02(String userId, String password, int coin) {
		log.info("register02() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		log.info("coin : " + coin);
		return "success";
	}

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>RegisterForm</title>
	</head>
	<body>
		<h3>REGISTER FORM</h3>
		<hr /><br />
		
		<h4>2. 요청 처리</h4>
		<hr />
		
		<p>1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register?userId=hongkd&password=1234">Button1</a>
		<br />
		
		<p>2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register/hongkd">Button2</a>
		<br />
		
		<p>
			3) HTML Form 필드명과 컨트롤러 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.<br />
		</p>
		<form action="/register01" method="post">
			userId : <input type="text" name="userId" /><br />
			password : <input type="text" name="password" /><br />
			coin : <input type="text" name="coin" /><br />
			<button type="submit">전송</button>
		</form>
		<br />
		
		<p>
			4) HTML Form 필드 값이 숫자일 경우에는 숫자로 타입 변환되어 데이터를 취득할 수 있다.<br />
		</p>
		<form action="/register02" method="post">
			userId : <input type="text" name="userId" /><br />
			password : <input type="text" name="password" /><br />
			coin : <input type="text" name="coin" /><br />
			<button type="submit">전송</button>
		</form>
		<br />
		
		<hr /><br />
		
		<h4>3. 요청 데이터 처리 어노테이션</h4>
		<hr />
		
		<p>1) URL 경로 상의 경로 변수가 여러 개일 떄, @PathVariable 어노테이션을 사용하여 특정한 경로 변수명을 지정해준다.</p>
		<a href="/register/hongkd/100">Button3</a><br />
	</body>
</html>
package kr.or.ddit.controller.member;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class MemberController {

	/*
	 * [ 5장 : 컨트롤러 요청 처리 ]
	 * 
	 * 		1. 컨트롤러 메서드 매개변수
	 * 
	 * 			- Model : 이동 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- RedirectAttributes : 리다이렉트 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- 자바빈즈 클래스 : 요청 파라미터를 가지고 있는 자바빈즈 클래스
	 * 			- MultipartFile : 멀티파트 요청을 사용해 업로드된 파일 정보를 가지고 있는 인터페이스
	 * 			- BindingResult : 도메인 클래스의 입력값 검증 결과를 가지고 있는 인터페이스
	 * 			- Locale : 클라이언트 Locale
	 * 			- Principal : 클라이언트 인증을 위한 사용자 정보를 가지고 있는 인터페이스
	 */
	
	// 요청 처리 페이지
	@RequestMapping(value = "/registerForm", method = RequestMethod.GET)
	public String registerForm() {
		log.info("registerForm() 실행...!");
		return "member/registerForm";
	}
	
	// 1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public String registerByParameter(String userId, String password) {
		log.info("registerByParameter() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
	// 2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register/{userId}", method = RequestMethod.GET)
	public String registerByPath(@PathVariable String userId) {
		// 넘겨 받은 userId를 경로상에서 꺼낼 때, @PathVariable를 이용한다.
		log.info("registerByPath() 실행...!");
		log.info("userId : " + userId);
		return "success";
	}
	
	// 3) HTML Form 필드명과 컨트롤러 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.
	//		그리고, 매개변수의 위치는 순서에 상관없고 오직 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register01", method = RequestMethod.POST)
	public String register01(String userId, String password) {
		log.info("register01() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
	// 4) HTML Form 필드 값이 숫자일 경우에는 숫자로 타입 변환되어 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register02", method = RequestMethod.POST)
	public String register02(String userId, String password, int coin) {
		log.info("register02() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		log.info("coin : " + coin);
		return "success";
	}
	
	/*
	 * 		3. 요청 데이터 처리 어노테이션
	 * 
	 * 			- @PathVariable : URL에서 경로 변수 값을 가져오기 위한 어노테이션
	 * 			- @RequestParam : 요청 파라미터 값을 가져오기 위한 어노테이션
	 * 			- @RequestHeader : 요청 헤더 값을 가져오기 위한 어노테이션
	 * 			- @RequestBody : 요청 본문 내용을 가져오기 위한 어노테이션
	 * 			- @CookieValue : 쿠키 값을 가져오기 위한 어노테이션
	 */
	
	// 1) URL 경로 상의 경로 변수가 여러 개 일때 @PathVariable 어노테이션을 사용하여 특정한 경로 변수명을 지정해 준다.
	@RequestMapping(value = "/register/{userId}/{coin}", method = RequestMethod.GET)
	public String registerByPath(
			@PathVariable("userId") String userId,
			@PathVariable("coin") int coin
			) {
		log.info("registerByPath() 실행...!");
		log.info("userId : " + userId);
		log.info("coin : " + coin);
		return "success";
	}
	
}

- http://localhost/registerForm


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>RegisterForm</title>
	</head>
	<body>
		<h3>REGISTER FORM</h3>
		<hr /><br />
		
		<h4>2. 요청 처리</h4>
		<hr />
		
		<p>1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register?userId=hongkd&password=1234">Button1</a>
		<br />
		
		<p>2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.</p>
		<a href="/register/hongkd">Button2</a>
		<br />
		
		<p>
			3) HTML Form 필드명과 컨트롤러 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.<br />
		</p>
		<form action="/register01" method="post">
			userId : <input type="text" name="userId" /><br />
			password : <input type="text" name="password" /><br />
			coin : <input type="text" name="coin" /><br />
			<button type="submit">전송</button>
		</form>
		<br />
		
		<p>
			4) HTML Form 필드 값이 숫자일 경우에는 숫자로 타입 변환되어 데이터를 취득할 수 있다.<br />
		</p>
		<form action="/register02" method="post">
			userId : <input type="text" name="userId" /><br />
			password : <input type="text" name="password" /><br />
			coin : <input type="text" name="coin" /><br />
			<button type="submit">전송</button>
		</form>
		<br />
		
		<hr /><br />
		
		<h4>3. 요청 데이터 처리 어노테이션</h4>
		<hr />
		
		<p>1) URL 경로 상의 경로 변수가 여러 개일 떄, @PathVariable 어노테이션을 사용하여 특정한 경로 변수명을 지정해준다.</p>
		<a href="/register/hongkd/100">Button3</a><br />
		
		<p>2) @RequestParam 어노테이션을 사용하여 특정한 HTML Form의 필드명을 지정하여 요청을 처리한다.</p>
		<form action="/register0202" method="post">
			userId : <input type="text" name="userId" /><br />
			password : <input type="text" name="password" /><br />
			coin : <input type="text" name="coin" /><br />
			<button type="submit">전송</button>
		</form>
	</body>
</html>
package kr.or.ddit.controller.member;

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

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class MemberController {

	/*
	 * [ 5장 : 컨트롤러 요청 처리 ]
	 * 
	 * 		1. 컨트롤러 메서드 매개변수
	 * 
	 * 			- Model : 이동 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- RedirectAttributes : 리다이렉트 대상에 전달할 데이터를 가지고 있는 인터페이스
	 * 			- 자바빈즈 클래스 : 요청 파라미터를 가지고 있는 자바빈즈 클래스
	 * 			- MultipartFile : 멀티파트 요청을 사용해 업로드된 파일 정보를 가지고 있는 인터페이스
	 * 			- BindingResult : 도메인 클래스의 입력값 검증 결과를 가지고 있는 인터페이스
	 * 			- Locale : 클라이언트 Locale
	 * 			- Principal : 클라이언트 인증을 위한 사용자 정보를 가지고 있는 인터페이스
	 */
	
	// 요청 처리 페이지
	@RequestMapping(value = "/registerForm", method = RequestMethod.GET)
	public String registerForm() {
		log.info("registerForm() 실행...!");
		return "member/registerForm";
	}
	
	// 1) URL 경로 상의 쿼리 파라미터 정보로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public String registerByParameter(String userId, String password) {
		log.info("registerByParameter() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
	// 2) URL 경로 상의 경로 변수로부터 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register/{userId}", method = RequestMethod.GET)
	public String registerByPath(@PathVariable String userId) {
		// 넘겨 받은 userId를 경로상에서 꺼낼 때, @PathVariable를 이용한다.
		log.info("registerByPath() 실행...!");
		log.info("userId : " + userId);
		return "success";
	}
	
	// 3) HTML Form 필드명과 컨트롤러 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.
	//		그리고, 매개변수의 위치는 순서에 상관없고 오직 매개변수명이 일치하면 요청 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register01", method = RequestMethod.POST)
	public String register01(String userId, String password) {
		log.info("register01() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		return "success";
	}
	
	// 4) HTML Form 필드 값이 숫자일 경우에는 숫자로 타입 변환되어 데이터를 취득할 수 있다.
	@RequestMapping(value = "/register02", method = RequestMethod.POST)
	public String register02(String userId, String password, int coin) {
		log.info("register02() 실행...!");
		log.info("userId : " + userId);
		log.info("password : " + password);
		log.info("coin : " + coin);
		return "success";
	}
	
	/*
	 * 		3. 요청 데이터 처리 어노테이션
	 * 
	 * 			- @PathVariable : URL에서 경로 변수 값을 가져오기 위한 어노테이션
	 * 			- @RequestParam : 요청 파라미터 값을 가져오기 위한 어노테이션
	 * 			- @RequestHeader : 요청 헤더 값을 가져오기 위한 어노테이션
	 * 			- @RequestBody : 요청 본문 내용을 가져오기 위한 어노테이션
	 * 			- @CookieValue : 쿠키 값을 가져오기 위한 어노테이션
	 */
	
	// 1) URL 경로 상의 경로 변수가 여러 개 일때 @PathVariable 어노테이션을 사용하여 특정한 경로 변수명을 지정해 준다.
	@RequestMapping(value = "/register/{userId}/{coin}", method = RequestMethod.GET)
	public String registerByPath(
			@PathVariable("userId") String userId,
			@PathVariable("coin") int coin
			) {
		log.info("registerByPath() 실행...!");
		log.info("userId : " + userId);
		log.info("coin : " + coin);
		return "success";
	}
	
	// 2) @RequestParam 어노테이션을 사용하여 특정한 HTML Form의 필드명을 지정하여 요청을 처리한다.
	@RequestMapping(value = "/register0202", method = RequestMethod.POST)
	public String register0202(
			@RequestParam("userId") String username, String password, int coin
			) {
		log.info("registerByPath() 실행...!");
		log.info("username : " + username);
		log.info("password : " + password);
		log.info("coin : " + coin);
		return "success";
	}
	
}

- http://localhost/registerForm