코딍코딍
코딩기록
코딍코딍
전체 방문자
오늘
어제
  • 분류 전체보기 (271)
    • 개발 (2)
    • Java (1)
    • 스프링 (28)
    • JPA (11)
    • Git (3)
    • 알고리즘 (160)
      • 백준 (132)
      • 프로그래머스 (8)
      • SWEA (20)
    • 토이 프로젝트 (14)
      • 간단한 Springboot CRUD (1)
      • 게시판 프로젝트 (13)
    • 알고리즘 개념정리 (8)
    • 오류 해결 (13)
    • 보류 (0)
    • AWS (5)
    • 트러블 슈팅 (0)
    • 회고 (3)
    • CS (4)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

최근 글

티스토리

hELLO · Designed By 정상우.
코딍코딍

코딩기록

스프링

[스프링 MVC 1편] 스프링 MVC - 기본 기능 (1)

2022. 6. 23. 10:58

로깅 간단히 알아보기

스프링 부트 로깅 라이브러리

  • SLF4J
  • Logback
  • 로그 라이브러리는 Logback, Log4J, Log4J2 등등 수 많은 라이브러리가 있는데, 그것을 통합해서 인터페이스로 제공하는 것이 바로 SLF4J 라이브러리다.
  • 즉, SLF4J는 인터페이스이고 그 구현체로 Logback 같은 로그 라이브러리를 선택하면 된다. 실무에서는 스프링 부트가 기본으로 제공하는 Logback을 대부분 사용한다.

 

로그 선언

private Logger log = LoggerFactory.getLogger(getClass());
private static final Logger log = LoggerFactory.getLogger(Xxx.class);
@Slf4j : 롬복 사용 가능

 

LogTestController (http://localhost:8080/log-test)

@Slf4j
@RestController #"ok"을 바로 반환하여서 출력하게끔 한다
public class LogTestController {
//     private final Logger log = LoggerFactory.getLogger(getClass());

     @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);
         //로그를 사용하지 않아도 a+b 계산 로직이 먼저 실행됨, 이런 방식으로 사용하면 X
         log.debug("String concat log=" + name);
         return "ok";
     }
}

 

@RestController

  • @Controller 는 반환 값이 String 이면 뷰 이름으로 인식된다. 그래서 뷰를 찾고 뷰가 랜더링 된다.
  • @RestController 는 반환 값으로 뷰를 찾는 것이 아니라, HTTP 메시지 바디에 바로 입력한다. 따라서 실행 결과로 ok 메세지를 받을 수 있다. @ResponseBody 와 관련이 있는데, 뒤에서 더 자세히 설명한다.

 

로그 레벨

  • TRACE > DEBUG > INFO > WARN > ERROR
  • 개발 서버는 debug 출력, 운영 서버는 info 출력

 

로그 레벨 설정

#application.properties 파일에 설정하기

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

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

 

올바른 로그 사용법

  • log.debug("data=" + data) : 로그 출력 레벨을 info로 설정해도 해당 코드에 있는 "data="+data가 실제 실행이 되기에 의미없는 연산이 발생한다.
  • log.debug("data={}", data) : 의미없는 연산이 발생하지 않으므로 이렇게 사용하자.

 

로그 사용시 장점

  • 쓰레드 정보, 클래스 이름 같은 부가 정보를 함께 볼 수 있고, 출력 모양을 조정할 수 있다.
  • 로그 레벨에 따라 로그를 상황에 맞게 조절할 수 있다.
  • 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있다.
  • 성능도 일반 System.out보다 좋기에 실무에서는 꼭 로그를 사용해야 한다.

 

- private: 다른 클래스에서 가로채 사용하지 못하도록
- static: 인스턴스당 하나만 필요하므로, 또한 직렬화를 피하기 위해
- final: 변경될 일이 없으므로

 

 

요청 매핑

@RestController
public class MappingController {
     private Logger log = LoggerFactory.getLogger(getClass());
     
     /*
      기본 요청, 둘다 허용 /hello-basic, /hello-basic/
      HTTP 메서드 모두 허용 GET, HEAD, POST, PUT, PATCH, DELETE
     */
     @RequestMapping("/hello-basic")
     public String helloBasic() {
     log.info("helloBasic");
     return "ok";
     }
}

@RequestMapping("/hello-basic")

  • /hello-basic URL 호출이 오면 이 메서드가 실행되도록 매핑한다. 대부분의 속성을 배열[] 로 제공하므로 다중 설정이 가능하다. @RequestMapping({"/hello-basic","/hello-go"})
  • method 속성으로 HTTP 메서드를 지정하지 않으면 HTTP 메서드와 무관하게 호출된다. 모두 허용 GET, HEAD, POST, PUT, PATCH, DELETE

 

이런 경우엔 다른 URL 이지만, 스프링에서는 같은 요청으로 매핑한다.

  • URL 요청: /hello-basic , /hello-basic/
  • 매핑: /hello-basic

 

 

HTTP 메서드 매핑

#RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, ...
@RequestMapping("/mapping-get-v1", method = RequestMethod.GET)
public String mappingGetV1() {
     log.info("mappingGetV1");
     return "ok";
}
  • method 특정 HTTP 메서드 요청만 허용
  • 만약 여기에 POST 요청을 하면 스프링 MVC는 HTTP 405 상태코드(Method Not Allowed)를 반환한다.\

 

HTTP 메서드 매핑 축약

@GetMapping("/mapping-get-v2")
public String mappingGetV2() {
     log.info("mapping-get-v2");
     return "ok";
}
  • 훨씬 직관적이므로 이렇게 사용하자.
  • @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping

 

PathVariable (경로 변수)

@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {
     log.info("mappingPath userId={}", data);
     return "ok";
}
  • 실행: http://localhost:8080/mapping/userA
  • @PathVariable의 이름과 파라미터 이름이 같으면 생략 가능하다.
    • @PathVariable("userId") String userId -> @PathVariable String userId
  • 최근 HTTP API는 다음과 같이 리소스 경로에 식별자를 넣는 스타일을 선호한다.
    • /mapping/userA,  /users/1

 

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";
}
  • 실행: http://localhost:8080/mapping/users/userA/orders/100

 

특정 파라미터 조건 매핑

@GetMapping(value = "/mapping-param", params = "mode=debug")
public String mappingParam() {
     log.info("mappingParam");
     return "ok";
}
  • 실행: http://localhost:8080/mapping-param?mode=debug
  • 파라미터에 특정 값이 포함되어야 동작할 수 있다. 여기서는 mode=debug가 포함되어야 한다.

 

특정 헤더 조건 매핑

@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
     log.info("mappingHeader");
     return "ok";
}
  • 실행: Postman으로 테스트해야한다.
  • 파라미터 매핑과 비슷하지만, HTTP 헤더를 사용한다.
  • 헤더이름: mode, 헤더값: debug를 설정해줘야 동작한다.

 

미디어 타입 조건 매핑 - HTTP 요청 Content-Type, consume

@PostMapping(value = "/mapping-consume", consumes = "application/json")
public String mappingConsumes() {
     log.info("mappingConsumes");
     return "ok";
}
  • HTTP 헤더의 Content-Type이 application/json 이어야 동작한다.
  • 맞지 않으면 HTTP 415 상태코드(Unsupported Media Type)을 반환한다.

 

미디어 타입 조건 매핑 - HTTP 요청 Accept, produce

@PostMapping(value = "/mapping-produce", produces = "text/html")
public String mappingProduces() {
     log.info("mappingProduces");
     return "ok";
}
  • HTTP 헤더의 Accept가 text/html 이어야 동작한다.
  • 맞지 않으면 HTTP 406 상태코드(Not Acceptable)을 반환한다.

 

 

요청 매핑 - API

회원관리 API

@RestController
@RequestMapping("/mapping/users")
public class MappingClassController {
     @GetMapping #회원목록 조회
     public String users() {
     	return "get users";
     }
     
     @PostMapping #추가
     public String addUser() {
     	return "post user";
     }
    
     @GetMapping("/{userId}") #조회
     public String findUser(@PathVariable String userId) {
     	return "get userId=" + userId;
     }
     
     @PatchMapping("/{userId}") #수정
     public String updateUser(@PathVariable String userId) {
     	return "update userId=" + userId;
     }
     
     @DeleteMapping("/{userId}") #삭제
     public String deleteUser(@PathVariable String userId) {
     	return "delete userId=" + userId;
     }
}
  • 회원 목록 조회: GET          /users
  • 회원 등록:         POST        /users
  • 회원 조회:         GET          /users/{userId}
  • 회원 수정:         PATCH      /users/{userId}
  • 회원 삭제:         DELETE    /users/{userId}

 

 

HTTP 요청 - 기본, 헤더 조회

@Slf4j
@RestController
public class RequestHeaderController {
     @RequestMapping("/headers")
     public String headers(HttpServletRequest request,
     						HttpServletResponse response,
     						HttpMethod httpMethod,
     						Locale locale,
     						@RequestHeader MultiValueMap<String, String> headerMap,
                            @RequestHeader("host") String host,
                            @CookieValue(value = "myCookie", required = false) String cookie
     					   ) {
                           
         log.info("request={}", request);
         log.info("response={}", response);
         log.info("httpMethod={}", httpMethod);
         log.info("locale={}", locale);
         log.info("headerMap={}", headerMap);
         log.info("header host={}", host);
         log.info("myCookie={}", cookie);
         return "ok";
     }
}
  • HttpMethod : HTTP 메서드를 조회한다. org.springframework.http.HttpMethod
  • Locale : Locale 정보를 조회한다.
  • @RequestHeader MultiValueMap headerMap : 모든 HTTP 헤더를 MultiValueMap 형식으로 조회한다.
  • @RequestHeader("host") String host : 특정 HTTP 헤더를 조회한다.
  • @CookieValue(value = "myCookie", required = false) String cookie : 특정 쿠키를 조회한다.

 

 

 

 

'스프링' 카테고리의 다른 글

[스프링 MVC 1편] 스프링 MVC - 기본 기능 (3)  (0) 2022.06.29
[스프링 MVC 1편] 스프링 MVC - 기본 기능 (2)  (0) 2022.06.24
[스프링 핵심 원리] 빈 스코프 (2)  (0) 2022.06.22
[스프링 핵심 원리] 빈 스코프 (1)  (0) 2022.06.22
[스프링 핵심 원리] 빈 생명주기 콜백  (0) 2022.06.20
    '스프링' 카테고리의 다른 글
    • [스프링 MVC 1편] 스프링 MVC - 기본 기능 (3)
    • [스프링 MVC 1편] 스프링 MVC - 기본 기능 (2)
    • [스프링 핵심 원리] 빈 스코프 (2)
    • [스프링 핵심 원리] 빈 스코프 (1)
    코딍코딍
    코딍코딍
    ㅎ2

    티스토리툴바