목차
1.로거
2. 요청 매핑
3. HTTP 요청 - 기본, 헤더 조회
4. HTTP 요청 파라미터 - 쿼리 파라미터, HTML Form
5. HTTP 요청 파라미터 - @RequestParam
6. HTTP 요청 파라미터 - @ModelAttribute
7. HTTP 요청 메시지 - 단순 텍스트
8. HTTP 요청 메시지 - JSON
로거
개요
스프링 부트 라이브러리에는 logging이 포함되어있다. 기본적으로 SLF4J와 Logback 라이브러리를 사용한다. 로그 라이브러리에는 여러가지가 있는데, 이를 통합해 인터페이스로 제공하는 것이 SLF4J 라이브러리이다.
사용법
로그 선언
private Logger log = LoggerFactory.getLogger(getclass());
@Slf4j 롬복 사용도 가능하다.
로그 호출
log.info(" info log = {}", name);
log.trace("trace log = {}", name);
log.debug("debug log = {}", name);
log.warn("warn log = {}", name);
log.error("error log={}", name);
로그 레벨 설정
application.properties
#전체 로그 레벨 설정(기본 info)
logging.level.root=info
#hello.springmvc 패키지와 그 하위 로그 레벨 설정
logging.level.hello.springmvc=debug
설정에 따라, 로그가 출력되는 범위가 달라진다.
올바른 로그 사용법
log.debug("data" + data)와 같은 식으로 사용하지 않는다. 만약 debug를 사용하지 않는 로그 레벨인 경우에도, 코드에 연산이 있으면, 문자 더하기 연산이 발생해 효율성이 떨어진다.
log.debug("debug log = {}", name);
로그 장점
1. 쓰레드 정보, 클래스 이름 등의 부가 정보를 함께 볼 수 있다.
2. 로그 레벨에 따라 개발 서버에서는 모든 록를 출력하고, 운영서버에서는 출력하지 않는 등 상황에 맞게 로그를 조절할 수 있다.
3. 팡리이나, 네트워크 등 로그를 다른 위치에도 남길 수 있다.
4. 성능도 System.out보다 더 좋다.
요청 매핑
HTTP 메서드 매핑
HTTP 통신 방식 중 GET만 허용한다는 의미에서 method = RequestMethod.GET을 파라미터로 넣어주는데, 스프링은 GetMapping등 간단하게 코드를 줄인 어노테이션을 제공한다.
PathVariable(경로 변수) 사용
@ResponseBody
@GetMapping("/request-mapping-path/{userId}")
public String mappingPathVariable(@PathVariable("userId") String data) {
log.info("mapping Path userId={}", data);
return "ok";
}
Url로 넘어온 값을 받아서 사용할 수 있다.
특정 파라미터 조건 매핑
@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";
}
Content-Type 헤더 기반 추가 매핑
@PostMapping(value = "/mapping-consume", consumes = "application/json")
public String mappingConsumes() {
log.info("mappingConsumes");
return "ok";
}
클라이언트로부터 서버가 전송받는 리소스의 형태를 지정한다.
Accept 헤더 기반 추가 매핑
@PostMapping(value = "/mapping-produce", produces = "text/html")
public String mappingProduces() {
log.info("mappingProduces");
return "ok";
}
서버가 클라이언트에게 제공하는 리소스의 형태를 지정한다.
http 요청 - 기본, 헤더 조회
애노테이션 기반의 스프링 컨트롤러는 다양한 파라미터를 지원한다.
@ResponseBody
@GetMapping("/request-mapping-header")
public String mappingHeader(HttpServletRequest request,
HttpServletResponse response,
Locale locale,
@RequestHeader("host") String host,
@CookieValue(value = "myCookie", required = false) String cookie){
log.info("request={}", request);
log.info("response={}", response);
log.info("locale={}", locale);
log.info("header host={}", host);
log.info("myCookie={}", cookie);
return "ok";
}
HTTP 요청 파라미터 - 쿼리 파라미터, HTML Form
@Slf4j
@Controller
public class RequestParamController {
@RequestMapping("request-param-v1")
public void requestParamV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
log.info("username={}, age={}", username, age);
response.getWriter().write("ok");
}
}
get이든 Post든 데이터의 형태가 같게 들어오므로 위의 코드를 통해 파라미터로 값을 받을 수 있다.
요청: http://localhost:8080/request-param-v1?username=kim&age=25
HTTP 요청 파라미터 - RequestParam
1) 기본
@ResponseBody
@RequestMapping("/request-param-v2")
public String requestParamV2(
@RequestParam("username") String memberName,
@RequestParam("age") int memberAge) {
log.info("username={}, age={}", memberName, memberAge);
return "ok";
}
@ResponseBody: View 조회를 무시하고, HTTP message body에 직접 입력한다.
@RequestParam: 파라미터 이름으로 바인딩을 한다.
2) 파라미터 이름과 변수 이름이 같을 때 @RequestParam("")생략 가능
@ResponseBody
@RequestMapping("/request-param-v3")
public String requestParamV3(
@RequestParam String username,
@RequestParam int age) {
log.info("username={}, age={}", username, age);
return "ok";
}
username 변수명이 파라미터 이름 username과 같으므로 생략할 수 있다.
3) 이름이 같고 String, int, Integer 등의 단순 타입일 때 @RequestParam도 생략 가능
@ResponseBody
@RequestMapping("/request-param-v4")
public String requestParamV4(
String username, int age) {
log.info("username={}, age={}", username, age);
return "ok";
}
4) 파라미터 필수 여부 - requestParamRequired
@ResponseBody
@RequestMapping("/request-param-required")
public String requestParamRequired(
@RequestParam(required=true) String username,
@RequestParam(required=false) Integer age) {
log.info("username={}, age={}", username, age);
return "ok";
}
만약 required= true로 설정된 파라미터가 요청에 없을 경우, 400 예외가 발생한다.
주의점
1. /request-param?username= 파라미터 이름만 있고 값이 없는 경우 400오류가 나지 않고 빈문자로 통과되므로 주의해야 한다.
2. 기본형(primitive)에 null을 입력할 수 없다. 예를 들어, 위의 예제에서 int age에 null 입력하는 것은 불가능(500 예외 발생) 따라서 null 을 받을 수 있는 Integer 로 변경하거나, 또는 다음에 나오는 defaultValue 사용해야 한다.
5) 기본 값 적용 - default
@ResponseBody
@RequestMapping("/request-param-default")
public String requestParamDefault(
@RequestParam(required=true, defaultValue = "guest") String username,
@RequestParam(required=false, defaultValue = "-1") Integer age) {
log.info("username={}, age={}", username, age);
return "ok";
}
값이 없거나, 빈문자의 경우 default 값이 들어온다.
6) 파라미터 Map 조회 - requestParamMap
@ResponseBody
@RequestMapping("/request-param-map")
public String requestParamMap(@RequestParam Map<String, Object> paramMap){
log.info("username={}, age={}", paramMap.get("username"), paramMap.get("age"));
return "ok";
}
HTTP 요청 파라미터 - @ModelAttribute
@ResponseBody
@PostMapping("/request-mapping-model")
public String mappingModel(@ModelAttribute Member member) {
log.info("membername={}, memberage={}", member.getName(), member.getAge());
return "ok";
}
@ModelAttribute를 통해 요청에 의해 입력받은 파라미터를 자동으로 넣는다.
HTTP 요청 메시지 - 단순 텍스트
앞서 사용한 @RequestParam과 @ModelAttribute는 요청 파라미터를 조회하는 기능이다. 이와 달리 HTTP 메시지 바디를 직접 조회하는 방법들에 대해 알아보자.
1) InputStream
@PostMapping("/request-body-string-v1")
public void requestBodyString(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("messageBody={}", messageBody);
response.getWriter().write("ok");
}
2) Input, Output 스트림, Reader
@PostMapping("/request-body-string-v2")
public void requestBodyStringV2(InputStream inputStream, Writer writer) throws IOException{
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("messageBody={}", messageBody);
writer.write("ok");
}
3) HttpEntity
@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
String messageBody = httpEntity.getBody();
log.info("messageBody={}", messageBody);
return new HttpEntity<>("ok");
}
4) RequestBody
@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
log.info("messageBody={}", messageBody);
return "ok";
}
현업에서 가장 많이 쓰는 방식이다. 사실 이 방식을 설명하기 위해 위의 내용들이 있다고 해도 무방하다.
HTTP 요청 메시지 - JSON
아래 처럼 단순화의 과정을 거쳤다.
간단 예제 코드
@ResponseBody
@PostMapping("/request-mapping-json")
public String mappingJson(@RequestBody Member member) {
log.info("membername={}, memberage={}", member.getName(), member.getAge());
return "ok";
}
본 포스팅은 김영한님 인프런 강의내용을 바탕으로 복습을 위해 작성하였습니다. 강의를 통해 배운 개념을 바탕으로 추가적으로 공부한 부분과 간단한 코드 예제를 작성하였습니다. 코드 전체를 복사한 것이 아니라 임의로 수정하거나 생략하였습니다.
'백엔드 > Spring' 카테고리의 다른 글
[Spring] 타임리프 실습 (0) | 2022.07.26 |
---|---|
[Spring] 스프링 HTTP 응답 하기 (0) | 2022.07.22 |
[Spring] 스프링 MVC - 구조 이해 (0) | 2022.07.11 |
[Spring] MVC 패턴 핸들러, 어댑터 (0) | 2022.06.14 |
[Spring] FrontController로 View분리, Model 추가 등 실습해보기 예제 (0) | 2022.06.11 |