반응형
- 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에 해당하는 게시물 목록을 읽어온다, 전체 게시물을 구한다
- 프로토타이핑
- path:
- 게시판 목록보기 예시
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
로 오면 이 메소드를 실행
- 디폴트 Path에 파라미터로
반응형