[MVC1] 6. 로그와 URL매핑

kiwonkim·2021년 7월 15일
0
post-thumbnail

로그 기능과 스프링 MVC에서 URL매핑, 헤더조회에 대해 알아보자



로그

운영시스템에서는 필요한 정보 출력시 System.out.println()이 아닌 로깅 라이브러리로 로그를 출력한다. 로깅 라이브러리는 Logback, Log4J 등이 있는데 이것들을 통합해 인터페이스화한 라이브러리가 SLF4J 라이브러리이다. 주로 SLF4J 라이브러리와 그 구현체로 Logback 을 선택한다.


Logger 객체 생성

//Logger 는 SLF4J 인터페이스 타입 참조변수임에 유의
private Logger log = LoggerFactory.getLogger(getClass());

위와 같이 컨트롤러 클래스의 필드에 Logger 객체를 직접 생성해도 되고

@Slf4j
@Controller
public class example1 {
}

Lombok의 @Slf4j 애노테이션을 사용하면 Logger 객체의 이름을 log로 자동으로 만들어준다.


로그 레벨

특정 수준의 로그까지만 출력하도록 로그 레벨을 정할 수 있다. 로그레벨은 Trace, Debug, Info, Warn, Error 다섯단계가 존재하며 상위 레벨로 설정 시 하위부터 해당 레벨까지 출력한다.

ex) Info 레벨로 설정시, Info, Warn, Error 레벨의 로그를 출력

#전체 로그 레벨 설정(기본 : info)
logging.level.root=info

#hello.spring 패키지와 그 하위 패키지 로그 레벨 설정
logging.level.hello.spring=debug

로그 레벨은 application.properties 파일에서 설정이 가능하다.


로그 출력

@RequestMapping("/log-test")
public String logTest() {
    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);
}

URI로 접속하면 컨트롤러가 실행되어 위와 같이 콘솔에 로그가 출력된다. 로그는 시간, 로그레벨, 프로세스 ID, 쓰레드 명, 클래스명, 로그 메시지 순서대로 정보를 출력한다.

현재 로그레벨이 trace 여서 다섯가지 레벨이 모두 출력되었다. 로그 레벨을 info로 변경한다면 하위 세개만 출력될 것이다.

// 로그 출력에서 문자열 합치는 방식 금지
log.info("String log = " + name);

문자열을 합치는 방식으로 로그를 출력하면 안된다. 위의 방법은 로그 레벨에 해당하지 않더라도 코드가 실행되어 문자열을 더해서 준비시킨다. 따라서 문자열 합치기 연산 낭비가 발생한다. {} 방식은 레벨에 해당할 때만 연산이 발생하므로 반드시 {} 방식으로 로그를 출력해야한다.


로그를 쓰는 이유

  1. 쓰레드, 클래스 같은 부가정보 함께 볼 수 있음.
  2. 콘솔에만 출력가능한 println과 달리 별도의 위치에 저장할 수 있고 자동 압축도 지원
  3. 최적화가 잘되어있어 System.out 보다 성능이 좋다.

따라서 실무에서는 꼭 로그를 사용.
보통 개발서버는 debug. 운영서버는 info의 레벨을 사용한다.

로그는 Lombok이나 Slf4j + Logback으로 객체를 만들어 사용한다. 설정한 로그의 출력 범위를 로그 레벨을 통해 정할 수 있다. 오버헤드 방지를 위해 꼭 {} 방식을 사용하자.



요청 매핑

Servlet은 @WebServlet에서 urlpattern 속성 설정 후 서블릿을 등록하여 매핑을 수행했다. 그러면 스프링은 어떻게 컨트롤러와 URI를 매핑할까?

- @RequestMapping

@ResponseBody
@RequestMapping("/hello/spring")
public String helloSpring() {
	log.info("helloSpring");
    return "ok";
}

@Controller 클래스 내부 메서드에 @RequestMapping으로 메서드 단위로 URI와 매핑을 수행한다.

- PathVariable

@ResponseBody
@RequestMapping("/hello/{userId}")
public String mappingPath(@PathVariable String userId) {
	log.info("mappingPath userId={}", userId);
    return "ok";
}

쿼리 파라미터가 아닌 URI에 userId 등의 식별자를 넣는 경우가 있다. 이때 PathVariable을 파라미터로 하여 식별자 부분을 컨트롤러 내에서 사용할 수 있다. {userId} 부분과 파라미터 userId부분이 같아야함을 주의하자.

- 특정 조건 매핑

//파라미터에 userId = kim 이 있어야 매핑
@RequestMapping(value = "/mapping-param", params = "userId=kim")

//Http 요청 헤더에 hello = spring 이 있어야 매핑
@RequestMapping(value = "/mapping-header", headers = "hello=spring")

//Http 요청 헤더 content-type 값이 application/json 이어야 매핑
@RequestMapping(value = "/mapping-consume", consumes = "application/json")

//Http 요청 헤더 accept 값이 text/html 이어야 매핑
@RequestMapping(value = "/mapping-produce", produces = "text/html")

- 메서드 조건 매핑

@GetMapping

@PostMapping

@PutMapping

특정 조건의 매핑중 가장 많이 사용하는 메서드 조건 매핑은 별도의 애노테이션으로 분화되었다.

스프링의 URL매핑은 @RequestMapping을 사용한다. PathVariable이 있는 경우 가져와 사용할 수 있다. 매핑에 조건을 추가할 수 있다. 메서드 조건은 @GetMapping @PostMapping 과 같이 별도 애노테이션이 존재한다.



요청 헤더 가져오기

@RequestMapping"/headers")
public String headers(HttpServletReqeust request, //요청 객체
			HttpServletResponse response, //응답 객체
                        HttpMethod httpMethod, //메서드 방식
                        @RequestHeader MultiValueMap<String, String> // 모든 헤더
                        @RequestHeader("host") String host) // 특정 헤더
                        {
                        	//받은 헤더정보 객체들 사용
                        }

서블릿에서는 WAS가 메시지를 분석하여 HttpServletRequest와 HttpServletResponse 객체를 생성해 서블릿에 넣어준다고 하였다. 스프링은 후에 서술할 ArgumentResolver가 이 기능을 대신해 여러 객체를 생성해 컨트롤러에 넣어준다. 이때 @ReqeustHeader로 헤더정보도 가져올 수 있다.

컨트롤러 파라미터에 @RequestHeader로 헤더 정보를 컨트롤러로 가져올 수 있다.



본 글은 김영한님의 "스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술" 강의내용 및 이해한 내용을 정리한 것입니다.

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard

0개의 댓글

관련 채용 정보