본 프로젝트 자료는 김영한님의 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술을 참고 제작됐음을 알립니다.
실무에 들어가면 System.out.println() 같은 시스템 콘솔을 사용하기 보다는 logging 이라는 라이브러리를 사용한다.
logging 관련 프레임워크는 log4j, logback, log4j2 등 통합해서 Slf4j 라이브러리가 있다.
그럼 어떻게 사용하는지 알아볼려고 한다.
public class LogTestController {
// 롬복을 사용하면 이걸 사용할 필요없이 자동으로 다 출력해준다
private final Logger log = LoggerFactory.getLogger(getClass());
@RequestMapping("/log-test")
public String logTest() {
String name = "Spring";
// 무슨 일이든 실행만 시키면 무조건 나오는거라 시스템아웃은 쓰지마라
System.out.println("name = " + name);
// 이렇게 쓰면 안된다
// 쓸모없는 리소스를 사용하게 된다
log.trace(" trace my log = {}" + name);
// 아래 방식을 추천
// 이렇게 사용하면 출력할 필요 없을 때 출력을 안한다.
// 그리고 현재 로그는 설정을 해서 튜닝해서 로그를 남길 수 있다
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); // 에러
return "ok";
}
}
로그를 사용하기 위해서는 위와 같은 로그를 먼저 선언을 해줘야 한다. log 종류에는 trace, debug, info, warn, error 가 있으며 각각의 의미는
info는 기본적으로 우선 순위로 출력된다.
lombok 의 @Slf4j 어노테이션을 선언만 해주면 별도의 선언 필요없이 사용할 수 있다.
그렇다면 왜 굳이 println문으로 찍으면 편할 것을 굳이 logging을 이용할까?
@RequestMapping("/mapping")
public String mappingPath() {
log.info("request mapping");
return "ok";
}
@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
public String mappingGetV1() {
log.info("mappingGetV1");
return "ok";
}
/**
* 편리한 축약 애노테이션 (코드보기) * @GetMapping
* @PostMapping
* @PutMapping
* @DeleteMapping
* @PatchMapping
*/
@GetMapping(value = "/mapping-get-v2")
public String mappingGetV2() {
log.info("mapping-get-v2");
return "ok";
}
@PathVariable을 이용하여 url 경로에서 매칭되는 부분(변수)를 조회할 수 있다.
// localhost:8080/mapping/userA 로 요청한 경우, data의 값에 userA가 들어가게 된다.
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {
log.info("mappingPath userId={}", data);
return "ok";
}
@PathVariable의 이름과 변수명이 같다면 밑과 같이 생략할 수 있다.
// @PathVariable의 이름과 파라미터 이름이 같으면 밑과 같이 생략할 수 있다.
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable String userId) {
log.info("mappingPath userId={}", userId);
return "ok";
}
@PathVariable을 다중으로 사용할 수도 있다.
@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {
log.info("mappingPath userId={}, orderId={}", userId, orderId);
return "ok";
}
/**
* 특정 헤더로 추가 매핑
* headers="mode",
* headers="!mode"
* headers="mode=debug"
* headers="mode!=debug" (! = )
*/
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
log.info("mappingHeader");
return "ok";
}
/**
* 특정 헤더로 추가 매핑
* headers="mode",
* headers="!mode"
* headers="mode=debug"
* headers="mode!=debug" (! = )
*/
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
log.info("mappingHeader");
return "ok";
}
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
log.info("mappingHeader");
return "ok";
}
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
log.info("mappingHeader");
return "ok";
}
REST API의 핵심인 리소스의 표현과 행위의 표현을 충족하기 위해서 Mapping의 축약 방법을 활용하면 좀 더 깔끔하게 설계가 가능하다