[Spring]그림으로 배우는 스프링 6 - 11장 스프링 MVC

Gaeng·2024년 11월 20일

[Spring] 공부

목록 보기
11/21
post-thumbnail

책을 기반을 내용을 정리하고 추가했습니다. Thymeleaf 내용은 스킵하고 기본적인 개념만 정리했습니다.

MVC패턴?

1-1 MVC?

MVC는 사용자 인터페이스를 가진 애플리케이션을 개발할 때 적용하는 일반적인 설계 개념으로 MVC패턴으로 불림.

역할

  • Model : 업무 로직(Service), 데이터 보유(Entity), 데이터 접근(Repository)
  • View : 화면을 표현하기 위한 HTML 생성
  • Controll : Request -> Response에 대한 전체 흐름도
단계동작 흐름설명
1브라우저 → Controller사용자가 브라우저를 통해 요청을 보냄
2Controller → ModelController가 요청을 처리하고 Model 호출
3Model ↔ 데이터베이스Model이 데이터베이스와 통신하여 데이터 처리
4Model → Controller처리된 데이터를 Controller에 반환
5Controller → ViewController가 데이터를 View에 전달
6View → 브라우저View가 데이터를 렌더링하여 사용자에게 응답

1-2 스프링MVC

스프링 MVC는 MVC 패턴의 사고방식에 따라 효율적으로 web application을 만들 수 있게 하는 것이 스프링의 기능.
Controller는 Bean으로 관리되므로 Service 등의 의존 객체를 인젝션하여 사용할 수 있음.

2. Controller 클래스 설정.

@Controller는 스테레오 어노테이션 중 하나로, 컴포넌트로 스캔되어 Bean으로 관리.
또한 스프링MVC에 Controller 클래스로 인식되어 스프링 MVC가 제공하는 어노테이션을 사용할 수 있게 됨.

//예시 코드
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String sayHello(Model model) {
        // Model에 데이터를 추가
        model.addAttribute("message", "안녕하세요, MVC 패턴!");

        // "hello"라는 이름의 뷰를 반환
        return "hello";
    }
}

설명

  • @Controller: 이 클래스가 컨트롤러 역할을 한다고 선언합니다.
  • @GetMapping("/hello"): /hello 경로로 GET 요청이 오면 sayHello 메서드를 실행합니다.
  • Model: 뷰(View)에 데이터를 전달하기 위해 사용됩니다.
  • return "hello": 뷰의 이름으로 hello.html (혹은 hello.jsp)를 반환합니다.

3. MVC 내부구조 전체 처리 흐름.

Spring MVC의 내부 동작을 보여주는 이 그림은 요청이 클라이언트(브라우저)에서 시작되어 DispatcherServlet을 거쳐 최종적으로 View로 응답되는 과정

단계구성 요소설명
1브라우저클라이언트가 HTTP 요청을 보냅니다. 예를 들어, 특정 URL 요청을 전송합니다.
2DispatcherServlet모든 요청을 받아 적절한 처리 흐름을 결정합니다.
3Handler Mapping요청 URL과 관련된 컨트롤러를 찾아 DispatcherServlet에 전달합니다.
4Handler Adapter컨트롤러를 호출하기 위해 필요한 추가 작업(데이터 바인딩 등)을 수행합니다.
5Controller요청을 처리하고 비즈니스 로직을 실행하거나 Service와 상호작용합니다.
6Model컨트롤러에서 데이터를 저장하여 View에 전달합니다.
7View Resolver컨트롤러가 반환한 뷰 이름을 기반으로 실제 뷰 템플릿을 찾습니다.
8View데이터를 렌더링하여 HTML 등의 형식으로 클라이언트에 반환합니다.
9클라이언트(브라우저)최종적으로 클라이언트가 렌더링된 HTML 응답을 받습니다.

4. Service 객체 인젝션

Contrller 객체는 Service 객체의 메서드를 호출해야 하기 때문에 Service 객체가 필요함.

  • 생성자 주입을 통한 서비스 객체 주입
    생성자 주입은 의존성을 주입하는 가장 권장되는 방식으로, 불변성을 보장하고 테스트 용이성을 높여줍니다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class SampleController {

    private final SampleService sampleService;

    public SampleController(SampleService sampleService) {
        this.sampleService = sampleService;
    }

    @GetMapping("/sample")
    public String getSample(Model model) {
        String data = sampleService.getData();
        model.addAttribute("data", data);
        return "sampleView";
    }
}

5. 핸들러 메서드와 @XxxMapping

@RequestMapping은 Spring MVC에서 HTTP 요청컨트롤러의 메서드를 매핑하는 데 사용됩니다. 이를 통해 특정 URL 경로와 메서드를 연결하여 요청을 처리할 수 있습니다.

핸들러 메서드 동작 과정
1. 클라이언트 요청 → DispatcherServlet이 요청을 받음.
2. @RequestMapping URL과 매핑된 핸들러 메서드를 호출.
3. 메서드가 데이터를 준비하여 반환 (뷰 이름 또는 JSON 응답).
4. DispatcherServlet이 반환 데이터를 뷰로 렌더링하거나 직접 응답으로 반환.

핵심 개념

  1. @RequestMapping:
    • 클래스나 메서드 수준에서 사용 가능.
    • URL 경로, HTTP 메서드(GET, POST 등), 요청 매체 유형 등을 설정.
    • 기본적으로 모든 HTTP 메서드(GET, POST 등)를 처리하지만, 명시적으로 제한 가능.
  2. 핸들러 메서드:
    • 요청을 처리하고 응답을 반환하는 메서드.
    • 요청 URL에 따라 실행되며, 비즈니스 로직을 처리하거나 서비스를 호출.
    • 뷰 이름을 반환하거나 JSON, XML 같은 데이터를 직접 반환 가능.

@RequestMapping 사용

  @Controller
  @RequestMapping("/example") // 클래스 레벨 매핑
  public class ExampleController {

      @RequestMapping(value = "/hello", method = RequestMethod.GET)
      public String sayHello(Model model) {
          model.addAttribute("message", "안녕하세요, Spring MVC!");
          return "helloView"; // 뷰 이름 반환 (예: helloView.html)
      }
  }

축약 어노테이션 사용 (@GetMapping, @PostMapping 등)

장점: 코드가 간결해지고, HTTP 메서드가 더 명확하게 드러납니다.
Spring 4.3 이상에서는 @RequestMapping의 축약형 어노테이션을 사용할 수 있습니다:

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping
  import org.springframework.web.bind.annotation.*;

  @RestController
  @RequestMapping("/api")
  public class ApiController {

      @GetMapping("/get")
      public String handleGet() {
          return "GET 요청 처리";
      }

      @PostMapping("/post")
      public String handlePost() {
          return "POST 요청 처리";
      }
  }

핸들러 메서드 요청 방식

매핑 방식어노테이션설명예시
Path Variable@PathVariableURL 경로에서 변수로 값을 전달받음/users/{id}@PathVariable("id") Long id
Query Parameter@RequestParamURL 쿼리 문자열에서 값을 추출/search?query=book@RequestParam("query") String query
Request Body@RequestBodyHTTP 요청 본문에서 JSON, XML 데이터를 객체로 매핑{ "name": "John", "age": 25 }@RequestBody User user
HTTP Header@RequestHeaderHTTP 요청 헤더에서 값을 추출Authorization: Bearer <token>@RequestHeader("Authorization") String token
Cookie@CookieValueHTTP 요청 쿠키에서 값을 추출Cookie: sessionId=abc123@CookieValue("sessionId") String sessionId
Matrix Variable@MatrixVariableURL 경로에서 세미콜론(;)으로 구분된 데이터를 추출/users;name=John;age=30@MatrixVariable("name") String name
File Upload@RequestParamHTTP 요청 본문에서 파일 데이터를 처리<input type="file" name="file">@RequestParam("file") MultipartFile file

6. Bean Validation을 이용한 입력 검사

  • 입력 검사 기술로는 자바 표준 기술인 Bean Validation을 이용하는 것이 편리.
  • Spring MVC는 Bean Validation과 원활하게 연동 가능

Bean Validation 주요 어노테이션

어노테이션설명사용 예시
@NotNull값이 null이 아니어야 함@NotNull private String name;
@NotEmpty문자열, 컬렉션 등이 null이거나 비어 있지 않아야 함@NotEmpty private String name;
@NotBlank문자열이 null, 공백(스페이스) 또는 빈 문자열이 아니어야 함@NotBlank private String name;
@Size문자열, 컬렉션, 배열 등의 크기가 지정된 범위 내에 있어야 함@Size(min=2, max=30) private String name;
@Min숫자가 지정된 최소값 이상이어야 함@Min(18) private int age;
@Max숫자가 지정된 최대값 이하여야 함@Max(65) private int age;
@Email유효한 이메일 형식이어야 함@Email private String email;
@Pattern특정 정규 표현식에 맞는 문자열이어야 함@Pattern(regexp="^[a-zA-Z0-9]*$") private String username;
@AssertTrue값이 true여야 함@AssertTrue private boolean isActive;
@AssertFalse값이 false여야 함@AssertFalse private boolean isInactive;
@Null값이 null이어야 함@Null private String deprecatedField;

7. 오류 문구 설정

입력 오류 시 화면에 표시되는 문구는 기본으로 제공되지만 임의의 문구로 지정 가능. 오류 문구는 프로파티 파일로 지정해야함.

  • message.properties resource 아래에 설정하면 됨.
# Bean Validation 메시지
NotNull.user.name = 이름은 반드시 입력해야 합니다.
Size.user.name = 이름은 {min}자 이상 {max}자 이하로 입력해야 합니다.
Email.user.email = 유효한 이메일 주소를 입력하세요.
NotBlank.user.password = 비밀번호는 공백일 수 없습니다.
Size.user.password = 비밀번호는 {min}자 이상 {max}자 이하로 입력해야 합니다.
Positive.user.age = 나이는 양수로 입력해야 합니다.
Past.user.birthDate = 생년월일은 과거 날짜여야 합니다.
FutureOrPresent.user.eventDate = 이벤트 날짜는 오늘 이후여야 합니다.

# Global 메시지
typeMismatch.java.lang.Integer = 숫자 형식으로 입력하세요.
typeMismatch.java.util.Date = 올바른 날짜 형식으로 입력하세요.

이미지 출처
스프링 내부구조 이미지 출처 - 그림으로 배우는 스프링6

profile
문제를 해결하면서 나온 문제를 기록하는 노트

0개의 댓글