@Slf4j
- 인터페이스이며, 그 구현체로 Logback 같은 라이브러리를 선택
- 실제 개발에서는 Spring boot가 기본적으로 제공하는 Logback을 사용
- Logging
- 쓰레드 정보, 클래스 이름과 같은 부가적인 정보를 함께 확인 가능
- 실제론 별도의 로깅 라이브러리를 통해 Console에 로그를 출력한다.
- Log Level 설정을 통해 원하는 메시지를 출력하며, 로그 메시지를 일자별로 모아 외부 저장소에 저장하기도 한다.
- Log Level
- TRACE > DEBUG > INFO > WARN > ERROR
- 예시 코드
package com.example.springbasicannotation.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; @Slf4j @RestController public class Slf4jController { // log를 사용할 때에는 {}, value 로 사용할 것. // 왜냐하면 +로 사용할 때에는 문자 연산을 무조건 해버리기 때문이다. @RequestMapping("/logging") public String logging() { String sparta = "Sparta"; // TRACE -> DEBUG -> INFO -> WARN -> ERROR log.trace("문자 trace={}", sparta); log.debug("문자 debug={}", sparta); // default log.info("문자 info={}", sparta);// 문자 연산을 진행하지 않는다. log.warn("문자 warn={}", sparta); log.error("문자 error={}", sparta); log.info("문자 info " + sparta); // 문자 연산을 먼저 해버린다. return "success"; } }
- 여기서 info, warn, error만 나오는데 그 이유는 default가 info로 설정돼있기 때문이며, default를 trace로 바꾸면 전부 다 출력
@Controller
- ★ View가 있는 경우에만 사용
- 즉 Template Engine인 Thymeleaf나 JSP를 사용하는 경우
- Thymeleaf 예시
- 의존성 추가 :
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'main/resources/templates가 기본 경로로 설정된다.- 즉 build.gradle에 의존성을 추가하면 Spring boot가 알아서 설정해줌
@RestController
- ★ 응답할 데이터가 있는 경우에만 사용된다.
- 현재는 대부분 @RestController를 사용하여 API가 만들어짐 (Restful API)
- 반환 값으로 View를 찾는게 아니라 HTTP Message Body에 Data를 입력
- 동작 순서
@Component
- Spring Bean에 등록하는 역할을 수행한다.
- Spring Bean은 애플리케이션의 구성요소를 정의하는 객체이다.
- Servlet을 Servlet 컨테이너에 등록하는 것과 같은 역할을 함
@Indexed: Spring Bean에 더 빠르게 등록되도록 도와주는 어노테이션
@Target
- @Target이 선언된 하위 어노테이션이 어떤 범위에 적용될지 설정
- ElementType Enum 속성
ex) @Target(ElementType.ANNOTATION_TYPE)- 각각의 Enum마다 적용되는 범위가 주석에 설명돼있음
@Retention
- 하위 어노테이션이 얼마나 오래 유지되는지를 결정
- RetentionPolicty Enum 속성
ex) @Retention(RetentionPolicity.RUNTIME)- SOURCE
- 소스 코드 (.java)에서만 유지된다.
- 컴파일 과정에서 어노테이션 정보가 사라짐
- CLASS
- 컴파일된 클래스 파일(.class)에 저장되지만, JVM이 실행시 읽지 않는다. (주석과 같음)
- Default 값이다.
- RUNTIME
- 클래스 파일에 저장되고, JVM에 의해 런타임 시점에 읽을 수 있다.
- 즉, 실제 런타임 시점의 코드에 반영되어 영향을 준다.
@Documented
- Javadoc 등의 문서화 도구에 의해 문서화돼야 함을 나타낸다.
다시 보는 @Controller
@Target
- Class, Interface, Enum, Annotation, Record Declaration에 적용할 수 있다.
@Retention
- 클래스 파일에 저장되고, JVM에 의해 런타임 시점에 읽을 수 있다.
@Documented
- Javadoc등의 문서화 도구에 의해 문서화가 돼야 함
@Component
- Spring Bean에 등록하며, 싱글톤으로 관리된다.
다시 보는 @RestController
- @Controller에 @ResponseBody가 결합된 어노테이션
- @Controller와 다르게 메서드마다 @ResponseBody를 추가하지 않아도 됨
@ResponseBody
- @ResponseBody는 Target({ElementType.TYPE, ElementType.METHOD}) 이지만, @RestController는 Target(ElementType.TYPE)으로 제한하였다.
- 즉 @RestController는 ElementType.TYPE 만 사용 가능하다.
@RequestMapping
- 특정 URL로 요청을 보내면, 들어온 요청을 Controller 내부의 특정 메서드와 Mapping 하기 위해 사용된다.
- 단순히 URL로 Mapping 하는 것이 아닌 여러가지 요소(URL, 메서드등)를 조합하여 Mapping 한다
- URL path
/example만 Mapping한다. (/example/이런 식은 안됨)- 속성값들을 설정할 때 배열 형태로 다중 설정이 가능하다.
ex) RequestMapping({/example1, /example2, ...})
- HTTP Method 모두 허용한다. (GET, POST, PUT, PATCH, DELETE 등)
- 메서드 속성으로 HTTP Method를 지정하면 지정된 것만 허용한다.
- ex) POST를 지정하면 POST만 허용함 (나머지 허용 X)
- Restful API의 계층 구조
ex) users/{userId}, category/{categoryId}/product/{productId}- prefix로 선언할 URL을 클래스 레벨에 적용할 때 주로 사용
@GetMapping
@Target(ElementType.METHOD)메서드 레벨에 해당 어노테이션을 적용한다.- 내부적으로
@RequestMapping(..., method = RequestMethod.GET)을 사용하고 있다.@PostMapping,@DeleteMapping,@PutMapping,@PatchMapping등 모두 다 가능하다.
❓ 그러면 이렇게 편리한 Mapping 들이 있으니 RequestMapping은 사용하지 않아도 되는거 아니야 ⁉
- 위 Mapping 들의 Target은 메소드 레벨만이다.
- 반면 RequestMapping의 Target은 클래스와 메소드 레벨에 적용이 가능하다.
- 즉, 클래스 레벨을 사용해야 될 때 RequestMapping을 사용한다 !!
@PathVariable
- 비연결성(Connectionless)을 극복하여 데이터를 전달하기 위한 방법
- URL로 전달된 값을 파라미터로 받아오는 역할을 수행
- 중괄호에 둘러싸인 값이 경로변수를 뜻한다.
ex) users/{id}
@PathVariable로 설정된 경로변수는 반드시 값을 가지고 있어야 하며, 값이 없으면 응답 코드인 404 Not Found Error 발생
- 최근엔 Restful API를 설계하는 것이 기준이 되며, 해당 어노테이션의 사용 빈도가 많아짐
- @PostVariable 규칙
- 파라미터 변수명과 PathVariable 변수명이 같다면 생략이 가능
- 생략 X
GetMapping("/{postId}")// value 생략
public String pathVariableV1(@PathVariable("postId") Long data) {}- 생략 O
GetMapping("/{postId}")// value 생략
public String pathVariableV1(@PathVariable Long postId) {}
- @PathVariable 다중 사용 가능
GetMapping("/{postId}/comments/{commentsId})
public String PathVariableV3(@PathVariable Long postId, @PathVariable Long commentsId) {}
- Parameter 추가 매핑
ex) @GetMapping(value = "/users", params = "gender=man")- 실제 URL GET
localhost:8080/users?gender=man파라미터가 있어야 호출된다.
- 파라미터가 없으면 응답 코드 400 Bad Request Error 발생
- 특정 Header 매핑
ex) @PostMapping(value = "/users", headers = "Content-Type=application/json")
- MediaType 매핑, consumes(수용)
ex) @PostMapping(value = "/users", consumes = "Content-Type=application/json)- HTTP Header Content-Type(요청)과 매핑된다
- consumes 속성 값으로는 이미 Spring에서 제공하는 Enum인
MediaType.APPLICATION_JSON_VALUE형태로 사용한다.
- MediaType 매핑 produces(제공)
- 요청 헤더의 Accepts 하는 값에 따라 produces 하는 값이 변한다.
- HTTP 요청 Accept Header에 MediaType이 있어야 한다.
- consumes 속성 사용법과 같다.
- 다양한 Enum 형태