[Spring] 기초 4주차
✏️ Spring Annotation
@Slf4j
Lombok 라이브러리에서 제공하는 어노테이션으로 로깅 기능을 쉽게 사용할 수 있도록 로그 객체를 자동으로 생성해준다.
SLF4J에서 지원하는 로그 레벨:
- log.trace: 가장 상세한 로그. 주로 개발 중 디버깅 용도로 사용.
- log.debug: 디버깅 정보.
- log.info: 일반 정보성 메시지.
- log.warn: 경고성 메시지.
- log.error: 오류 발생 시 메시지.
@Controller
View(thymeleaf, jsp)가 있는 경우 사용한다. 메소드에서 반환된 문자열은 해당 문자열의 뷰 파일로 이동된다. 데이터를 뷰에 전달하려면 Model 객체를 사용해서 전달한다. REST API 개발에는 잘 사용되지 않는다.
@Controller
public class HomeController {
@GetMapping("/home")
public String home(Model model) {
model.addAttribute("message", "Welcome to Spring MVC!");
return "home"; // 뷰 이름 (home.html)
}
}
@RestController
REST API 개발을 위해 사용된다. Controller 어노테이션과 다르게 뷰를 반환하지 않고 응답할 데이터가 있는 경우 사용한다. 문자열, 객체, 리스트 등을 반환하면 json 또는 xml로 직렬화된다. Controller+ResponseBody 어노테이션 역할.
@RestController
public class ApiController {
@GetMapping("/api/message")
public String getMessage() {
return "Hello, World!";
}
@GetMapping("/api/user")
public User getUser() {
return new User("John", 30);
}
}
❓ Controller에서 ResponseBody를 붙여서 사용하는 것과 RestController는 같은 동작을 하는가?
👉🏻 차이점
특성 | @Controller에서 @ResponseBody 쓰기 | @RestController |
역할 | 메서드 단위로 HTTP 응답 본문을 반환 | 클래스 전체에 HTTP 응답 본문 적용 |
작성 간편함 | 메서드마다 @ResponseBody를 붙여야 함 | 클래스 레벨에만 어노테이션 추가 |
뷰 렌더링 가능 여부 | 가능 (다른 메서드에서 뷰 이름 반환 가능) | 불가능 (뷰 이름 반환 불가) |
@Component
해당 클래스를 Spring Bean으로 등록할 때 사용한다.
❓ Bean등록?
👉🏻 Bean으로 등록하면 애플리케이션의 객체를 Spring IoC 컨테이너에서 관리해서 의존성 주입, 객체 생명 주기 관리, 재사용성을 제공한다.
@Service, @Controller, @Repository가 @Component의 특화 버전이다.
@Target
어노테이션을 적용할 수 있는 위치를 제한하는 어노테이션이다.
주요 값 (ElementType):
- ElementType.TYPE: 클래스, 인터페이스, 열거형에 적용.
- ElementType.METHOD: 메서드에 적용.
- ElementType.FIELD: 필드(멤버 변수)에 적용.
- ElementType.PARAMETER: 메서드 매개변수에 적용.
- ElementType.CONSTRUCTOR: 생성자에 적용.
- ElementType.ANNOTATION_TYPE: 다른 어노테이션에 적용.
- ElementType.LOCAL_VARIABLE: 지역 변수에 적용.
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface CustomAnnotation {
}
@CustomAnnotation을 메소드와 필드에만 적용할 수 있도록 타겟 지정한 코드
@Retention
어노테이션의 유지 기간을 지정하는 어노테이션이다.
주요 값 (RetentionPolicy):
- RetentionPolicy.SOURCE:
컴파일러가 어노테이션을 무시하며, 소스 코드에만 존재. - RetentionPolicy.CLASS:
컴파일 후 .class 파일에 포함되지만, 런타임에는 사용 불가능. (기본 값) - RetentionPolicy.RUNTIME:
컴파일 후 .class 파일에 포함되며, 런타임에도 리플렉션을 통해 사용할 수 있음.
@Documented
어노테이션이 javadoc에 포함되도록 지정하는 메타 어노테이션이다. 주로 라이브러리나 API 문서를 작성할 때 사용된다.
✏️ Request Mapping
@RequestMapping
HTTP 요청을 특정 메소드나 클래스에 매핑하는 데 사용된다. 주로 컨트롤러 클래스와 그 안의 핸들러 메소드에서 사용한다.
주요 역할
1. URL 매핑: 특정 URL 경로와 컨트롤러 메소드 연결
2. HTTP 메소드 매핑: GET, POST, PUT, DELETE 지정
3. 매개변수 및 헤더 조건: 요청 파라미터, 헤더 등의 조건도 매핑 조건에 포함할 수 있다.
@Controller
@RequestMapping("/users")
public class UserController {
@RequestMapping("/list")
public String listUsers() {
return "userList";
}
}
위 예제에서는 클래스에서 /users, 메서드에서 /list가 결합되어 /users/list 경로로 매핑된다.
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/get")
public String getHandler() {
return "GET Request";
}
@PostMapping("/post")
public String postHandler() {
return "POST Request";
}
}
일반적으로 클래스에는 RequestMapping 어노테이션을, 메서드에는 http 메서드에 따른 단축 어노테이션을 사용한다.
매개변수 및 헤더 조건에 따른 RequestMapping
1.특정 parameter 매핑
package com.example.springbasicannotation.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ParameterController {
// parms 속성값 추가
@GetMapping(value = "/users", params = "gender=man")
public String params() {
// logic
String result = "params API가 호출 되었습니다.";
return result;
}
}
실제 URL GET http://localhost:8080/users?gender=man 파라미터가 있어야 호출된다.
- 속성 작성 규칙
- params = "gender"
- params의 key값은 커스텀이 가능하다
- value는 없어도 된다.
- params = "!gender"
- gender가 없어야 한다.
- params = "gender=man"
- gender=man 이어야 한다.
- params = "gender!=man"
- params의 value값이 man가 아니여야 한다.
- params = {"gender=man", "gender=woman"}
- 배열로 속성 값을 여러 개 설정이 가능하다.
- params = "gender"
2. 특정 Header 매핑
@RestController
public class ParameterController {
// headers 속성값 추가
@PostMapping(value = "/users", headers = "Content-Type=application/json")
public String headers() {
// logic
String result = "headers API가 호출 되었습니다.";
return result;
}
}
@PathVariable
URL 경로에 포함된 값을 메서드 매개변수로 전달받기 위해 사용 => URL 경로에 포함된 값을 추출해서 컨트롤러 메서드에서 사용 가능!
@GetMapping("/users/{id}")
public String getUserById(@PathVariable String id) {
return "User ID: " + id;
}
@RequestParam
Http 요청의 쿼리 스트링 또는 폼 데이터에 포함된 파라미터 값을 메서드의 매개변수로 전달받기 위해 사용
@GetMapping("/search")
public String search(@RequestParam("query") String keyword) {
return "Search keyword: " + keyword;
}
URL: /search?query=Spring
결과: Search keyword: Spring
👉🏻 @RequestVariable와 @RequestParam 차이
특징 | @PathVariable | @RequestParam |
데이터 위치 | URL 경로의 일부 | URL 쿼리 스트링 또는 폼 데이터 |
사용 목적 | RESTful 경로 매핑 | 추가적인 쿼리 파라미터 매핑 |
예제 URL | /users/123 | /users?id=123 |
MultiValueMap
Map과 유사하게 Key, Value 형식으로 구현되어 있지만 하나의 Key가 여러 Value를 가질 수 있다. HTTP Header, Reqeust Parameter와 같이 하나의 Key에 여러 값을 받을 때 사용한다.
MultiValueMap<String, String> linkedMultiValuemap = new LinkedMultiValueMap();
// key1에 value1 저장
linkedMultiValuemap.add("key1", "value1");
// key1에 value2 저장
linkedMultiValuemap.add("key1", "value2");
// key1에 저장된 모든 value get
List<String> values = linkedMultiValuemap.get("key1");