📚 강의 출처
강사님께 항상 감사합니다. 🧑🏻💻
해당 글은 김영한님의 강의와 개인적 지식을 바탕으로 정리한 내용입니다.
모든 자료의 출처는 김영한 강사님임을 미리 밝힙니다.
섹션 5. 스프링 MVC - 구조 이해
- 동작 순서
- 핸들러 조회 : 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러) 조회
- 어댑터 조회 : 핸들러를 실행할 수 있는 핸들러 어댑터 조회
- 어댑터 실행 : 핸들러 어댑터를 실행
- 핸들러 실행 : 실제 핸들러를 실행
- ModelAndView 반환 : 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해 반환
- viewResolver 호출 : 뷰 리졸버를 찾고 실행
- View 반환 : 뷰의 논리 이름을 물리 이름 변경, 렌더링 역할을 담당하는 뷰 객체를 반환
- 뷰 렌더링 : 뷰를 렌더링 진행
- Spring MVC
- FrontController가 실제 구조는 DispatcherServlet
- DispatcherServlet은 Spring MVC 핵심
- DispatcherServlet을 서블릿으로 자동 등록, 모든 경로에 대해서 매핑
- Controller 인터페이스는 @Controller 애노테이션과는 전혀 다른 존재
- @RequestMapping
- 가장 우선순위가 높은 핸들러 매핑과 어댑터 RequestMappingHandlerMapping, RequestMappingHandlerAdapter
- 실무에서 99.9% 이 방식 컨트롤러 사용
- 클래스 레벨에 적용 시 메서드에 정의한 레벨과 조합
@RequestMapping("/springmvc/v2/members")
public class SpringMemberControllerV2 {}
- @Controller
- 자동으로 Spring Bean 등록
- Spring MVC에서 애노테이션 기반 컨트롤러로 인식
- ModelAndView : 모델과 뷰 정보를 담아서 반환
- Model 파라미터 : ViewName 직접 반환
- @RequestParam 사용해 요청 파라미터를 습득
- @RequestMapping -> @GetMapping, @PostMapping
- 더욱 편리하게 요청을 분류
🧑🏻💻 강의 실습 기록
섹션 6. 스프링 MVC - 기본 기능
- 로깅 라이브러리
- SLF4J 인터페이스, 구현체로 다양한 라이브러리가 존재하는데 실무에선 Logback을 대부분 사용
- Logback
private Logger log = LoggerFactory.getLogger(getClass());
private static final Logger log = LoggerFactory.getLogger(Xxx.class);
@Slf4j 롬북 사용 가능
- @RestController 애노테이션
@Controller 애노테이션은 String 반환 값이 뷰 이름으로 인식한다. 하지만, @RestController 애노테이션은 반환 값으로 HTTP Body에 바로 입력한다. (REST API)
- TRACE > DEBUG > INFO > WARN > ERROR (로그 레벨)
- Log 사용 주의
log.debug("data="+data)
log.debug("data={}", data)
2가지 차이는 문자의 더하기 연산이 실행되냐, 안되냐 차이다. 두 번째 방법의 로그 출력이 성능상으로도 효율적이다.
- 다중 URL 호출
@RequestMapping({"/hello-basic", "/hello-go"})
- HTTP 메서드 매핑
@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
@GetMapping(value = "/mapping-get-v1")
- 축약한 애노테이션을 사용하는 것이 더욱 직관적
- 다양한 방식
- @PathVariable 사용 or 다중 사용
- 특정 파라미터 조건 매핑
- 특정 헤더 조건 매핑
- 미디어 타입 조건 매핑 - HTTP 요청 Content-Type, consume
- 미디어 타입 조건 매핑 - HTTP 요청 Accept, produce
- 회원 관리 API 예시
- 전체 조회 : GET - '/users'
- 등록 : POST - '/users'
- 조회 : GET - '/users/{userId}'
- 수정 : PATCH - '/users/{userId}'
- 삭제 : DELETE - '/users/{userId}'
- HTTP 헤더 정보 조회
- HttpServletRequest
- HttpServletResponse
- HttpMethod : HTTP 메서드 조회
- Locale : 지역 정보 조회
- @RequestHeader MultiValueMap<String, String> headerMap : 모든 헤더 MultiValueMap 형식으로 조회
- @RequestHeader("host") String host : 특정 헤더 조회
- @CookieValue(value = "myCookie", required = false) String cookie : 특정 쿠키 조회
- MultiValueMap : 하나 키의 여러 값
- [클라이언트 -> 서버] 요청 데이터 전달 3가지 방법
- GET - 쿼리 파라미터
- POST - HTML Form
- HTTP message body
- 파라미터 인식 권장 방법
@RequestParam("username") String username
@PathVariable("userId") String userId
애노테이션에 이름을 생략하지 않고, 항상 적는다. (권장)
- 파라미터 필수 여부, 기본 값
public String requestParamDefault(
@RequestParam(required = true, defaultValue = "guest") String username,
@RequestParam(required = false, defaultValue = "-1") int age)
- 필수 여부 - required 기본 값 true
- 기본 값 - defalutValue 빈칸 시 기본 값 적용 가능
- 파라미터 Map 선언 가능
public String requestParamMap(@RequestParam Map<String, Object> paramMap)
- @ModelAttribute
public String modelAttributeV1(@ModelAttribute HelloData helloData)
- HelloData 객체 생성 후, 요청 파라미터 값을 모두 삽입
- 요청 파라미터 조회 기능 : @RequestParam, @ModelAttribute
- HTTP 메시지 바디 조회 기능 : @RequestBody
- @RequestBody
public String requestBodyJsonV3(@RequestBody HelloData data)
@ModelAttribute 애노테이션과 동일하게 전달 받은 파라미터가 아닌, 메시지를 객체에 바로 삽입할 수 있다.
하지만, 얘는 생략이 불가능하다. 생략 시 @ModelAttribute로 인식하기 때문이다.
- 메시지 컨버터
- HTTP 요청: @RequestBody , HttpEntity(RequestEntity)
- HTTP 응답: @ResponseBody , HttpEntity(ResponseEntity)
- canRead(), canWrite() : 지원하는 타입인지 체크
- read(), write() : 메시지를 읽고 쓰기 등
- ArgumentResolver
컨트롤러가 필요로 하는 다양한 파라미터의 값(객체)을 생성한다. 그리고 이렇게 변환된 값은 준비가 되면 컨트롤러를 호출하면서 값을 전달한다. 현재 코드에서 사양하는 다양한 애노테이션으로 원하는 값을 받을 수 있는 이유는 ArgumentResolver 이다. 또한, 원하는 변환 값이 필요하면 직접 인터페이스를 확장해서 원하는 클래스를 정의해서 사용할 수 있다.
🧑🏻💻 강의 실습 기록
섹션 7. 스프링 MVC - 웹 페이지 만들기
- 부트스트랩(Bootstrap)은 웹사이트를 쉽게 만들 수 있게 도와주는 HTML, CSS, JS 프레임워크
- @RequiredArgsConstructor : final이 붙은 멤버변수만 사용해 생성자를 자동으로 구현
- @PostConstruct : 빈의 의존관계가 모두 주입되고 나면 초기화 용도로 호출
- 타임리프 사용 선언 : <html xmlns:th="http://www.thymleaf.org">
- 속성 변경 : th:href="@{/css/bootstrap.min.css}"
- URL 링크 표현식1 : @{...} ex) th:href="@{/css/bootstrap.min.css}"
- URL 링크 표현식2 : th:href="@{/basic/items/{itemId}(itemId=${item.id})}"
- 리터럴 대체 : |...|
<span th:text="'Welcome to our application, ' + ${user.name} + '!'">
<span th:text="|Welcome to our application, ${user.name}!|">
- 반복 출력 : <tr th:each="item : ${items}">
- 변수 표현식 : <td th:text="${item.price}">10000</td>
- 내용 변경 : <td th:text="${item.price}">10000</td>
- 속성 변경 : th:value="${item.id}"
- 속성 변경 : th:action (주소가 따로 없으면, 현재 URL에 데이터 전송)
타임리프는 순수 HTML을 그대로 유지하면서 뷰 템플릿도 사용할 수 있는 타임리프의 특징을 살린 네츄럴 템플릿이다.
- @ModelAttribute : 요청 파라미터 처리
객체를 생성하고, 요청 파라미터의 값을 프로퍼티 접근법으로 입력한다. 한가지더 중요한 기능이 존재한다. Model에 @ModelAttribute로 지정한 객체를 자동으로 넣어준다.
@ModelAttribute("hello") Item item
@ModelAttribute Item item // 추가 생략 가능
- 리다이렉트
@PostMapping("/{itemId}/edit")
public String edit(@PathVariable Long itemId, @ModelAttribute Item item) {
itemRepository.update(itemId, item);
return "redirect:/basic/items/{itemId}";
}
- PRG Post/Redirect/Get : 상품이 계속해서 중복 등록되는 것을 방지
- RedirectAttributes
@PostMapping("/add")
public String addItemV6(Item item, RedirectAttributes redirectAttributes) {
Item savedItem = itemRepository.save(item);
redirectAttributes.addAttribute("itemId", savedItem.getId());
redirectAttributes.addAttribute("status", true);
return "redirect:/basic/items/{itemId}";
}
// 뷰 템플릿
<h2 th:if="${param.status}" th:text="'저장 완료!'"></h2>
위와 같이 상태를 'true' 참으로 해두고 템플릿으로 전달해, 템플릿에서 해당 값을 바탕으로 메시지 및 다양하게 활용할 수 있다.
🧑🏻💻 강의 실습 기록
'✍️ 정리 > Spring' 카테고리의 다른 글
[Inflearn] 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 정리 (B) (0) | 2024.08.06 |
---|---|
[Inflearn] 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 정리 (A) (0) | 2024.07.31 |
[Inflearn] 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 정리 (A) (0) | 2024.07.18 |
[Inflearn] 모든 개발자를 위한 HTTP 웹 기본 지식 정리 (2) | 2024.07.03 |
[Inflearn] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 정리 (0) | 2024.06.28 |
Backend 개발자를 꿈꾸는 꿈나무💭 기술 블로그
꾸준함을 목표로 하는 꿈나무 개발자 택이✌️입니다. 궁금하신 점이나 잘못된 정보가 있으면 언제든지 연락주세요. 📩 함께 프로젝트 및 스터디도 언제든지 희망합니다! 📖