MVC 프레임워크 12

Mar 7, 2023

7 mins read

HTTP 요청 - 기본, 헤더 조회

  • 애노테이션 기반의 스프링 컨트롤러는 다양한 파라미터를 지원한다.
  • 헤더 정보를 조회하는 방법을 알아보기.
  • hello.springmvc.basic.request 패키지에 RequestHeaderController를 만들어서 알아본다.
package hello.springmvc.basic.request;

import java.util.Locale;
import org.springframework.http.HttpMethod;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@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";
	}
}

HTTP 요청 파라미터 - 쿼리 파라미터, HTML Form

  • 스프링을 사용해 서블릿에서 해봤던 HTTP 요청 데이터 전달 방법을 알아본다.
  • GET, POST, HTTP message body 3가지 방법을 하나씩 알아본다.
  • GET과 POST는 request.getParameter()로 받는 방법이 동일하다.
package hello.springmvc.basic.request;

import java.io.IOException;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@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으로 테스트는 http://localhost:8080/request-param-v1?username=hello&age=20 해보면 되고
  • POST로 테스트는 HTML을 하나 만들어서 해본다.
<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
 <form action="/request-param-v1" method="post">
 	username: <input type="text" name="username" />
 	age: <input type="text" name="age" />
 <button type="submit">전송</button>
 </form>
</body>
</html>

HTTP 요청 파라미터 - @RequestParam

  • 위에서 본 request.getParameter()를 @RequestParam을 써서 편리하게 사용할 수 있다.
package hello.springmvc.basic.request;

import java.io.IOException;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@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");
	}
	
	//@ResponseBody를 쓰면 @RestController처럼 View 조회를 무시하고, HTTP message body에 직접 해당 내용 입력
	@ResponseBody
	@RequestMapping("/request-param-v2")
	public String requestParamV2(
			@RequestParam("username") String memberName,
			@RequestParam("age") int memberAge) {
		
		log.info("username={}, age={}", memberName, memberAge);
		
		return "ok";
	}
	
	//HTTP 파라미터 이름이 변수 이름과 같으면 @RequestParam(name="xx") 생략 가능
	@ResponseBody
	@RequestMapping("/request-param-v3")
	public String requestParamV3(
			@RequestParam String username,
			@RequestParam int age) {
		
		log.info("username={}, age={}", username, age);
		
		return "ok";
	}
	
	//@RequestParam : 변수명이 같으면 @RequestParam도 생략할 수 있다.
	@ResponseBody
	@RequestMapping("/request-param-v4")
	public String requestParamV4(String username, int age) {
		log.info("username={}, age={}", username, age);
		return "ok";
	}
	
	//필수 변수 값을 설정할 수 있다.
	@ResponseBody
	@RequestMapping("/request-param-required")
	public String requestParamRequired(
			@RequestParam(required = true) String username, //null은 에러나지만 빈문자를 보내면 통과 된다. 
			@RequestParam(required = false) Integer age) { //int형에는 null을 넣을 수 없다. Integer에만 넣을 수 있다.
		log.info("username={}, age={}", username, age);
		return "ok";
	}
	
	@ResponseBody
	@RequestMapping("/request-param-default")
	public String requestParamDefault(
			@RequestParam(required = true, defaultValue = "guest") String username, //defaultValue는 빈 문자의 경우에도 적용(username= 만 써도 적용)
			@RequestParam(required = false, defaultValue = "-1") int age) {
		log.info("username={}, age={}", username, age);
		return "ok";
	}
	
	@ResponseBody
	@RequestMapping("/request-param-map") 
	public String requestParamMap(@RequestParam Map<String, Object> paramMap) { //MultiValueMap도 사용 가능
		log.info("username={}, age={}", paramMap.get("username"), paramMap.get("age"));
		return "ok";
	}
	
}

HTTP 요청 파라미터 - @ModelAttribute

  • 요청 파라미터를 받아서 필요한 객체를 만들고 값을 넣어주는 방법을 알아본다.
  • hello.springmvc.basic 패키지에 HelloData 클래스를 추가한다.
  • @Data : @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor 를 자동으로 적용해준다.
package hello.springmvc.basic;

import lombok.Data;

@Data
public class HelloData {
	private String username;
	private int age;
}
  • RequestParamController 클래스에 아래 메소드만 추가해서 확인해 본다.
	@ResponseBody
	@RequestMapping("/model-attribute-v1")
	public String modelAttributeV1(@ModelAttribute HelloData helloData){ //@RequestParam String username, @RequestParam int age
		//HelloData helloData = new HelloData();
		//helloData.getUsername();
		//helloData.getAge();
		
		log.info("username={}, age={}",helloData.getUsername(), helloData.getAge());
		return "ok";
	}
	
	@ResponseBody
	@RequestMapping("/model-attribute-v2")
	public String modelAttributeV2(HelloData helloData){ //@ModelAttribute 생략 가능
		log.info("username={}, age={}",helloData.getUsername(), helloData.getAge());
		return "ok";
	}
  • @ModelAttribute 와 @RequestParam는 생략할 수 있으니 혼란이 발생할 수 있다.
  • 둘다 생략했을 경우
    • String , int , Integer 같은 단순 타입 = @RequestParam
    • 나머지 = @ModelAttribute (argument resolver 로 지정해둔 타입 외)