main2 메서드의 매개변수인 String year 부분은 원래 @RequestParam(name="year", required=false)부분이 생략된 것이다. year는 파라미터이름이고 required는 필수여부이다.
요청시 year를 적어주지 않는다면 year값은 null이 입력되고 year만 적어준다면 빈 문자열이 자동 입력된다. 만약 컨트롤러의 매개변수에 @RequestParam을 적는다면 (@RequestParam String year), (@RequestParam(name="year", required=true) String year)와 동일하다. required가 true이므로 요청시 year를 적어주지 않는다면 null로 전달되서 클라이언트 에러가 발생한다. year만 적어준다면 빈 문자열을 전달하기때문에 이때는 에러가 발생하지 않는다.
위에 main8 메서드에서 required는 false이지만 year값을 전달할 때 year를 요청해주지 않는다면 year에는 null이 저장되고 null은 int로 변환되지 않으므로 서버에서 처리해주어야 한다. 그러므로 500대 에러가 발생한다. main8 메서드에서 year값을 전달해주어도 빈 문자열을 전달하므로 int형으로 변환되지 않는다. 여기서는 사용자가 값을 잘못전달해주었으므로 400대 클라이언트 에러가 발생한다. 이를 막기위해 required가 false인 경우는 defaultValue로 기본값을 주어야 한다.
위 코드에서 year값을 전달해주지 않는다면
year는 자동 null값을 출력한다.
위 코드에서는 year만 전달해주면 빈 문자열을 화면에 출력한다.
위 코드에서 requestParam8과 매핑하면 에러메시지가 출력된다. 그 이유는 required가 false인데 defaultValue를 설정해주지 않아서이다.
defaultValue값을 설정해주면 다음과 같이 나온다.
요청에서는 year값을 전달해주지 않았기때문에 year=null값이 나온다.
하지만 콘솔창을 보면 year에 2021이 담겨져있는 것을 확인할 수 있다.
required=true일때는 예외처리를 해줘서 사용자가 올바른값을 입력할수 있도록 해주는 것이 좋다.
--------------------예외처리코드------------------------------
매개변수가 많을 때는 새로운 클래스를 생성해서 위와 같이 쓸 수 있다.
MyDate클래스에서 get/set메서드를 통해 값을 준다.
위 코드에서 @ModelAttribute를 적용한 date 객체가 Model에 자동저장된다. 그러므로 아래 m.addAttribute메서드를 사용할 필요가 없다.
위에서 @ModelAttribute("myDate")에서 myDate를 생략하면 자동으로 첫글자를 소문자로한 myDate를 자동으로 Model의 키 값에 저장해준다.
위 코드에서 반환타입 char에 @ModelAttribute("yoil")을 붙이면 자동으로 모델에 키가 yoil로 저장해주므로 위에서 char yoil = getYoil(date); 가 필요하지 않아져서 코드가 간결해진다.
컨트롤러의 매개변수에 @ModelAttribute를 생략해도 적용된다.
매개변수 타입이 기본형이거나 String이면 @RequestParam을 생략했다고 볼 수 있고, 참조형일때는 @ModelAttribute를 생략했다고 볼 수 있다. 기본형이나 스트링같은 경우는 모델에 저장할 필요가 없다. 그 이유는 ${param. 파라미터이름}으로 값을 받을 수 있기 때문이다. 그러므로 기본형, 스트링같은 경우는 모델을 사용하지 않는다.
위 그림에서 year, month, day 값을 스트링형으로 받는데 MyDate 객체에서는 int형으로 저장해주어야 한다. 이 중간에서 변환해주는 역할을 하는 것이 WebDataBinder이다.
WebDataBinder에서 타입변환, 데이터검증을 마친 바인딩된 결과를 BindingResult에 담고 그 값을 컨트롤러에 넘겨준다. BindingResult는 바인딩할 객체의 바로 뒤에 와야한다.
개발자로서 배울 점이 많은 글이었습니다. 감사합니다.