코딩/자바

[Spring] 기초 4주차

yoney 2025. 1. 22. 17:17

✏️ 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 파라미터가 있어야 호출된다.

 

  • 속성 작성 규칙
    1. params = "gender"
      • params의 key값은 커스텀이 가능하다
      • value는 없어도 된다.
    2. params = "!gender"
      • gender가 없어야 한다.
    3. params = "gender=man"
      • gender=man 이어야 한다.
    4. params = "gender!=man"
      • params의 value값이 man가 아니여야 한다.
    5. params = {"gender=man", "gender=woman"}
      • 배열로 속성 값을 여러 개 설정이 가능하다.

 

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");