스프링 @MVC에서 메서드 파라미터와 리턴에 사용되는 어노테이션
스프링의 MVC에서 @Controller 어노테이션을 사용하기 이전에는 Controller인터페이스를 구현하고 xml파일등에 등록하여 컨트롤러를 빈으로 등록하였으나 @Controller의 등장으로 @Controller 어노테이션을 클래스 위에 첨가하는 것 만으로 해당 클래스를 컨트롤러의 빈으로 사용할 수 있다.
뿐만 아니라 각 @Controller를 사용하는 클래스의 각 메서드마다 @RequestMapping 어노테이션을 사용하여 URL 매핑을 할 수 있어 클래스의 양을 상당히 줄일 수 있다.
개인적으로 @Controller의 존재와 @RequestMapping의 존재를 알고 있어서 두가지 어노테이션을 개발시 사용하고 있었으나 지금 생각해보면 그 외의 기능들은 스프링의 기능은 사용하지 않고 JSP를 공부할 당시의 기술을 쓰고 있어서 소스코드의 양이 방대해졌던 기억이 난다.
그러기에 어노테이션을 이용한 컨트롤러에서 파라미터와 모델, 뷰의 리턴과 관련된 기법들을 정리하여 차후에 기억이 희미해졌을 경우 찾아보고 또한, 해당 기술들을 이해함으로써 양질의 코드를 작성하고자 블로그에 포스팅 한다.
@Controller에서는 컨트롤러 역할을 담당하는 메소드의 파라미터 개수와 타입, 리턴 타입등을 자유롭게 결정할 수 있다는 것을 기억하고 아래의 예제를 참고하도록 하자.
1. 메소드 파라미터에 사용되는 어노테이션
1.1 @PathVariable
@RequestMapping의 URL에 {}에 들어가는 패스변수(Path variable)을 받는다.
ex) http://[ip]/test/주현태/30
url에 있는 이름과 나이정보를 읽을 경우
@RequestMapping(value = "/test/{name}/{age}")
public String pathVariableSample(@PathVariable("name") String name,
@PathVariable("age") int age, ModelMap map)
{
map.put("name", name);
map.put("age", age);
return "samplePath";
}
1.2 @RequestParam
단일 HTTP 요청 파라미터를 메소드 파라미터에 넣어주는 애노테이션이다.
ex) http://[ip]/test?name=주현태&age=30 으로 요청할 경우
@RequestMapping(value="/test")
public String pathVariableSample(@RequestParam("name") String name,
@RequestParam("age") int age, ModelMap map)
{
map.put("name", name);
map.put("age", age);
return "samplePath";
}
1.3 @CookieValue
HTTP 요청과 함께 전달된 쿠키 값을 메소드 파라미터에 넣어주도록 @CookieValue를 사용할 수 있다.
ex) 쿠키에들어있는 auth값을 읽어올 경우
@RequestMapping(value = "/test")
public String pathVariableSample(@CookieValue(value = "auth", required = false,
defaultValue = "NONE") String auth) {
map.put("auth", auth);
return "sampleAuth";
}
1.4 @RequestHeader
요청 헤더 정보를 메소드 파라미터에 넣어주는 애노테이션
ex) Accept-Encoding 헤더 정보를 읽어올 경우
@RequestMapping(value = "/test")
public String pathVariableSample(@RequestHeader("Accept-Encoding") String encoding, ModelMap map) {
map.put("encoding", encoding);
return "samplePath";
}
1.5 @ModelAttribute
도메인 오브젝트나 DTO의 프로퍼티에 요청 파라미터를 바인딩해서 한 번에 받는 경우
ex) http://[ip]/test?name=주현태&age=30로 요청할 경우 User 객체에 자동으로 매핑이 된다.
[User.java]
@Data
public class User {
int id;
String name;
int age;
}
[Controller]
@RequestMapping(value = "/test")
public String pathVariableSample(@ModelAttribute User user) {
user.setAge(29);
return "samplePath";
}
[결과]
1.6 @RequestBody
요청받은 HTTP의 body부분이 전달된다. 보통 ajax통신에서 자주 쓰인다고 함.
ex) post요청으로 폼에 a=b, c=d 의 값을 전달하였을 경우
@RequestMapping(value = "/test", method = RequestMethod.POST)
public String pathVariableSample(@RequestBody String body) {
System.out.println(body);
return "home";
}
[결과]
2. 리턴시 사용되는 어노테이션
2.1 @ModelAttribute
메소드 파라미터중에서 @ModelAttribute를 붙인 오브젝트라면 자동으로 컨트롤러가 리턴하는 모델에 추가됨
ex)
바인딩되어 넘어온 user도 그대로 모델로 리턴이 됨
@RequestMapping(value = "/test")
public String pathVariableSample(@ModelAttribute User user) {
user.setAge(29);
return "samplePath";
}
2.2 @ModelAttribute 메소드
@ModelAttribute가 붙은 메소드는 클래스안에 정의하지만 컨트롤러의 기능은 담당하지 않고 다른 컨트롤러 메소드의 모델에 자동 추가되는 기능이 있다.
ex) 아래와 같이 코드를 실행하면 user라는 이름으로 모델이 등록이 된다.
@RequestMapping(value = "/test")
public String pathVariableSample() {
user();
return "samplePath";
}
@ModelAttribute("user")
public User user() {
User user=new User();
user.setName("terry");
user.setAge(30);
return user;
}
2.3 @ResponseBody
@ResponseBody가 메소드 레벨에 부여되면 메소드가 리턴하는 오브젝트는 뷰를 통해 결과를 만들어내는 모델로 사용되지 않고 메시지 컨버터를 통해 HTTTP 응답의 메시지 본문으로 전환된다.
@RequestMapping(value = "/test")
@ResponseBody
public String pathVariableSample() {
return "hello";
}
[결과]
2.4 @SessionAttributes
@SessionAttributes의 기능
-
컨트롤러 메소드가 생성하는 모델정보 중에서 @SessionAttributes에 지정한 이름과 동일한 것이 있다면 이를 세션에 저장해준다.
-
@ModelAttribute가 지정된 파라미터가 있을 때 이 파라미터에 전달해줄 오브젝트를 세션에서 가져오는 것.
ex)
@Controller
@SessionAttributes("user")
public class HomeController {
@Autowired
UserDao userDao;
@RequestMapping(value = "/user/edit", method = RequestMethod.GET)
public String pathVariableSampleGET(@RequestParam int id, Model model) {
model.addAttribute("user", userDao.getUser(id));
return "samplePath";
}
@RequestMapping(value = "/user/edit", method = RequestMethod.POST)
public String pathVariableSamplePOST(@RequestParam int id, Model model) {
model.addAttribute("user", userDao.getUser(id));
return "redirect:/user/edit";
}
}
위에 나와있는 파라미터와 리턴타입에 나와있는 어노테이션의 용도를 잘 이해하고 사용하면 Controller내의 소스코드의 양이 상당히 줄어들 것으로 예상되므로 항상 숙지해두도록 하자.