스프링 MVC 기본 기능

Jimin·2023년 3월 6일
0

스프링 - inflearn

목록 보기
14/15

Logging(로깅)

로깅 라이브러리

스프링 부트 로깅 라이브러리는 기본으로 다음 로깅 라이브러리를 사용한다.
1. SLF4J - http://www.slf4j.org
2. Logback - http://logback.qos.ch

로그 선언

  1. private Logger log = LoggerFactory.getLogger(getClass());
  2. private static final Logger log = LoggerFactory.getLogger(Xxx.class)
  3. @Slf4j : 롬복 사용 가능
    @Slf4j 를 로그 호출 대신 붙이고 log.getLogger() 를 바로 사용할 수 있다.

로그 호출

log.info("hello")

RestController

매핑 정보

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

Test

  • 개발 서버는 debug 출력
  • 운영 서버는 info 출력

로그 레벨 설정

  • application.properties
# 전체 로그 레벨 설정(기본 info) 
logging.level.root=info
# hello.springmvc 패키지와 그 하위 로그 레벨 설정 
logging.level.hello.springmvc=debug

올바른 로그 사용법

  1. X
log.debug("data="+data)

로그 출력 레벨을 info로 설정해도 해당 코드에 있는 "data="+data가 실제 실행이 되어 버린다.
⇒ 결과적으로 문자 더하기 연산이 발생한다.

  1. O
log.debug("data={}", data)

로그 출력 레벨을 info로 설정하면 아무일도 발생하지 않는다.
⇒ 따라서 앞과 같은 의미없는 연산이 발생하지 않는다.


요청 매핑

RequestParam과 PathVariable의 차이

  1. RequestParam
    http://192.168.0.1:8080?aaa=bbb&ccc=ddd
  2. PathVariable
    http://192.168.0.1:8080/bbb/ddd

HTTP 요청 파라미터 - @ModelAttribute

롬복 @Data

@Getter , @Setter , @ToString , @EqualsAndHashCode , @RequiredArgsConstructor 를 자동으로 적용해준다.

일반적인 코드

  @RequestParam String username;
  @RequestParam int age;
  HelloData data = new HelloData();
  data.setUsername(username);
  data.setAge(age);

@ModelAttribute 이용한 코드

  @ResponseBody
  @RequestMapping("/model-attribute-v1")
  public String modelAttributeV1(@ModelAttribute HelloData helloData) {
      log.info("username={}, age={}", 
      		helloData.getUsername(),
      			helloData.getAge());
      return "ok";
  }

스프링MVC는 @ModelAttribute 가 있으면 다음을 실행한다.
1. HelloData 객체를 생성한다.
2. 요청 파라미터의 이름으로 HelloData 객체의 프로퍼티를 찾는다.
3. 해당 프로퍼티의 setter를 호출해서 파라미터의 값을 입력(바인딩) 한다.
예) 파라미터 이름이 username 이면 setUsername() 메서드를 찾아서 호출하면서 값을 입력한다.

→ 생략 가능

생략 → @RequestParam Vs.@ModelAttribute

@ModelAttribute 는 생략할 수 있다.
그런데, @RequestParam 도 생략할 수 있으니 혼란이 발생할 수 있다.

스프링은 해당 생략시 다음과 같은 규칙을 적용한다.

  1. String , int , Integer 같은 단순 타입 = @RequestParam
  2. 나머지 = @ModelAttribute (argument resolver 로 지정해둔 타입 외)

HTTP 요청 메시지 - 단순 텍스트

HTTP message body에 데이터를 직접 담아서 요청

  1. HTTP API에서 주로 사용, JSON, XML, TEXT
  2. 데이터 형식은 주로 JSON 사용
  3. POST, PUT, PATCH

요청 파라미터와 다르게, HTTP 메시지 바디를 통해 데이터가 직접 넘어오는 경우는 @RequestParam , @ModelAttribute 를 사용할 수 없다.
(물론 HTML Form 형식으로 전달되는 경우는 요청 파라미터로 인정된다.)

@RequestBody, @ResponseBody 사용하기

    @ResponseBody
    @PostMapping("/request-body-string-v4")
    public String requestBodyStringV4(@RequestBody String messageBody) throws IOException {
        log.info("messageBody = {}", messageBody);
        return "ok";
    }

요청 파라미터 vs HTTP 메시지 바디

  1. 요청 파라미터를 조회하는 기능
    • @RequestParam
    • @ModelAttribute
  2. HTTP 메시지 바디를 직접 조회하는 기능
    • @RequestBody

HTTP 요청 메시지 - JSON

단순 text 반환하기

단순 String을 반환해주고 싶으면 @ResponseBody 를 사용하면 된다.

@RequestBody는 생략 불가능

스프링은 @ModelAttribute , @RequestParam 과 같은 해당 애노테이션을 생략시 다음과 같은 규칙을 적용한다.

  1. String , int , Integer 같은 단순 타입 = @RequestParam
  2. 나머지 = @ModelAttribute (argument resolver 로 지정해둔 타입 외)

따라서 이 경우 HelloData에 @RequestBody 를 생략하면 @ModelAttribute 가 적용되어버린다.
HelloData data@ModelAttribute HelloData data
⇒ 따라서 생략하면 HTTP 메시지 바디가 아니라 요청 파라미터를 처리하게 된다.


HTTP 응답 - HTTP API, 메시지 바디에 직접 입력

@RestController

@ResponseBody 를 일일이 붙이고 싶지 않다면 클래스 레벨에 붙여도 된다.
아니면 아예 @RestController 를 사용해주면 된다.

@RestController = @Controller + @ResponseBody

HttpStatus

	@ResponseStatus(HttpStatus.OK)
    @ResponseBody
    @GetMapping("/response-body-json-v2")
    public HelloData responseBodyJsonV2() {
        HelloData helloData = new HelloData();
        helloData.setUsername("userA");
        helloData.setAge(20);
          return helloData;
	 }

ResponseEntity 는 HTTP 응답 코드를 설정할 수 있는데, @ResponseBody 를 사용하면 이런 것을 설정하기 까다롭다.
@ResponseStatus(HttpStatus.OK) 애노테이션을 사용하면 응답 코드도 설정할 수 있다.
물론 애노테이션이기 때문에 응답 코드를 동적으로 변경할 수는 없다. 프로그램 조건에 따라서 동적으로 변경하려면 ResponseEntity 를 사용하면 된다.

profile
https://github.com/Dingadung

0개의 댓글