백엔드 측 애플리케이션은 기본적으로 클라이언트 유형과 무관하게

공통의 정보를 제공하도록 디자인이 되어야 한다.

하지만 특정 클라이언트 유형에 맞는 정보를 추가적으로 제공하기 위한 확장을 고려해야 하는 경우도 빈번하다.

 

애플리케이션을 설계할 때 기능을 다 넣어서 만들어 버리면 범위가 너무 넓어져서 구현하기 힘들다.

요구사항에 맞춰서 애플리케이션의 기능을 특정 범위까지만 제한하는 것을

애플리케이션 경계를 설정한다” 고 한다.

 

 

 

 

Spring MVC Architecture

 

 

➤ Spring MVC란?

 

스프링 모듈 중에 웹 계층*을 담당하는 몇가지 모듈이 있다.

 

Sevlet API를 기반으로 클라이언트의 요청을 처리하는 모듈도 있다.

이 모듈이 spring-webmvc 이다.

 

 

✔️ web layer(웹 계층)?

 

Spring MVC layer architecture

 

  • Spring MVC layer architecture의 최상위 계층 이다.
  • 클라이언트의 요청을 받고 응답을 전달하는 계층이다.
  • 다른 계층에서 발생한 예외를 처리한다.
  • 인증을 관리하여 권한이 없는 사용자의 인가를 거부하는 역할도 한다.

 

Spring MVC 레퍼런스

https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html

 

17. Web MVC framework

@RequestMapping(method = RequestMethod.POST) public String processSubmit(@ModelAttribute("pet") Pet pet, Model model, BindingResult result) { … } Note, that there is a Model parameter in between Pet and BindingResult. To get this working you have to reor

docs.spring.io

 

 

 

▶️ Servlet 이란?

 

클라이언트의 요청을 처리하도록 규약에 맞추어서 Java 코드로 작성하는 클래스 파일이다.

아파치 톰캣(Apache Tomcat)은 이런 서블릿들이 웹 애플리케이션으로 실행이 되도록 해주는 Servlet Container 중 하나이다.

특징

  • 클라이언트의 요청에 대해 동적으로 작동하는 웹 애플리케이션 컴포넌트
  • html을 사용하여 요청에 응답한다.
  • Java Thread를 이용하여 동작한다.
  • MVC패턴에서 Controller로 이용된다.
  • HTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속받는다.
  • HTML 변경 시 Servlet을 재컴파일해야 하는 단점이 있다.

 

 

 

 

MVC의 의미

 

 

API 계층

구현하려는 Spring MVC는 계층형 아키텍처에서 API 계층에 해당한다.

 

➤ Model(M)

 

MVC에서 M에 해당한다.

클라이언트에게서 받은 요청을 기반으로 처리한 결과인 데이터Model이라고 한다.

클라이언트에게 응답으로 Model 데이터를 돌려준다.

 

 

➤ View(V)

 

MVC에서 V에 해당한다.

Model 데이터를 이용해서 클라이언트 애플리케이션의 화면에 보여지는 리소스(Resource)를 제공한다.

 

Spring MVC에는 다양한 View기술이 포함되어 있다.

  • HTML 페이지의 출력
  • PDF, Excel 등의 문서 형태로 출력
  • XML, JSON 등 특정 형식의 format으로 변환

 

 

※ JSON(JavaScript Object Notation)이란?

 

데이터를 통신하는 포맷 형식 중의 하나이다.

웹 애플리케이션에서 가장 많이 사용한다.

Spring MVC에서 클라이언트 애플리케이션과 서버 애플리케이션이 주고 받을 때 JSON 형식을 사용한다.

과거에는 XML 형식이 가장 많이 사용되었지만 JSON이 상대적으로 가볍고 복잡하지 않아서 대세이다.

기본 포맷 : {“속성”:”값”}

 

※ 참고) JSON to Java Converter

https://json2csharp.com/code-converters/json-to-pojo

 

JSON to POJO Object Online Converter - Json2CSharp Toolkit

 

json2csharp.com

 

 

 

➤ Controller

 

MVC에서 C에 해당된다.

Controller는 클라이언트 측의 요청을 직접적으로 전달 받는 엔드포인트(Endpoint)이다.

Model과 View의 중간에서 상호 작용을 해주는 역할을 한다.

Model 데이터를 View로 전달하는 역할을 한다.

 

 

➤ Model, View, Controller 간의 처리 흐름

 

Client가 요청 데이터 전송

➡️ Controller가 요청 데이터 수신 ➡️ 비즈니스 로직 처리 ➡️ Model 데이터 생성

➡️ Controller에게 Model 데이터 전달 ➡️ Controller가 View에게 Model 데이터 전달

➡️ View가 응답 데이터 생성

 

 

 

※ Gson 클래스 찾을 수 없는 오류

 

Gradle 방식

스프링 프로젝트 내에 build.gradle로 들어가서

“dependencies” 에  implementation 'com.google.code.gson:gson:2.9.0' 추가 ➡️ gradle reload

 

Maven방식

<dependency>

	<groupId>com.google.code.gson</groupId>

 	<artifactId>gson</artifactId>

 	<version>2.9.0</version>

</dependency>

 

사용하려는 위치에서 import com.google.gson.Gson;

 

 

 

 

Spring MVC 동작 방식과 구성 요소

 

 

Spring MVC 동작방식

 

※ DispatcherServlet의 역할

많은 일을 처리하는 것 같지만 실제로는 요청에 대한 처리는 다른 구성 요소들에게 위임(Delegate)하고 있다.

 

애플리케이션의 가장 앞단에 배치되어 다른 구성 요소들과 상호작용 하면서 클라이언트의 요청을 처리하는 패턴을 ‘Front Controller Pattern’이라고 한다.

 

※ Handler메서드

@GetMapping

@PutMapping

@DeleteMapping

@PatchMapping

@PostMapping

 

 

 

Controller

 

 

➤ 패키지 구조 생성

 

Spring Boot 기반의 애플리케이션에서 주로 사용되는 자바 패키지 구조에는

기능 기반 패키지 구조(package-by-feature)계층 기반 패키지 구조(package-by-layer)가 있다.

 

 

▶️ 기능 기반 패키지 구조(package-by-feature)

 

애플리케이션의 패키지를 구현해야 하는 기능을 기준으로 패키지를 구성하는 것이다.

패키지 안에는 하나의 기능을 완성하기 위한 계층별(API 계층, Service 계층, DataAccess 계층) 클래스들이 모여있다.

상대적으로 테스트와 refactoring이 용이하여 많이 사용한다.

 

 

▶️ 계층 기반 패키지 구조(package-by-layer)

 

패키지를 하나의 계층으로 보고 클래스들을 계층별로 묶는 구조이다.

ex) controller, dto, model, repository, service,...

 

 

 

➤ 실습 예제

 

예제를 따라하면서 정리해보았다.

Mock 데이터를 응답으로 넘기는 형태로 작성하였다.

프론트에 요청과 응답이 정상적으로 통신되는지만 확인하기 위해

실제 안에서 동작하는 로직은 구현하지 않았다.

 

실습 내용 : 커피 주문 애플리케이션 Controller 설계하기

 

▶️ 기능 요구 사항

커피 주문 앱에 넣을 수 있는 기능을 모두 넣으면 구현하기 어렵고 복잡해진다.

따라서 동작에 필요한  기능을 넣어서 먼저 애플리케이션 경계를 설정해야 한다.

  • 주인이 커피 정보를 관리하는 기능
    • 커피 정보 등록 기능
    • 등록한 커피 정보 수정 기능
    • 등록한 커피 정보 삭제 기능
    • 등록한 커피 정보 조회 기능
  • 고객이 커피 정보를 조회하는 기능
    • 커피 정보 조회 기능
  • 고객이 커피를 주문하는 기능
    • 커피 주문 등록 기능
    • 커피 주문 취소 기능
    • 커피 주문 조회 기능
  • 고객이 주문한 커피를 주인이 조회하는 기능
    • 커피 주문 조회 기능
    • 고객에게 전달 완료한 커피에 대한 주문 완료 처리 기능

 

커피 주문 애플리케이션에 필요한 리소스: Member, Coffee, Order

리소스에 해당하는 Controller 클래스를 작성

 

▶️ 엔트리포인트(Entrypoint) 클래스

Spring Boot 기반의 애플리케이션이 정상적으로 실행되려면 main() 메서드가 포함된

애플리케이션의 엔트리포인트를 작성해야 한다.

 

(Spring Initializr을 통해 생성한 프로젝트는 엔트리포인트 클래스가 이미 작성되어 있다.)

 

 

▶️ @SpringBootApplication

  • String Boot의 자동 구성을 활성화한다. (@EnableAutoConfiguration)
  • 애플리케이션 패키지 내에서 @Component 가 붙은 클래스를 검색한 후(scan), Spring Bean으로 등록하는 기능을 활성화 (@ComponentScan)
  • @Configuration 이 붙은 클래스를 자동으로 찾아서 Spring Bean을 등록하는 기능을 활성화 (@SpringBootConfiguration)

 

 

▶️ SpringApplication.run(~.class, arrgs);

  • Spring 애플리케이션을 부트스트랩하고 실행하는 역할

 

 

➤ Controller 만들기

 

▶️ @RestController

  • 클래스에 추가하면 해당 클래스가 REST API의 리소스를 처리하기 위한 API 엔드포인트로 동작함을 의미한다.
  • @RestController가 추가된 클래스는 애플리케이션 로딩 시, Spring Bean으로 등록된다.

 

▶️ @RequestMapping

  • 클라이언트 요청과 클라이언트 요청을 처리하는 Handler Method를 매핑해주는 역할을 한다.
  • 클래스 레벨에 추가하여 클래스 전체에 사용되는 공통 URL(Base URL)을 설정해준다.
  • Attribute
    • value : URL을 넣어준다.
    • produces : 응답 데이터를 어떤 미디어 타입으로 전송할지 설정한다.

 

 

※ 추가학습) URI 작성 기본 규칙

  • 마지막이 ‘/‘로 끝나지 않아야 한다.
  • 동사보다는 명사를 사용한다.
  • 단수형 보다는 복수형 명사를 사용한다.
  • 기본 소문자를 사용한다.
  • 언더스코어(_) 대신에 하이폰(-)을 사용한다.
  • 파일 확장자는 URI에 포함하지 않는다.

 

 

➤ Handler Method 작성하기

 

▶️ @PathVariable

괄호 안에 입력한 문자열 값은 밑의 @~Mapping 의 attribute의 중괄호 안의 문자열과 동일해야 한다.

다르면 “MissingPathVariableException” 발생

 

 

▶️ @PostMapping

클라이언트가 HTTP 메서드 POST를 이용해서 보낸 request body를 서버에 생성할 때 사용, 메서드 위에 작성

  • 원하는 HTTP 메서드에 맞추어서 GetMapping, DeleteMapping, PatchMapping 등 다양하게 지원된다. 반드시 요청하는 HTTP Method 타입과 동일하게 맞춰주어야 정상적으로 매핑된다.
  • 괄호() 안에 몇 가지 Attribute를 넣어줄 수 있다.
  • attribute에 HTTP URI의 일부를 지정해 줄 수 있다.

 

 

▶️ @RequestParam

클라이언트 쪽에서 전송하는 요청 데이터를 쿼리 파라미터(Query Parameter 또는 Query String), 폼 데이터(form-data), x-www-form-urlencoded 형식으로 전송하면 이를 서버 쪽에서 전달 받을 때 사용하는 애너테이션

  • 쿼리 파라미터 : 요청 URL에서 물음표(?)를 기준으로 붙는 key/value 쌍의 데이터를 말한다.
  • 괄호()안에 전달받을 key값 작성
  • 애너테이션이 붙는 변수는 전달받은 value

 

 

 

➤ ResponseEntity

 

클라이언트의 응답으로 전송하는 JSON 형식의 문자열을 직접 타이핑해서 작성하면 문제가 생기기 쉽고  수정이 번거롭다.

ResponseEntity 객체로 리턴값을 변경하면 JSON을 수작업으로 작성할 필요가 없다.

ResponseEntity를 사용하면 JSON 형식에 타이핑할 필요없이 응답 정보를 map에 담아서 보내면 된다.

ResponseEntity 객체를 생성하면서 생성자 매개변수로 응답 데이터(map)와 HTTP 응답 상태를 함께 전달한다.

리턴 값으로 Map 객체 그대로 리턴해도 클라이언트에서 JSON 형식으로 정상적으로 응답 데이터를 받을 수 있지만 ResponseEntity 객체로 응답 데이터 래핑함으로써 더 세련된 방식으로 응답 데이터를 생성할 수 있다.

 

  • HttpEntity의 확장 클래스이다.
  • ResponseEntity에 Custom header를 포함하려면 HttpHeaders에 원하는 헤더를 추가하고 ResponseEntity의 생성자 매개변수로 객체를 전달하면 된다.
  • BodyBuilder 클래스를 이용하면 각각의 항목들(body, header, HttpStatus)을 메서드 체인 방식으로 전달할 수 있다.

 

HTTP 상태 코드

https://developer.mozilla.org/ko/docs/Web/HTTP/Status

 

HTTP 상태 코드 - HTTP | MDN

HTTP 응답 상태 코드는 특정 HTTP 요청이 성공적으로 완료되었는지 알려줍니다. 응답은 5개의 그룹으로 나누어집니다: 정보를 제공하는 응답, 성공적인 응답, 리다이렉트, 클라이언트 에러, 그리고

developer.mozilla.org

 

 

 

 

 

프로젝트 코드 깃허브 링크

https://github.com/WiseJade/SpringBoot-practice/tree/main/section2-week3

 

 

 

 

읽어주셔서 감사합니다. 스프링 공부 어려운 데 화이팅하세요!

오개념에 대한 지적은 환영입니다.