MVC 디자인 패턴
- 프로그램을 효율적으로 개발하기 위해서 코드를 3가지로 구분하여 개발을 진행하고자 하는 디자인 패턴
- 프로그램의 비즈니스 로직과 화면을 구분하는데에 초점을 맞춘 디자인 패턴
- Model, View, Controller 세 가지로 나뉜다.
- Model : 데이터의 형태를 표현하기 위한 용도의 코드
- View : 사용자에게 보여지는 화면을 꾸미기 위한 용도의 코드 (html, css, js, jsp, ...)
- Controller : 요청을 받으면 어떤 서비스를 거쳐 어떤 뷰로 가야할지를 결정하는 코드
@Controller
- 해당 MVC 패턴 중 Controller임을 표시하는 어노테이션
- spring-context가 자동으로 수거해 알아서 사용한다.
- uri + method에 대해 어떤 처리를 하고 어떤 뷰로 가야하는지를 정의하는 곳이다.
- 다른 uri에서 같은 처리를 진행할 수도 있으므로 컨트롤러에서 비즈니스 로직을 구현하는 것을 바람직하지 않다.
컨트롤러에서 자동으로 받을 수 있는 인자값들
1. HttpServletRequest
- 컨트롤러에서 JSP의 request 객체를 받아서 사용할 수 있다.
2. HttpServletResponse
- 컨트롤러에서 JSP의 response 객체를 받아서 사용할 수 있다.
3. 자바빈 형태의 모델 객체
- 파라미터의 이름과 모델 객체의 필드명이 동일하다면 값을 바인딩해준다.
- 심지어, 데이터 타입도 알아서 변환해준다. (파라미터는 원래 String이었지만 age를 Integer로 변환하여 넣어준다.)
- 만약 바인딩이 성공했다면 view에서 사용할 수 있도록 자동으로 어트리뷰트에 추가해준다.
4. 전달받는 파라미터의 name과 같은 이름의 변수
- 메서드에 파라미터와 같은 이름의 매개변수를 선언해두면 값이 바인딩된다.
- 타입도 알아서 변환해준다.
- 기본적으로 어트리뷰트에 자동으로 추가되지는 않는다.
- 매개변수 앞에 @ModelAttribute("name")을 사용하는 경우 어트리뷰트에도 추가된다.
5. HttpSession
- 세션 객체를 꺼내 활용할 수 있다.
컨트롤러의 리턴 타입
1. 다음 view 페이지를 찾는 타입
- String : 리턴하는 문자열의 앞에는 /WEB-INF/views/를 더하고 뒤에는 .jsp를 더해 다음 view페이지를 찾아 포워드한다.
리턴하는 문자열 앞에 redirect:를 붙이면 리다이렉트를 응답한다.
- void : 컨트롤러로 접속할 때 사용했던 URI를 그대로 사용해 다음 view를 찾는다.
2. view를 찾지 않는 타입
- 자바빈 객체 타입으로 리턴 : 웹 페이지 코드 대신 데이터를 바로 응답한다.
- ResponseEntity : 직접 원하는 응답을 생성하여 응답한다. (직접 커스텀)
HttpServletRequest와 HttpServletResponse
package com.ezen.springmvc.controller;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.ezen.springmvc.model.Survey;
import lombok.extern.log4j.Log4j;
@Log4j
@Controller
public class HelloController {
// 해당 컨트롤러에서 필요한 것을 메서드 인자에 정의해두면 알아서 채워준다.
@PostMapping("/survey/")
String addSurvey(HttpServletRequest request, HttpServletResponse response) throws IOException {
String name = request.getParameter("name");
String age = request.getParameter("age");
log.info("name: " + name);
log.info("age: " + age);
if (name == null || age == null || name.trim().equals("") || age.trim().equals("")) {
response.sendRedirect(request.getContextPath() + "/");
return null;
}
request.setAttribute("name", name);
request.setAttribute("age", age);
return "survey/result";
}
}
자바빈 형태의 모델 객체
package com.ezen.springmvc.model;
import lombok.Data;
@Data
public class Survey {
private String name;
private Integer age;
}
package com.ezen.springmvc.controller;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.ezen.springmvc.model.Survey;
import lombok.extern.log4j.Log4j;
@Log4j
@Controller
public class HelloController {
@PostMapping("/survey/2")
String addSurvey2(Survey survey) {
// 모델 클래스를 메서드의 인자로 설정해두면 파라미터로부터 받은 데이터를 바인딩해준다. (알아서 채워줌)
// form에 설정한 name 속성값과 모델 클래스(dto, vo)의 변수명이 일치해야 바인딩이 가능하다.
log.info(survey);
// 바인딩이 성공하는 경우 해당 인스턴스는 어트리뷰트에 자동으로 추가된다.
return "survey/result2";
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>설문결과</title>
</head>
<body>
<h3>데이터 클래스 바인딩 결과</h3>
<p>컨트롤러에서 바인딩이 성공적으로 진행된다면 자동으로 어트리뷰트에도 추가해준다.</p>
<p>${survey}</p>
</body>
</html>
전달받는 파라미터의 name과 같은 이름의 변수
package com.ezen.springmvc.controller;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.ezen.springmvc.model.Survey;
import lombok.extern.log4j.Log4j;
@Log4j
@Controller
public class HelloController {
@RequestMapping(value = "/survey/3", method = RequestMethod.POST)
String addSurvey3(@ModelAttribute("name") String name, @ModelAttribute("age") Integer age) {
log.error("name : " + name);
log.error("age : " + age);
return "survey/result";
}
}
void 리턴 타입
package com.ezen.springmvc.controller;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.ezen.springmvc.model.Survey;
import lombok.extern.log4j.Log4j;
@Log4j
@Controller
public class HelloController {
@GetMapping("/test/abc")
void index(Model model) {
// request.setAttribute()와 같은 것
model.addAttribute("name", "I'm index1");
}
}
'Spring' 카테고리의 다른 글
[Spring] Mybatis (0) | 2023.07.06 |
---|---|
[Spring] Connection Pool (0) | 2023.07.06 |
[Spring] Lombok (0) | 2023.07.04 |
[Spring] Log4j (0) | 2023.07.04 |
[Spring] JUnit (0) | 2023.07.04 |