728x90

최근에 스터디를 하면서 공부를 하고 있습니다.

그런데 금방 까먹는 듯한 기분이 들어 정리하는 시간을 가지려고 합니다.

이렇게 하면 더 오래 남지 않을까 하는 개인적인 기대가 있습니다.

이번 글은 인프런 김영한 님의 스프링 강의 - 스프링의 기본 기능 내용 정리입니다.

 

로깅(Logging)

제가 프로젝트를 수행할 때는 어떠한 버그가 발생했을 때 이유를 알아보기 위해서 

시스템 콘솔에 데이터를 출력하는 System.out.println()을 사용했습니다.

하지만 실무에서 위의 방법을 사용할 경우에는 로그관리를 할 수 없기 때문에 별도의 로깅 라이브러리를 사용합니다.

스프링 부트는 기본적으로 slf4j라는 라이브러리를 사용하는데,

이는 Logback, Log4j, Log4j2 등 수많은 라이브러리를 통합해서 제공하는 라이브러리입니다.

 

로그의 선언에는 

private Logger log = LoggerFactory.getLogger(getClass());
private static final Logger log = LoggerFactory.getLogger(Xxx.class);
@Slf4j

위와 같은 방법을 사용할 수 있습니다. Logger와 LoggerFactory은 slf4j의 클래스입니다.

그리고 @Slf4j 어노테이션은 Lombok 라이브러리의 어노테이션으로 위의 두줄과 같이 직접적인 선언 없이

로그를 호출할 수 있게 해 줍니다. 이외에도 Lombok은 DTO 클래스에서 setter, getter의 작성을 쉽게 해주기도 합니다.

Lombok에 대한 자세한 내용은 다음에 다뤄보도록 하겠습니다.

 

 호출은 아래와 같이 할 수 있습니다.

String name = "Spring";
 
 log.trace("trace log={}", name);
 log.debug("debug log={}", name);
 log.info(" info log={}", name);
 log.warn(" warn log={}", name);
 log.error("error log={}", name);

로그의 출력은 개발 단계와 운영 단계에 맞춰 각각 출력하는 범위를 정할 수 있습니다.

레벨 순은 trace >> debug >> info >> warn >> error 순으로 디폴트 값은 info입니다.

그래서 출력을 info로 설정하면 하위 레벨인 debug와 trace는 출력되지 않습니다.

 

log.debug("String concat log=" + name);

그리고 로그의 출력을 위와 같이 + 연산자를 사용해서 출력할 수도 있습니다.

하지만 위와 같은 경우는 리소스를 낭비하여 사용하지 않아야 합니다.

출력이 info로 설정되어 있을 경우 debug는 대상이 아니라 그냥 넘어가야 하지만

그 작업이 이뤄지기 이전에 + 연산자의 로직이 실행돼 불필요한 자원을 소모하기 때문입니다.

 

로그 사용의 장점

  • 스레드 정보, 클래스 이름 같은 부가 정보를 함께 볼 수 있고, 출력 모양을 조정할 수 있습니다.
  • 로그를 상황에 맞게 레벨을 조절하여 출력할 수 있습니다.
  • 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있습니다.
  • 파일로 남길 때에는 특정 기준에 맞춰 로그를 분할할 수 있습니다. 

 

매핑(Mapping)

스프링에서는 @Controller 어노테이션을 사용해 컨트롤러를 찾을 수 있습니다.

그리고 @RequestMapping 어노테이션을 사용해 해당하는 URL 호출이 오면 메서드가 실행되도록 매핑할 수 있습니다.

여기서는 @RequestMapping의 여러 매핑 방법에 대해 정리해보도록 하겠습니다.

 

@RequestMapping 방법 

  • HTTP 메서드 매핑
  • PathVariable 매핑
  • 특정 파라미터 조건 매핑
  • 특정 헤더 조건 매핑
  • 미디어 타입 조건 매핑

 

HTTP 메서드 매핑

 

HTTP 메서드 매핑은 @RequestMapping의 method 속성으로 매핑을 하는 방법입니다.

기본적으로 GET, POST, PUT, PATCH 등 모든 메서드에 대해 허용하게 됩니다.

method 속성을 사용하면 이를 특정 메서드의 요청에만 응답하도록 설정할 수 있습니다.

@RequestMapping(value = "/mapping", method = RequestMethod.GET)

위 URL에 POST 요청을 보내고 POST 요청에 해당하는 매핑이 없을 경우 

스프링 MVC는 HTTP 405(Method Not Allowed) 코드를 반환합니다.

덧붙여 스프링 부트는 해당 메서드 매핑의 축약형 어노테이션을 제공합니다.

@GetMapping(value="/mapping")
@PostMapping(value="/mapping")
@PutMapping(value="/mapping")

 

 

PathVariable 매핑

 

HTTP 리소스 경로에 식별자를 넣는 방법입니다.

@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {}

@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable String userId) {}

위와 같이 사용할 수 있으며, 경로 변수와 파라미터의 이름이 같다면 @PathVariable의 이름을 생략할 수 있습니다.

 

특정 파라미터 조건 매핑

 

/**
 * 파라미터로 추가 매핑
 * params="mode",
 * params="!mode"
 * params="mode=debug"
 * params="mode!=debug" (! = )
 * params = {"mode=debug","data=good"}
 */
@GetMapping(value = "/mapping-param", params = "mode=debug")

특정 파라미터가 있거나 없는 요청에 대해서 매핑하는 방법입니다.

하지만 잘 사용되지는 않는다고 합니다.

 

 

특정 헤더 조건 매핑

 

/**
 * 특정 헤더로 추가 매핑
 * headers="mode",
 * headers="!mode"
 * headers="mode=debug"
 * headers="mode!=debug" (! = )
 */
@GetMapping(value = "/mapping-header", headers = "mode=debug")

파라미터 매핑과 비슷하지만 HTTP 헤더를 이용합니다.

 

 

미디어 타입 조건 매핑

 

미디어 타입 조건 매핑에는 HTTP 요청의 Content-Type과 Accept 해당하는 매핑이 있습니다.

Content-Type은 클라이언트가 서버에게 전송하는 데이터의 원래 미디어 유형을 말합니다.

Accept는 클라이언트가 이해할 수 있는 미디어 유형의 HTTP 요청 헤더입니다. 

 

특정 Content-Type 요청에는 consumes 속성을 사용하고, Accept 요청에는 produces 속성을 사용합니다.

제가 이 속성들을 사용할 때에는 주로 jQuery로 Ajax 통신을 할 때 사용했습니다.

특정한 값으로 전달받거나 전달하기 위해서 그렇습니다.

 

Content-Type

/**
 * Content-Type 헤더 기반 추가 매핑 Media Type
 * consumes="application/json"
 * consumes="!application/json"
 * consumes="application/*"
 * consumes="*\/*"
 * MediaType.APPLICATION_JSON_VALUE
 */
@PostMapping(value = "/mapping-consume", consumes = "application/json")

/**
 *
 * consumes 예시
 */
consumes = "text/plain"
consumes = {"text/plain", "application/*"}
consumes = MediaType.TEXT_PLAIN_VALUE

맞지 않으면 HTTP 415(Unsupported Media Type) 상태 코드를 반환합니다.

 

Accept

/**
 * Accept 헤더 기반 Media Type
 * produces = "text/html"
 * produces = "!text/html"
 * produces = "text/*"
 * produces = "*\/*"
 */
@PostMapping(value = "/mapping-produce", produces = "text/html")

/**
 *
 * produces 예시
 */
produces = "text/plain"
produces = {"text/plain", "application/*"}
produces = MediaType.TEXT_PLAIN_VALUE
produces = "text/plain;charset=UTF-8"

맞지 않으면 HTTP 406(Not Acceptable) 상태코드를 반환합니다.

728x90

+ Recent posts