오랜만에 깊은 숙면을 했다.















섹션2가 끝나고 섹션3이 시작되는 날이다.
드디어 Spring에 대한 여러 공부들이 이루어질 것 같다.
Spring MVC에 대해 주로 공부할 것 같다
오늘도 열심히 달려보자 !


Spring MVC

Spring Web MVC를 줄요서 Spring MVC라고 부른다.
MVC는 Model, View, Controller의 약자들이고
클라이언트의 요청을 편리하게 처리해주는 프레임워크들이다.
우리가 이제부터 만들게 될 샘플 애플리케이션은
Spring MVC가 제공해주는 기능을 이용해서 만들기 때문에 중요한 시간이라고 볼 수 있다.

Model : 작업의 처리 결과 데이터
View : Model 데이터를 이용해 웹브라우저 같은 클라이언트 애플리케이션의
화면의 보여지는 리소스를 제공하는 역할

Controller : 클라이언트 측의 요청을 직접적으로 전달 받는 엔드포인트로써
Model과 View의 중간에서 상호작용을 해주는 역할

example image

아래는 이전에 공부했던 계층형 아키텍처이다.
여기서 API계층을 Spring MVC 기반의 코드로 구현해보자

example image

패키지 구조

1).기능 기반 패키지 구조
-. 하나의 기능을 완성하기 위한 계층별 클래스들을 모아놓는 구조










2). 계층 기반 패키지 구조
-. 패키지를 하나의 계층으로 보고 클래스들을 계층별로 묶어서 관리하는 구조

example image

Controller 관련 부분을 배워보자
현재 Postman을 통해 API를 요청중이다.

example image

status : 404
Not Found 에러가 리턴되었는데
클라이언트의 요청을 처리할 핸들러 메서드가 아지 없기 때문이다.
간단하게 여러 애노테이션을 알아보고 사용해보자

핸들러 메서드(Handler Method)
@RestController
-> 클래스에 추가함으로써 해당 클래스를 REST API의 리소스를
처리하기 위한 API 엔드포인트로 동작하게 해준다

@RequestMapping
-> Controller 클래스 레벨에 추가하여 클래스 전체에 사용되는 공통 Base URL을 설정할 수 있다.
-> 방식을 명시하지 않을 경우, GET,POST사용

@GetMapping
-> 조회 맵핑
-> {} 동적으로 바뀌는 값이되어짐

@PostMapping
-> 쓰기 맵핑
-> {} 동적으로 바뀌는 값이되어짐

@PathVariable
-> 클라이언트 요청 URI에 패턴 형식으로 지정된 변수값을 파라미터로 전달받는다
-> GetMapping의 괄호안에 문자열과 동일해야한다.
만약 다를경우 MissingPathVaribleException을 발생한다.

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

ResponseEntity

ResponseEntity 타입의 객체로 map과 HTTP상태를 보냄
-> Map<String,String> map = new HashMap<>(); 데이터를 담은 map
-> HTTP상태, CREATE, OK 등등…
-> Handler Method를 통해 ReponseEntity객체를 반환하면 ResponseBody로 전달됨

HttpStatus
Eunm로 구성되어져있음. HTTP 상태를 나타내는 여러 상수들이 있음 물론 더 있지만 우선 오늘 사용해본것들 위주로 예제프로그램을 작성해보자 기존에 값이 저장되어있는 Map에 데이터를 수정하는 프로그램이다.

@RestController
@RequestMapping("/v1/members")
public class MemberController {
    private final Map<Long, Map<String, Object>> members = new HashMap<>();

    @PostConstruct
    public void init() {
        Map<String, Object> member1 = new HashMap<>();
        long memberId = 1L;
        member1.put("memberId", memberId);
        member1.put("email", "dhfif718@naver.com");
        member1.put("name", "이재혁");
        member1.put("phone", "010-1111-5555");
        members.put(memberId, member1);
    }
    
    @PostMapping("/phone/{memberId}")
    public ResponseEntity changeCoffees(@PathVariable("memberId") long memberId,
                                        @RequestParam("phone") String phone) {

        //저장되어있는 객체 조회
        Map<String, Object> chagnePhoneNumber = members.get(memberId);

        System.out.println("-->Phone 번호 변경 로직 실행됨");
        System.out.println("변경전 : " + members.get(memberId));

        //해당 members 맵에 회원 id가 없을 경우 BAD_REQUSET 반환
        if (members.get(memberId) == null) {
            System.out.println("해당 memberId에 데이터가 존재하지 않습니다");
            return new ResponseEntity(HttpStatus.BAD_REQUEST);
        }

        //핸드폰 번호 변경 로직
        //얕은 복사로 같은 객체를 변경하는 것이기 때문에 members.put을 따로 해줄 필요는 없다.
        chagnePhoneNumber.put("phone", phone);

        System.out.println("변경후 : " + chagnePhoneNumber);

        return new ResponseEntity(chagnePhoneNumber, HttpStatus.OK);
    }
}

POST에 해당하는 핸들러 메서드를 만들었다.
Postman을 통해 요청을 보냈더니
ResponseEntity를 통해 객체와 상태를 리턴해주었다.


example image

API 요청시 인텔리제이의 System.out 프린트로 출력된 로그

–>Phone 번호 변경 로직 실행됨
변경전 : {phone=010-1111-5555, name=이재혁, email=dhfif718@naver.com, memberId=1}
변경후 : {phone=010-1111-6777, name=이재혁, email=dhfif718@naver.com, memberId=1}


오늘은 정리가 조금 부실하다…
실습하기 바쁘기도했고, 오늘 저녁에
백엔드 현업개발자 친구를 만나 여러가지 얘기도나누고
공부방향이 잘되고있는 건지 등
여러 잡담을 나누다보니 집에 11시에 도착해버렸다…
부랴부랴 오늘 학습한 내용을 정리하는데,, 머릿속이 텅…
비어버려서 내일학습에 지장이 생기면안될 것 같아.
우선 간단하게만 정리하고 마무리해보려한다.
주말을 이용해 인프런강의와 오늘 배운 여러지식들을 다시 공부해봐야겠다.


오늘의 커피량: ☕️ ☕️ ☕️
오늘의 점심: 오징어 덮밥, 계란 부침