@JsonIgnore / request / @Controller / HTTP / @ResponseBody / MVC 동작원리 /CS 스터디 (항해 16일차)

김형준·2022년 5월 24일
0

TIL&WIL

목록 보기
16/45
post-thumbnail
  • 오늘은 스프링 입문 주차 과제 구현을 마무리하며, 스프링 심화 강의를 듣기 시작했다.
  • 주특기 주차가 시작되고 하루 하루 받아들여야 하는 정보량이 무척 많다..
  • 마음 같아선 하나 하나 타겟팅해서 깊이있게 공부하고 싶으나 지금은 전체적인 흐름을 읽고 숲을 파악하는 단계이기에 빠르게 1회독을 끝내고 하나 하나 정리해야겠다.😂

1. 개발 및 학습일지


1) 스프링 입문 개인 과제 (@JsonIgnore, JPA)

  • 🔗 과제 코드 GitHub
  • 과제는 게시글의 CRUD API를 RestController로 구현하는 것이다.
  • 신경써야 할 부분은 크게 2가지 였다.
    • 게시글이 생성 및 수정일자 역순으로 조회되도록 하는 것
    • 게시글 조회 시 Response에 password를 담지 않는 것
  • 날짜를 기준으로 역순으로 조회하는 것은 Repository에서 FindAllByOrderByModifiedAtDESC(); 와 같은 메서드를 작성하여 해결했다.
  • Response에 특정 컬럼을 담지 않는 것은 구글링하여 @JsonIgnore 어노테이션을 활용했다.
  • @JsonIgnore는 JSON 직렬화/역직렬화 과정에서 해당 속성을 무시한다는 뜻을 지닌다.
  • 여기에서 직렬화는 자바 객체를 JSON 객체로 변환하는 것을 의미.
  • 즉 Controller에서 spring이 @ResponseBody에 의해 객체를 JSON으로 바꿔줄 경우 @JsonIgnore가 붙은 변수는 무시한 채 직렬화하게된다.
  • 따라서 Post 클래스의 password 변수에 @JsonIgnore를 붙여주며 해결했다.
  • (@ResponseBody는 아래에서 설명)

2) request (param, query, body)

  • 클라이언트가 보낸 Request 객체는 API를 컨트롤하기 위한 메소드로 3가지를 담고 있다.

    • param: 주소에 포함된 변수를 담는다,
      localhost:8080/api/posts/{id},
      @PathVariable로 지정한 변수에 매핑된다.
    • query: 주소 바깥에서 ? 이후의 변수를 담는다
      localhost:8080/api/posts?id=1
      @RequestParam으로 지정한 변수명과 매핑 (여기에선 id)
      위 어노테이션 이름 때문에 헷갈리지 말자! 🔗헷갈린다면?
    • body: XML, JSON, Form 등의 데이터를 담는다.
      주소에서 확인할 수 없다.
      @RequestBody로 지정한 변수에 매핑된다.
  • 아래의 특징대로 적절한 상황에 적절한 방식을 사용하면 된다.

    • param: id값을 받아서, 해당 id에 관한 CRUD를 하는 경우, (resource를 식별해야하는 상황) (ex) localhost:8080/post/3
    • query : 검색, 정렬을 해야할 경우, (ex) localhost:8080/list?keyword=’검색’
    • body : 인수가 매우 길거나, 데이터가 많고 url에 노출할 수 없는 경우
  • 과제를 구현할 때에는 param과 body를 혼용하여 사용했다.

    • 생성은 body에 JSON data를
    • 특정 게시글 조회는 param에 id를
    • 수정은 param에 id와 body에 수정 내용 및 비밀번호를
    • 삭제는 param에 id와 body에 비밀번호만 담아서 보냈다.
  • Restful 여부는 내일 공부하고 검토해보기로..


3) @Controller를 쓰는 이유

  • 이유를 알기 위해 먼저 스프링이 제공하는 기능을 배제하고 servlet 방식으로 API를 구현해본다.
  • Servlet(서블릿)이란 자바를 사용하여 웹페이지를 동적으로 생성하는 서버측 프로그램 혹은 그 사양을 말한다. (위키백과)
    • 서블릿 방식 구현 과정
        1. @WebServlet 붙이고 HttpServlet extends
        1. HttpServlet의 메서드 오버라이드하여 파라미터 자리에 HttpServletRequest request, HttpServletResponse response 넣어줌
        1. 즉 request와 response 관련 처리를 모두 해줘야함....
        1. request에서 query,param,body의 정보 가져오기
        1. API 호출에 필요한 Headers, Boddy 정리 (참고로 네이버 쇼핑몰 검색 API 호출하는 과정임)
        1. HttpEntity (네이버에 보낼 request)생성
        1. ResponseEntity 정의 ( 네이버에서 받아온 값)
        1. Java객체 -> JSON / JSON -> Java 객체 과정 모두 구현
        1. API Response 정리 및 보내는 코드 작성
  • 위에 정리한대로 굉장히 처리해줄 일이 많다..
    • Controller의 장점
      • Servlet 방식과 달리 request, response 처리를 자동으로 해준다.
      • 따라서 API마다 작성해야하는 Http 코드를 생략할 수 있다 (정확히는 어노테이션에 담겨있다.)
      • Controller는 자동으로 request의 파라미터에서 값을 추출하고,
      • API 의 Response를 보내며
      • response의 헤더와 바디를 설정해준다.
  • 결론, @Controller는 수동적으로 작성해줘야 할 귀찮은 코드들을 자동으로 처리해준다. ✨ 두번 쓰세요✨

4) Http 메시지

  • 메시지 구조

5) Controller와 HTTP Response 메시지

  • 우선 Sptring Boot 프로젝트에서 main 아래 resources 영역에는 2가지 영역이 있다.

    • static: static 폴더안의 html 파일은 말 그대로 정적 파일로
      return: "redirect:/hello.html"는 static 폴더 안의 정적파일을 찾고 반환한다. 만약 POST방식이라면 .html 대신 주소가 적혀있을텐데(REST 규약에는 POST일 경우 페이지를 반환하는 기능이 가능하지만 제한한다.) 그 주소로 보내진다.
    • templates: 반면 templates안의 파일은 controller에서 Template engine에 View를 전달하는 방식인데 타임리프의 디폴트 기능으로
      return "hello"는 prefix: classpath:/templates/ + return값 + suffix: .html가 붙어서 반환된다.
      +) View와 Model을 같이 보낼수도 있다. (동적 페이지 구현 -> 과제 상세페이지 이동 구현한 것 참조)
    • 최근에는 동적페이지인 JSP 보다 http는 한번만 내려주고 비동기적으로 정보만 변경하는 SPA(Single Page App) 방식이 많이 쓰인다고 한다.
  • 핵심은 @ResponseBody의 유무와 String 타입 여부

  • @ResponseBody가 없는 경우 "View이름"만 반환 시 타임리프라는 템플릿 엔진에 의해 View에 담긴 html코드가 String으로 Response Body에 담긴다.

  • 주의해야할 사항은 dependency에 tyhme leaf와 같은 템플릿 엔진이 없다면 작동하지 않는다.

  • @ResponseBody가 없는 경우 "redirect:/{url}" Response 헤더에 Location으로 해당 url이 지정되어 리다이렉된다.

  • ResponseBody가 있는 경우 리턴타입이 String인 경우를 제외하고 모든 타입의 Java 객체가 JSON객체로 직렬화 되어 Response Body에 담기게 된다. (header의 content-Type도 application/json)

  • 즉, @ResponseBody가 붙으면 TemplateEngine에 넘겨지지 않아 View를 통과하지 않는다. (String은 그대로 text가 / 나머지 객체는 JSON화되어 json이 바디에 담김)

    ➕ @RestController = @Controller + @ResponseBody

    • 그동안 무지성으로 써왔던 @RestController는 사실 @Controller에 @ResponseBody가 붙은 것이라고 한다.
    • 즉, 그동안 편하게 자바 객체와 리스트 등을 Response Body에 넘겨줄 수 있던 이유가, 그리고 Response type이 application/json이었던 이유가 한방에 이해갔다 (항해의 빌드업인가..🕵️‍♂️)

6) Spring MVC 동작 원리

    1. Client Request -> DisPatcherServlet
    • DispatcherServlet은 가장 앞 단에서 요청을 받아 FrontCotroller라고도 불린다.
    1. DispatcherServlet -> HandlerMapping
    • HandlerMapping에는 API Path와 Controller 함수가 매칭되어 있다.
    • 그동안 @RestController에서 메서드 이름을 편하게 지정해도 됐던 이유.
    • 따라서 Path에 해당하는 Controller의 함수를 찾는다.
    1. HandlerMapping -> DispatcherServlet -> Controller
    • 핸들러 매핑에서 찾은 함수에 따라 올바른 Controller로 찾아간다.
    • Controller에서 요청하는 Request의 정보(Model) 전달
    1. Controller -> DispatcherServlet
    • Controller가 Client한테 받은 API 요청 처리 후 View와 Model 정보를 DispatcherServlet으로 전달
    1. DispatcherServlet -> ViewResolver
    • ThymeLeaf와 같은 Template Engine, 즉 View Resolver로 보내 View에 Model을 적용시킨다.
    1. DispatcherServlet -> Client
    • 처리된 View를 Client에게 Response로 전달한다.

2. CS 개념 정리 (14단원)


014) 프로세서는 무조건 빠른게 좋을까?

  • 결론부터 말하자면 아니다!

  • 상황에 따라 프로세서의 속도는 동적으로 조정되기도 하기 때문에 요구 사항을 확인해야 한다.

  • 예를 들어 스마트 폰을 사용하는 경우 프로세서가 엄청나게 빠른 대신 배터리가 1시간도 못가는 경우 vs 전력 소모를 낮추고자 빠른 실행 속도를 포기하여 적당한 속도로 배터리가 오래가는 경우에는 보통 후자를 택할 것이다.


1) 프로세서

  • 인출 -> 해석 -> 실행 -> 인출.. 사이클을 반복하여 수행한다.
    • 인출: 메모리에서 다음에 처리할 명령어를 인출한다. (순차 혹은 지정 by GOTO IFZERO 등)
    • 해석: 가져온 명령어를 해석한다.
    • 실행: 해석한 명령어를 실행한다. (일련의 작업을 명령어에 따라 적절하게 조합함으로써 이루어진다.)
  • 모형 컴퓨터에 비해 실제 컴퓨터에는 더 많은 명령어가 있으나 기본 명령어 유형은 동일하다
  • 그러나 작업이 더욱 복잡하며 방대하다.

2) 컴퓨터 아키텍처

  • 프로세서 설계와 더불어 프로세서와 컴퓨터 나머지 부분 간의 연결 방식 설계를 다루는 분야다.

  • 주요 관심사는 명령어 집합(프로세서가 제공하는 명령어 레퍼토리)
    -> 다양한 종류의 계산을 위해 많은 수의 명령어가 있는 것 vs 작성하기 쉽고 빨리 실행되도록 적은 수의 명령어가 있는 것

    이처럼 컴퓨터 아키텍처는 기능성 / 속도 / 복잡도 / 전력 소모 정도 / 프로그램 가능성 등 다양한 요소 간 상충관계(trade-off)를 수반한다.

    "일반적으로 산술 장치의 내부 자원 운영은 빠른 연산 속도에 대한 욕구와.. (중략) 기계의 단순성 또는 저비용에 대한 욕구 사이의 절충으로 결정된다." -폰 노이만

  • 프로세서는 메모리를 비롯한 컴퓨터의 나머지 부분에 비해 속도가 현격히 빠르다. (아마 뒤에 나올 내용을 위한 빌드업 같습니다.)

  • 캐시 이야기는 다음 장에 상세히 나와 제가 발표할 권리를 빼앗는 것 같아 삼가겠습니다. 🤐

  • 컴퓨터 설계자들은 프로세서가 더 빨리 작동하도록 하기 위해 여러 아키텍처 기법을 동원한다.

    • 파이프라이닝: 인출과 실행 단계가 겹치도록 프로세서를 설계하여 명령어 여러 개가 다양한 단계에 걸쳐 진행되도록하는 기법

    • 병렬적 실행: 다수의 명령어들이 서로 간섭하거나 의존하지 않을 때 진행하는 기법
    • 동시 작업: 프로세서 여러 개가 동시에 작업하도록 하는 기법, 오늘날 노트북과 휴대전화에서 표준으로 사용되는 기술
  • 요즘은 단일칩에 더 많은 프로세서 코어를 담거나, 컴퓨터마다 두 개 이상의 칩을 넣는 경향이 크다.

  • 이로 인해 개별 프로세서는 더 이상 빨라지지 않지만 더 많은 코어를 사용할 수 있어 실질적인 연산 속도는 꾸준히 증가중이다.

  • 오랜 기간 동안 프로세서는 전력과 물리적 공간이 비교적 넉넉한 데스크톱 컴퓨터에서 주로 사용되어 왔다.

  • 따라서 설계자들은 프로세서가 가능한 빨리 작동하도록 만드는 데 집중해왔다.

  • ✨하지만 노트북이 등장하며 트레이드 오프의 양상이 크게 바뀌었다.

  • 맨 처음 언급한 바와 같이 휴대 목적으로 만들어진 기기들은 전력에 제약을 훨씬 많이 받게된다.

  • 데탑, 노트북용 프로세서는 Intel과 AMD가 지배적이었으나, 휴대전화와 태블릿 PC는 대부분 ARM 이라는 프로세서 설계를 사용한다.

  • (ARM 프로세서 설계는 전력을 적게 사용하도록 특별히 설계된 방식)


3) 결론

  • 프로세서 간 속도를 비교하는 것은 어려울 뿐만 아니라 무의미하다.
  • 즉, 프로세서의 속도는 더이상 성능을 나타내는 지표가 아니다.
  • 프로세서의 속도는 주어진 요구 사항에 따라 동적으로 조정되어야 한다.
profile
BackEnd Developer

0개의 댓글