일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 프로그래머스 자바
- 백준 14938번 서강그라운드
- StringBuilder
- Stack
- replace()
- 프로그래머스 java
- 백준 2473번 세 용액 - java
- dp
- 백준 1541
- hash
- 백준 2467번 용액 자바 - 이분탐색
- StringTokenizer
- 백준 3190번
- 백준 1197번 최소 스패닝 트리 - java
- HashMap
- toUpperCase
- ac 5430번
- 최소 힙 1927
- mysql hy000 에러
- map
- 백준 1647번 도시 분할 계획 - java
- Java
- kotlin
- HashSet
- 백준 1806번 부분합 java
- 프로그래머스
- 백준 1043번 거짓말 - java 분리 집합
- 18111번 마인크래프트 - java 구현
- append
- 코틀린기초
- Today
- Total
말하는 컴공감자의 텃밭
Spring - 로깅? 요청 매핑? 본문
로깅 라이브러리를 사용해 로그를 출력해보자.
스프링 부트에서는 기본적으로 아래 라이브러리를 사용한다.
SLF4J - http://www.slf4j.org
Logback - http://logback.qos.ch
오늘은 SLF4J 를 사용해봅시도
@RestController로 View를 반환하지 않고 바로 메세지 바디에 String을 넣어주게 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package hello.springmvc.basic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class LogTestController { private final Logger log = LoggerFactory.getLogger(getClass()); @RequestMapping("/log-test") public String logTest() { // System.out.println(" 기존에는 이렇게 찍어봤었죠.. "); 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"; } } | cs |
- application.properties 에 아래 코드를 추가하면 콘솔창 색이 구분되어진다.
spring.output.ansi.enabled=always
로그 범위 ?
-> 로그가 출력되는 포멧 확인
시간, 로그 레벨, 프로세스 ID, 쓰레드 명, 클래스명, 로그 메시지
Level 단계
TRACE > DEBUG > INFO > WARN > ERROR
개발 서버는 debug 출력
운영 서버는 데이터가 많으므로 Info 출력
근데 엥.. 내가 쓴 코드 로그가 없길래 확인해보니
윈도우 cmd로 PID 찾아서 꺼주고 진행해줬다.
CMD -> netstat -ano 입력 -> 8080 포트 PID 찾기 -> taskkill /f /pid ["PID"]
요청 매핑
@RequestMapping
클라이언트 요청에 정보를 어떤 Controller가 처리할지를 매핑하기 위한 어노테이션이다.
@RequestMapping에 URL을 포함하여 해당 Controller 클래스에 명시하여 사용한다.
요청에 맞는 컨트롤러를 사용한다고 이해하면 편하다.
예시로 @Controller에 반환 값이 `String` 이라면 뷰 이름으로 인식된다. 그래서 뷰를 찾고 뷰가 랜더링된다.
@RequestMapping을 사용하여 모든 유형의 HTTP 요청을 처리할 수 있다.
- 요청 처리 세부 정보를 지정하는 여러 속성을 제공한다.
- method: HTTP 메소드(예: RequestMethod.GET, RequestMethod.POST 등)
- value: 메소드가 처리할 URL 패턴입니다.
- params: 요청에 있어야 하는 요청 매개변수.
- headers: 요청에 있어야 하는 헤더.
- consumes: 요청 본문의 미디어 유형.
- produces: 응답의 미디어 유형. 등등
- method: HTTP 메소드(예: RequestMethod.GET, RequestMethod.POST 등)
각각 로그를 찍어보면서 올바르게 처리되는지 확인해보자.
[기본] 예제 코드
@RestController
public class MappingController {
private Logger log = LoggerFactory.getLogger(getClass());
@RequestMapping("/hello-basic")
public String helloBasic() {
log.info("helloBasic");
return "ok";
}
[HTTP 메서드 매핑] 예제 코드
@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
public String mappingGetV1() {
log.info("mappingGetV1");
return "ok";
}
[HTTP 메서드 축약] 예제 코드
@GetMapping(value = "/mapping-get-v2")
public String mappingGetV2() {
log.info("mapping-get-v2");
return "ok";
}
[PathVariable] 경로변수, 다중도 가능하다
- @PathVariable("userId") String userId 를 @PathVariable String userId 로 바꿔도 동작한다.
@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {
log.info("mappingPath userId={}, orderId={}", userId, orderId);
return "ok";
}
다 잘 나오다가 엥? 오류가 발생했다.
넌 뭐야
2024-04-17T18:32:37.015+09:00 ERROR 2944 --- [springmvc]
[nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] :
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
[Request processing failed: java.lang.IllegalArgumentException: Name for argument of type
[java.lang.String] not specified, and parameter name information not available via reflection.
Ensure that the compiler uses the '-parameters' flag.]
with root cause
에러를 읽어보니 스프링에서 파라미터 이름을 추론하려다 실패해서 IllegalArgumentException가 발생했다.
예제에서는 PathVariable에 명시하지 않았기에 변수이름을 지정해주었다.
@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable("userId") String userId, @PathVariable("orderId") Long orderId) {
log.info("mappingPath userId={}, orderId={}", userId, orderId);
return "변수명 명시 후 -> ok";
}
잘 뜨는구만 ^<^
이어서
[특정 파라미터 조건 매핑] : 특정 파라미터가 있는지 없는지 조건 추가
- 파라미터로 추가 매핑
- params="mode"
- params="!mode" 등등
@GetMapping(value = "/mapping-param", params = "mode=debug")
public String mappingParam() {
log.info("mappingParam");
return "ok";
}
[특정 헤더조건 매핑] : 헤더도 존재.
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
log.info("mappingHeader");
return "ok";
}
[미디어 타입 조건 매핑]
HTTP 요청 Content-Type, consume
@PostMapping(value = "/mapping-consume", consumes = "application/json")
public String mappingConsumes() {
log.info("mappingConsumes");
return "ok";
}
- HTTP 요청의 Content-Type 헤더를 기반으로 미디어 타입으로 매핑한다.
- 만약 맞지 않으면 HTTP 415 상태코드(Unsupported Media Type)을 반환한다.
- postman으로 json을 Post로 테스트 하니 ok로 잘 나왔다.
HTTP 요청 Accept, produce
@PostMapping(value = "/mapping-produce", produces = "text/html")
public String mappingProduces() {
log.info("mappingProduces");
return "ok";
}
- HTTP 요청의 Accept 헤더를 기반으로 미디어 타입으로 매핑한다.
- 만약 맞지 않으면 HTTP 406 상태코드(Not Acceptable)을 반환한다.
text/html을 생산하기에 Accept를 설정해주어야 한다.
에러의 원인은 미디어 타입이 안맞기 때문이다.
produces = "text/plain"
produces = {"text/plain", "application/*"}
produces = MediaType.TEXT_PLAIN_VALUE
produces = "text/plain;charset=UTF-8"
이처럼 여러 방법으로 가능하다
'백엔드 > Spring' 카테고리의 다른 글
Spring 포인트 컷? - AOP (0) | 2024.06.24 |
---|---|
Spring과 웹 애플리케이션 (1) | 2023.10.29 |