애너테이션과 함께 ModelAttribute를 사용해주면 자동으로 모델안에 저장이 된다
매개변수에 저장이 가능하고 반환타입에도 저장이 가능하다
우선 매개변수에 적용하는 것을 알아보자
위 이미지처럼 앞에 써주게 되면 MyDate date 가 자동으로 모델안에 저장이 된다
MyDate라는 타입의 첫 글자를 소문자로 해서 자동으로 myData라는 키값을 지정한다
그림과 함께 보면 Model m은 이미지처럼 Key Value 형태로 존재한다
앞에서 애너테이션을 사용해줬기 때문에 MyDate의 date는 자동으로 키값 벨류값으로 저장이 될 것이다
그렇기 때문에 하단에서 m.addAttribute("myDate", date); 이런식으로 작성해줄 필요가 없다
자동으로 저장이 되기 때문인데 MyDate라는 타입을 저장할때는 첫글자를 소문자로해서 저장하게 되는데
myDate가 되어서 키에 저장되고 그 뒤에 date 객체가 벨류가 되어 저장이 된다
원래대로면 위 초록색문장처럼 키를 따로 적어줘야하는데 생략이 가능하다 생략하면
첫글자를 소문자로해서 저장하게 된다
내가 저장할 수 도 있고 자동으로 할 수도 있고 그건 선택하기 나름이다
위 방식이 매개변수에 저장하는 방식이다
이제는 반환 타입에 저장하는 방법을 알아보자
char이라는 반환타입앞에 어노테이션을 붙여줘서 적용할 수도 있다
그러면 키값이 "yoil"이 되는 것이고 호출결과가 value안에 들어가게 되는데
호출결과가 예를 들어 수라고 하면 key = "yoil" value=수
이렇게 되는 것이다
내부적으로 어떻게 돌아가냐하면
컨트롤러의 메서드들 중에 해당 애너테이션이 붙어있는지 확인하고
붙어있는 것들은 전부다 호출을 해서 그 결과를 모두 모델에 저장해준다
우리는 그 결과로 호출도 저장도 하지 않아도 되는 편리한 점이 있다
예시코드를 보면서 설명을 덧붙여보면
package com.fastcampus.ch2;
import java.util.Calendar;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class YoilTellerMVC5 {
@ExceptionHandler(Exception.class)
public String catcher(Exception ex) {
System.out.println("ex="+ex);
return "yoilError";
}
@RequestMapping("/getYoilMVC5") // http://localhost/ch2/getYoilMVC5?year=2021&month=10&day=1
// public String main(@ModelAttribute("myDate") MyDate date, Model m) { // 아래와 동일
public String main(@ModelAttribute MyDate date, Model m) { // @ModelAttribute사용, 반환 타입은 String
System.out.println("myDate="+date);
// 1. 유효성 검사
if(!isValid(date))
return "yoilError";
// 2. 처리
// char yoil = getYoil(date);
// 3. Model에 작업한 결과를 저장
// @ModelAttribute 덕분에 MyDate를 저장안해도 됨. View로 자동 전달됨.
// m.addAttribute("myDate", date);
// m.addAttribute("yoil", yoil);
// 4. 작업 결과를 보여줄 뷰의 이름을 반환
return "yoil";
}
private @ModelAttribute("yoil") char getYoil(MyDate date) {
return getYoil(date.getYear(), date.getMonth(), date.getDay());
}
private char getYoil(int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, day);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
return " 일월화수목금토".charAt(dayOfWeek);
}
private boolean isValid(MyDate date) {
return isValid(date.getYear(), date.getMonth(), date.getDay());
}
private boolean isValid(int year, int month, int day) {
if(year==-1 || month==-1 || day==-1)
return false;
return (1<=month && month<=12) && (1<=day && day<=31); // 간단히 체크
}
}
주석처리를 한 곳을 집중적으로 보자
매개변수와 반환타입에 모두 애너테이션을 붙여줌으로써 주석처리한 곳의 코드를 쓰지 않아도
실행하면 잘 출력되는 것을 확인 할 수 있다
이로인해 코드가 훨씬 간결해지고 사용성에도 편리함이 더해지는 것이다
이렇게 출력이 잘 되고 있다
참조형 매개변수 앞에 애너테이션을 붙여서 사용해야한다고 설명을 했지만
사실 적지않아도 된다 생략이 가능하다
위에서 생략을하고 아래에 주석한 것을 그대로 주석처리해도 사용할 수 있다
컨트롤러 매개변수에 붙을 수 있는 애너테이션은 2개가 있는데
앞서 포스팅에서 설명했던 @RequestParam 그리고 지금 설명하고 있는 @ModelAttribute 2가지 이다
타입이 참조형일 경우에는 Model애너테이션을 생략할 수 있다고 보면되고
기본형일 경우 RequestParam을 생략했다고 보면된다
참조형일 경우 RequestParam을 붙일 수 없다 왜냐면 여러개 값이 바인딩되기 때문인데
기본형이나 String인 경우에 모델에 저장할 필요가 없다
왜냐면 view에서 바로 쓸 수 있기 때문인다 ${param.파라미터이름} 이렇게 바로 참조가 가능하기 때문이다
다음으로 WebDataBinder라는 것에 대해 알아보려고 한다
위 이미지처럼 getYoilMVC5를 호출했을 때 쿼리스트링 뒤에 있는 데이터가 맵 형태로 저장이 되는데
그 값이 컨트롤러 메서드한테 전달이 될 텐데 MyDate타입의 객체는 int이다
쿼리스트링으로 요청받은 값들을 객체에 채워줘야하는데 스트링 값을 int로 넣기위해 변환을 해줘야하는데
그게 바로 DataBinder인데 웹에서 구동하니까 웹데이터바인더라고 한다
중간에서 바인더가 값들을 받아서 첫번째로 타입변환을 통해서 결과와 에러를 BindingResult안에 저장한다
그리고 데이터를 검증(Validation)을 하는데 예를 들어 년월일에서 월은 1~12까지만 들어가야하고 일은 1~31까지만 들어가야한느데
day에 44라고 값이 들어왔다고해서 형변환을 하고 44를 넣게되면 최대 31까지 쓰이는 day를 초과하는 값이 들어오기 때문에
데이터 검증을 통해서 결과와 에러를 또 한번 BindingResult에 저장을 한다
그렇게 나온 결과와 에러를 웹바인더가 컨트롤러한테 넘겨줄 수 있다
그 값을 전달받아서 컨트롤러는 그 값을 처리할 수 있게 되는데
바인딩할 객체가 있다면 BindingResult는 해당 객체 바로 뒤에 작성되야한다
'BackEnd' 카테고리의 다른 글
@GetMapping 과 @PostMapping (0) | 2022.12.22 |
---|---|
URL 호출 시 경로설정 편리하게 하기 (0) | 2022.12.21 |
@RequestParam 에 대한 정리 (0) | 2022.12.18 |
서블릿과 JSP(4) - JSTL(JSP Standard Tag Library) (0) | 2022.12.17 |
서블릿과 JSP-(3) URL 패턴 (0) | 2022.12.17 |