Spring Annotation, Request Mapping

star_pooh·2024년 12월 6일
0

TIL

목록 보기
31/39
post-thumbnail

Spring Annotation

@Slf4j

Slf4j는 인터페이스이고 그 구현체로 Spring Boot가 기본으로 제공하는 Logback을 대부분 사용.

  • Logging
    • Thread 정보, 클래스 이름과 같은 부가 정보도 확인 가능
    • Log Level 설정을 통하여 특정 레벨의 메세지만 출력하도록 설정도 가능하고, 로그 메시지를 일자별로 외부 저장소에 보관하기도 함
    • Log Level
      • TRACE > DEBUG > INFO > WARN > ERROR
# com.example.springbasicannotation에 설정된 레벨과 하위 레벨의 로그만 출력
# 디폴트 값은 INFO
logging.level.com.example.springbasicannotation=TRACE
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
public class Slf4jController {
    @RequestMapping("/logging")
    public String logging() {
        String logging = "Logging";
        // 로그를 출력하기 위해선 {}를 사용하며 출력하고자 하는 내용을 파라미터로서 입력
        log.trace("문자 trace={}", logging);
        log.debug("문자 debug={}", logging);
        log.info("문자 info={}", logging); // 문자 info=Logging
        log.warn("문자 warn={}", logging);
        log.error("문자 error={}", logging);

		// 기존의 print()처럼 + 를 사용하면 문자 연산이 수행됨
        log.info("문자 info " + logging); // 문자 info logging
        return "success";
    }
}

@Controller

  • View가 있는 경우에 사용
    • 템플릿 엔진인 Thymeleaf, JSP 등을 사용하는 경우
  • 리턴 값이 String인 경우, ViewResolver에 의해 View name으로 인식

@RestController

  • 응답할 데이터가 있는 경우에 사용
  • 대부분 @RestController를 사용(Restful API)
  • @Controller + @ResponseBody
  • 리턴 값으로 HTTP Message Body에 데이터를 입력

@Component

  • Spring Bean에 등록하는 역할 수행
    • Spring Bean은 애플리케이션의 구성 요소를 정의하는 객체
    • @Indexed를 같이 사용하면, 컴포넌트 스캔의 대상으로 Spring Bean에 더 빠르게 등록되도록 함

@Target

  • 어떤 범위에 적용되는지 설정 (클래스, 인터페이스, 메소드, ...)
    • 범위에 대한 내용은 ElementType Enum에 정의되어 있음
    • 여러 어노테이션에 설정되어 @Target이 중복으로 선언된 경우 자세히 선언된 것을 적용
// @RestController의 구성
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
...
}
// @ResponseBody의 구성
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}

💡 위의 예사에서 자세히 선언된 것은 @Target({ElementType.TYPE})이다.
@Target({ElementType.TYPE, ElementType.METHOD})이 더 자세하다고 느낄 수 있지만, 여기서 자세하다라는 표현은 구체적인 목적에 맞게 제한되어 있는가 라는 관점에서 봐야한다.
이러한 관점에서 볼 때 @Target({ElementType.TYPE, ElementType.METHOD})은 클래스와 메소드에 적용할 수 있기 때문에 사용자가 더 많은 선택지를 가질 수 있어 범용적이다.
그에 반해 @Target({ElementType.TYPE})는 클래스에만 적용할 수 있기 때문에 더 목적에 맞게 제한되어 있다.
따라서 @Target({ElementType.TYPE})이 더 자세한 것이며, @RestController는 클래스나 인터페이스에만(ElementType.TYPE) 적용할 수 있는 것이다.

@Retention

  • 얼마나 오래 유지되는지 설정(.java, .class, 런타임)
    • 유지에 대한 내용은 RetentionPolicy Enum에 정의되어 있음

Request Mapping

@RequestMapping

특정 URL로 Request를 보냈을 때 들어온 요청을 Controller 내부의 특정 Method와 Mapping 하기 위해 사용.

  • Spring Boot 3.0 버전 이하
    • URL path에 /example, /example/를 모두 허용
  • Spring Boot 3.0 버전 이상
    • URL path /example 만 허용
  • 속성값들을 설정할 때 배열 형태로 다중 설정이 가능
    • ex) @RequestMapping({”/example”, “/example2”, “/example3”})
  • HTTP Method POST, GET, PUT, PATCH, DELETE, HEAD 모두 허용
  • method 속성으로 HTTP 메서드를 지정하면 지정된 것만 허용
  • 하지만, 각 HTTP Method에 대해 직관적이고 축약되게 만들어져 있는 어노테이션을 사용
  • @RequestMapping은 주로 prefix로 선언할 URL을 class 레벨에 적용하는 것으로 사용
@RequestMapping("/prefix")
@RestController
public class RequestMappingController {
	// @GetMapping
    // @PostMapping
    // @DeleteMapping
    // ...
	@GetMapping(value="/tests")
	public String createTest() {
	}
}

@PathVariable

HTTP 특성 중 하나인 비연결성을 극복하여 데이터를 전달하기 위한 방법 중 하나이며, URL로 전달된 값을 파라미터로 받아오는 역할을 수행.

  • 경로 변수를 중괄호에 둘러싸인 값으로 사용
    • ex) user/{id}
  • 기본적으로 @PathVariable로 설정된 경로 변수는 반드시 값을 가져야 하며 값이 없으면 응답 상태코드 404 Not Found Error가 발생
  • RestfulAPI를 설계하는 것이 API의 기준이 되며 사용 빈도가 높아짐

@PathVariable 규칙

  • 파라미터 변수명과 PathVariable 변수명이 같으면 속성 값 생략 가능
@RequestMapping("/posts")
@RestController
public class PathVariableController {
	@GetMapping("/{postId}")
	public String pathVariableV1(@PathVariable("postId") Long data) {
		return "PathvariableV1 결과입니다 : " + data;
	}
}
👇
@RequestMapping("/posts")
@RestController
public class PathVariableController {
	@GetMapping("/{postId}")
	public String pathVariableV1(@PathVariable Long postId) {
		return "PathvariableV1 결과입니다 : " + postId;
	}
}
  • @PathVariable 다중 사용 가능
@RestController
public class PathVariableController {
	@GetMapping("/{postId}/comments/{commentId}")
	public String pathVariableV3(
    	@PathVariable Long postId,
        @PathVariable Long commentId) {

		String result = "PathvariableV3 결과입니다 postId : " + postId + "commentsId : " + commentId;
		return result;
	}
}

// 위와 같은 내용의 코드
@RequestMapping("/posts/{postId}")
@RestController
public class PathVariableController {
	@GetMapping("/comments/{commentId}")
	public String pathVariableV4(
    	@PathVariable Long postId,
        @PathVariable Long commentId) {

		String result = "PathvariableV4 결과입니다 postId : " + postId + "commentsId : " + commentId;
		return result;
	}
}

Parameter 추가 매핑

  • 특정 파라미터 매핑
@GetMapping(value = "/users", params = "gender=man")
  • 특정 헤더 매핑
 @PostMapping(value = "/users", headers = "Content-Type=application/json")
  • MediaType 매핑(consume)
    • 서버로 요청이 들어오는 데이터 타입 정의
@PostMapping(value = "/users", consumes = "application/json") // MediaType.APPLICATION_JSON_VALUE
  • MediaType 매핑(produces)
    • 클라이언트에 응답을 보내는 데이터 타입 정의
@GetMapping(value = "/users", produces = "text/plain")

0개의 댓글

관련 채용 정보