이 문서는 가리사니 개발자 포럼에 올렸던 글의 백업 파일입니다. 오래된 문서가 많아 현재 상황과 맞지 않을 수 있습니다.
스프링 컨트롤러와 파라미터 시리즈
서론
서블릿을 사용하다 스프링으로 넘어가게 되면 서블릿의 관행대로 파라미터를 받는 경우가 많습니다. 그래서 이번 강의에서는 여러가지 파라미터를 받는 방법에 대해서 알아보도록 하겠습니다.
서블릿과 같이 Request를 통해 파라미터를 가져오는 방법
@RestController
class TempController
{
@GetMapping("/temp")
String temp(HttpServletRequest request)
{
String a = request.getParameter("a");
String b = request.getParameter("b");
System.out.println("a : " + a);
System.out.println("b : " + b);
return "none";
}
}
콘솔결과 : /temp?a=1&b=2 a : 1 b : 2
Request 에서부터 가져오는게 너무 거창하고 지저분해 보입니다.
파라미터를 Map으로 가져오는 방법
Request 부터 가져오는 것이 너무 거창하기 때문에 Map에서 부터 가져와 보도록하겠습니다.
@RestController
class TempController
{
@GetMapping("/temp")
String temp(@RequestParam Map<String, String> param)
{
String a = param.get("a");
String b = param.get("b");
System.out.println("a : " + a);
System.out.println("b : " + b);
return "none";
}
}
콘솔결과 : /temp?a=1&b=2 a : 1 b : 2
Request 에서부터 가져오지 않을 뿐 똑같이 지저분합니다.
@RequestParam를 통한 직접 매칭하는 방법
@RestController
class TempController
{
@GetMapping( "/temp")
String temp(@RequestParam("a") String a, @RequestParam("b") int b)
{
System.out.println("a : " + a);
// Integer.parseInt() 과정이 필요없다!
System.out.println("b : " + b);
return "none";
}
}
콘솔결과 : /temp?a=1&b=2 a : 1 b : 2
형변환 까지 되기 때문에 제법 깔끔해 보입니다.
모델 클래스를 통한 직접 매칭
@Data @ToString @Getter @Setter 가 낯설다면
- 롬복 : /wiki?dn=70
@RestController class TempController { @GetMapping("/temp") String temp(Abc abc) { System.out.println("a : " + abc.getA()); System.out.println("b : " + abc.getB()); return "none"; } @Data @ToString @Getter @Setter static public class Abc { String a; int b; } }
콘솔결과 : /temp?a=1&b=2 a : 1 b : 2
받는 자료가 많아질 때 유용합니다. 또한 모델 클래스로 받을 때에는 자동으로 모델 Attribute 로 추가됩니다.
// 일반적인 파라미터로 받을 때의 예제 - 당연히 모델에 추가되지 않는다.
@GetMapping("/temp")
String temp(@RequestParam("a") String a, @RequestParam("b") int b, Model model)
{
System.out.println("모델 스캔 - 시작");
Map<String, Object> map = model.asMap();
for (String key : map.keySet())
{
System.out.println(key + " : " + map.get(key).toString());
}
System.out.println("모델 스캔 - 종료");
return "none";
}
콘솔결과 : /temp?a=1&b=2 모델 스캔 - 시작 모델 스캔 - 종료
// 하지만 모델 클래스로 받았다면!
@GetMapping("/temp")
String temp(Abc abc, Model model)
{
System.out.println("모델 스캔 - 시작");
Map<String, Object> map = model.asMap();
for (String key : map.keySet())
{
System.out.println(key + " : " + map.get(key).toString());
}
System.out.println("모델 스캔 - 종료");
return "none";
}
콘솔결과 : /temp?a=1&b=2 모델 스캔 - 시작 abc : TempController.Abc(a=1, b=2) org.springframework.validation.BindingResult.abc : org.springframework.validation.BeanPropertyBindingResult: 0 errors 모델 스캔 - 종료
@ModelAttribute 어노테이션을 통한 모델에 저장되는 Attribute Key값을 직접 설정해 줄 수 있습니다.
@GetMapping("/temp")
String temp(@ModelAttribute("changeAttrName") Abc abc, Model model)
{
System.out.println("모델 스캔 - 시작");
Map<String, Object> map = model.asMap();
for (String key : map.keySet())
{
System.out.println(key + " : " + map.get(key).toString());
}
System.out.println("모델 스캔 - 종료");
return "none";
}
콘솔결과 : /temp?a=1&b=2 모델 스캔 - 시작 changeAttrName : TempController.Abc(a=1, b=2) org.springframework.validation.BindingResult.changeAttrName : org.springframework.validation.BeanPropertyBindingResult: 0 errors 모델 스캔 - 종료
Attribute Key 가 abc가 아닌 changeAttrName 로 바뀌었음이 확인되었습니다.
PathVariable
위에서 설명한 것들은 파라미터를 어떻게 받아서 처리하냐 였지만 PathVariable의 경우는 path에서 어떤 규칙으로 파라미터를 가져올까에 대한 규칙이라고 보시면 됩니다.
@RestController
class TempController
{
@GetMapping("/temp/{a}/{b}")
String temp(@PathVariable("a") String a, @PathVariable("b") int b)
{
System.out.println(a);
System.out.println(b);
return "none";
}
}
콘솔결과 : /temp/1/2 a : 1 b : 2
물론 모델 클래스에 대입할 수 도 있습니다.
@RestController
class TempController
{
@GetMapping("/temp/{a}/{b}")
String temp(Abc abc)
{
System.out.println(abc.getA());
System.out.println(abc.getB());
return "none";
}
@Data
@ToString @Getter @Setter
static class Abc {
String a;
int b;
}
}
콘솔결과 : /temp/1/2 a : 1 b : 2