1. @ModelAttribute
(1)기능
@ModelAttribute가 붙어 있는 적용 대상을 자동으로 모델의 어트리뷰트로 넣어준다.
(2) 적용 대상
a. Controller Method의 매개 변수
// 매개변수 앞에 붙는다.
public String main(@ModelAttribute MyDate date, Model m) { /... }
//public String main(@ModelAttribute("myDate") MyDate date, Model m) {/...}
밑의 주석도 위와 동일한 뜻이다. 어노테이션 뒤 ()에 Model 의 Key 값으로 쓰일 이름을 지정해 넣을 수 있다.
이는 생략 가능하며, 생략하면, 클래스의 첫글자를 소문자로 한 문자열이 Key 값이 된다.
Model안에 Attribute 저장하는 Map | |
Key | Value |
mydate | date 객체의 주소 |
//... | //... |
이런 식으로 들어간다.
b. 일반 Method
// 매소드의 반환형 앞에 붙는다.
// 해당 매소드의 반환값은 무조건 모델의 어트리뷰트로 들어간다는 뜻이다.
// 이 경우에는 Model의 Map 속 Key로 쓰일 값을 무조건 적어줘야 한다.
private @ModelAttribute ("yoil") char getYoil(MyDate date) {
return getYoil(date.getYear(), date.getMonth(), date.getDay())
}
이 경우 ()안에 적은 값이 Key가 되고 해당 매소드의 호출 결과가 Value로 저장된다.
Model의 Map | |
Key | Value |
yoil | getYoil에 date 객체 넣었을 때 반환 값 |
c. 해당 어노테이션으로 생긴 코드의 경제성
// 1. 모델 객체를 컨트롤러 매소드의 매개변수로 받을 필요가 없다!
// >> 어짜피 @ModelAttribute 어노테이션이 자동으로 모델에 다 값을 저장해주기 때문이다.
public String main(@ModelAttribute MyDate date) {
if(!isVaild(date)) {
return "yoilError";
}
//2. 어노테이션을 일반 매소드 반환형 앞에 쓴 경우 이 코드는 필요가 없다.
// @ModelAttribute("yoil") getYoil(...){...}은 밑의 과정을 포함한다.
// char yoil = getYoil(date);
//3. 어노테이션의 자동 값 저장 능력으로 해당 코드들이 필요 없어졌다.
// model.addAttribute("myDate",date);
// model.addAttribute("yoil", yoil);
return "yoil";
}
private @ModelAttribute("yoil") char getYoil(MyDate date) {
return getYoil(date.getYear(), date.getMonth(), date.getDay());
}
(3) 어노테이션을 생략 가능한 경우
참조형 변수의 경우 @ModelAttribute를 생략 가능하다.
// public String main( @ModelAttribute("mydate")MyDate date) 아래와 동일
public String main(MyDate date) {
따라서 그냥 참조형 변수 선언만 해도 Spring FrameWork가 알아서 값을 Map에 저장시켜준다.
**참고**
기본형이나 String 매개변수일 경우 앞에 @RequestParam 어노테이션이 생략되어 있었다.
해당 어노테이션을 안 적어도 스프링 프레임워크가 자동으로 요청의 파라미터와 기본형,String 매개변수를 Binding 해줬다.
참조형일 경우 앞에 @ModelAttribute가 생략되어 있어서 자동으로 참조형 변수 값을 Model의 Map에 저장시켜 줬다.
이러한 차이가 있는 이유가 무엇일까?
먼저, 기본형이나 String 매개변수는 모델에 넣을 이유가 없다.
왜냐면, View 또한 요청의 parameter에 접근할 수 있기 때문이다. 요청의 파라미터는 입력 부분에 있기 때문에 Controller든 view든 직접 사용할 수 있다. 따라서 모델에 넣을 필요가 없다.
반면 참조형 변수 (ex - 객체)는 입력에 존재하지 않고, 컨트롤러 영역에 존재하는 녀석이다. 따라서 View에서도 해당 변수들을 사용하려면, 컨트롤러와 View의 매개체인 Model에 꼭 있어야한다.
SpringFramWork는 이를 고려하여 편의를 제공한 것이다.
2. WebDataBinder
(1) 기능
WebDataBinder는 요청의 파라미터를 컨트롤러 매서드의 매개변수와 연결할 때 작동하는 녀석이고, 2가지 기능을 한다.
첫 번째는 형 변환이다. String으로 들어온 값들을 컨트롤러 매서드의 매개변수에 맞게 형 변환 시켜준다. 이때의 결과와 에러를 BindingResult란 클래스의 객체에 저장한다.
두 번째는 데이터 검증이다. 이는 데이터가 유효한 값인지 검사하는 것이다. 위에서 예를 들어 month는 1~12까지만 가능하다. 이때 month =34가 들어온다면 이는 유효하지 않은 값이다.
데이터 검증 결과와 발생한 에러도 BindingResult의 객체에 저장한다.
(2) 코드 리뷰
//BindingResult의 객체는 예외처리 매서드의 매개변수로도 쓰일 수 있다.
@ExceptionHandler(Exception.class)
public String Catcher (Exception ex, BindingResult result) {
System.out.println("result="+result);
//BindingResult 안의 변수 중 하나인 error 객체를 활용하여
// 어떤 에러고 어디서 발생했는지 확인한다.
FieldError error = result.getFieldError();
System.out.println("code="+error.getCode());
System.out.println("field="+error.getField());
System.out.println("msg="+error.getDefaultMessage());
ex.printStackTrace();
return "yoilError";
}
//원래 BindingResult는 컨트롤러 매서드에서 처리한다.
// 여기서는 URL을 직접 치고 들어와서 생기는 에러는
// 컨트롤러까지 안가고 예외처리 부분에서 catch 해서 처리한다.
// 위치는 항상 검사 당하는 매개변수들보다 뒤이다.
@RequestMapping("/getYoilMVC6")
public String main(MyDate date, BindingResult result) {
System.out.println("result= " + result);
if(!isVaild(date)) {
return "yoilError";
}
return "yoil";
}
3. 스스로 해보기
yoilMVC5, yoilMVC6 없애고 yoilMVC4로 새로 만들어봄.
'백엔드 개발 > SpringMVC' 카테고리의 다른 글
@ 어노테이션 전문화, view Controller, Redirection (0) | 2023.03.04 |
---|---|
회원 가입 화면 작성하기 (0) | 2023.03.03 |
@RequestParam과 컨트롤러 매개변수 깔끔정리하기 (0) | 2023.03.02 |
JSP와 서블릿(4) (0) | 2023.03.02 |
서블릿과 JSP(3) (0) | 2023.03.01 |