본문 바로가기
Spring

스프링부트로 쇼핑몰 만들기 - 2주차

by 향로 (기억보단 기록을) 2019. 1. 15.
반응형
  • HTTP 프로토콜 구조
  • 스프링에 대한 웹 프로그래밍 기본 학습
  • 웹 어플리리케이션 구조

2-1. HTTP 요청과 WAS

  • 브라우저에서 요청 정보가 오면 WAS가 이 요청정보를 모아 HttpServletRequest를 만든다.
  • WAS는 이 요청 정보에서 Context Path를 추출해서 특정 웹 어플리케이션을 찾는다
    • 웹 어플리케이션 안에는 다양한 Resource (정적) 와 Servlet 등이 존재
    • Context Path뒤에 있는 Path를 통해 어떤 Resource 혹은 Servlet이 필요한지를 찾는다
    • 즉, Path를 통해 찾으려면 Resource 혹은 Servlet들은 고유의 Path를 가져야 한다.
    • WAS에는 Default Servlet이 정적 Resource 서빙을 담당

Servlet (서블릿)

  • HttpServlet: 추상 클래스
    • init(), service(req, res), destory(), doGet(req, res), doPost(req, res) 등등 가지고 있음
    • Servlet을 만든다고 하면 이 추상 클래스르 상속해서 만듬
    • URL Path는 어노테이션(@WebServlet) 혹은 web.xml로 지정
    • URL 요청이 오면 메모리에 Servlet 인스턴스가 있는지 먼저 확인
    • 없으면 init을 통해 생성한다

위와 관련 내용은 예전에 정리했으니 한번 참고해보세요 :)

2-2. Thymeleaf + Spring Boot

  • IntelliJ에 Lombok 적용
  • Controller 코드 소개
    • @GetMapping 내부 코드로 설명
    • @RequestMapping 은 Controller/Method 어디서든 사용할 수 있음
    • @PathVariable 은 Path의 Resource를 변수로 호출 가능
      • 수업시간에는 설명 안했지만, name=은 변수와 Resource가 같으면 별도로 지정할 필요 없음
  • 템플릿 엔진
    • Freemarker, Thymeleaf, JSP 등등 서버 사이드 HTML 생성
  • URL 설계 해보자
    • 게시판 목록보기 예시
      • path: /board/{gameId}/{boardId}
      • 파라미터: sort = PID 혹은 name등
      • 로직: p에 해당하는 게시물 목록을 읽어온다, 전체 게시물을 구한다
      • 프로토타이핑

2-3. Spring MVC 기본 동작 흐름

  • 사용자의 모든 요청을 처리해주는 무언갈 만들자라고 Spring에서 고민
    • 그 무언가가 바로 Dispatcher Servlet
    • 원래 /을 처리하는 친구는 Default Servlet
      • 즉, 모든 경로를 처리
  • Dispatcher Servlet은 모든 호출을 받아 적절한 Servlet에 전달한다

2-4. 주요 클래스

WebMvc

  • Spring Boot2 혹은 Spring 5에서 WebMvcConfigurerAdapter가 Deprecate됨
    • Spring5, Spring Boot2가 JDK8 이상에서만 동작
    • Java8에서는 Default Method가 추가됨
    • WebMvcConfigurer가 인터페이스라 수십개의 메소드를 구현체에서 모두 오버라이딩 할 수 없으니 어댑터로 WebMvcConfigurerAdapter 추상클래스를 만들게됨
    • 하지만 Java8에서는 디폴트 메소드가 지원되니 굳이 어댑터가 필요하지 않게 됨

DispatcherServlet

  • Front Controller라고도 불림

  • Thread Local

    • 일반적으론 요청~응답까지는 1개의 쓰레드가 처리
    • 그 개별의 쓰레드에서만 사용할 수 있는 값들을 저장할 수 있는 공간을 가리킴
  • DispatcherServlet 내부 동작 흐름 상세 - 요청 선처리

    • 요청
    • locale 결정
    • RequestContextHolder 요청 저장
    • FlashMap 복원
    • Forward vs Redirect
    • Forward : 요청 정보를 가진채로 다른 곳으로 전달
    • Redirect : 완전히 새로운 페이지로 이동
    • 그럼 Redirect를 해도 값을 쓰고 싶으면 어쩌나? => FlashMap
    • 멀티파트 요청
    • Yes: MultipartResolver가 멀티파트 결정 => 핸들러 결정과 실행
    • No: 핸들러 결정과 실행
  • DispatcherServlet 내부 동작 흐름 상세 - 요청 전달

    • HandlerMapping으로 HandlerExecutionChain 결정
    • HandlerExecutionChain 발견
      • 요청 순서
      • 서블릿 필터
      • DispatcherServlet
      • Spring MVC Interceptor
        • Spring 기술이라 Bean으로 등록됨
      • Spring MVC Controller
      • Interceptor들의 순서를 얘기하는게 HandlerExecutionChain

2-4. 실습

  • IDE의 getter/setter 생성의 단점
    • 필드 하나가 삭제시 관련 메소드를 직접 찾아 지워야함
    • 번거로움
    • Lombok을 써야할 이유!
  • 생성자만으로 인스턴스 생성의 단점
    • 문자열 3개가 생성자 파라미터로 있을 경우 어느게 어느 필드에 꽂힐지는 생성자 코드를 봐야만 알수 있음
    • 생성자의 인자 순서가 변경되어도 문제가 발생할 수 있음
    • 직관성이 떨어지니 이런 문제를 해결하기 위해 Lombok의 @Builder를 사용
  • Thymeleaf에서 날짜 타입 원하는 포맷으로 노출하기
    • thymeleaf-extras-java8time 의존성 추가
코드)
${#temporals.format(값, '포맷')}

예시)
<td th:text="${#temporals.format(board.createDate, 'yyyy-MM-dd HH:mm')}"></td>
  • Thymeleaf에서 자바에서 받은 값들 JS에서 사용하기
    <script th:inline="javascript">
        /*<![CDATA[*/
        var testStr = /*[[${test}]]*/ '-- test --';
        /*]]>*/
        alert(testStr);
    </script>
  • Thymeleaf 조건문/반복문
    • #lists 는 Thymeleaf의 예약어
    • else는 없음
    <div th:if="${#lists.size(list) < 4}">
        list.size() < 4<br>
    </div>

    <div th:switch="${count}">
        <p th:case="50">count is 100!</p>
        <p th:case="100">count is 100!</p>
        <p th:case="150">count is 100!</p>
    </div>

2-5. 추가 팁

  • @GetMapping(params = "format=csv")?
    • 디폴트 Path에 파라미터로 ?format=csv로 오면 이 메소드를 실행
반응형