- 관심사의 분리, MVC 패턴

 

1. 관심사의 분리 Separation of Concers

관심사 = 해야 할 작업

 

코드 분리 point  1. 관심사 2. 변하는 것, 자주 변하지 않는 것 3. 공통 코드(중복)

 

2. 공통 코드의 분리  입력의 분리

입력 부분을 매개변수로 처리함

 

3. 출력(view)의 분리  변하는 것과 변하지 않는 것의 분리

 

 

4. MVC 패턴

MVC 패턴 : Model, View, Controller 의 처리 방식

 

요청을 받으면 DispatcherServlet이 입력처리를 하여 Model(결과를 저장할 객체)을 만들어 Controller에게 전달하고, Controller가 처리를 해서, Model에 데이터를 담아서 다시 DispatcherServlet으로 보낸다. DispatcherServlet은 작업 결과가 담긴 Model View에 전달하고, View에서 작업 결과를 읽어서 응답을 만들어내서 클라이언트에게 전송함.

5. ModelAndView

Model View가 객체에 함께 저장됨.

 

6. 컨트롤러 메소드의 반환타입

 

[String] : 뷰 이름을 반환

[void] : 맵핑된 url의 끝단어가 뷰 이름

[ModelAndView] : Model과 뷰 이름을 반환

 

 

 

 

1. @RequestParam

요청의 파라미터를 연결할 매개변수에 붙이는 애너테이션

	@RequestMapping("/requestParam2")
//	public String main2(@RequestParam(name="year", required=false) String year) {   // 아래와 동일 
	public String main2(String year) {   
//		http://localhost/ch2/requestParam2         ---->> year=null
//		http://localhost/ch2/requestParam2?year    ---->> year=""
		System.out.printf("[%s]year=[%s]%n", new Date(), year);
		return "yoil";
	}

매개변수에 @RequestParam이 생략되어 있다.

name은 파라미터 이름, required는 파라미터의 필수여부를 의미한다.

 

 

	@RequestMapping("/requestParam3")
//		public String main3(@RequestParam(name="year", required=true) String year) {   // 아래와 동일 
		public String main3(@RequestParam String year) {   
//		http://localhost/ch2/requestParam3         ---->> year=null   400 Bad Request. required=true라서 
//		http://localhost/ch2/requestParam3?year    ---->> year=""
		System.out.printf("[%s]year=[%s]%n", new Date(), year);
		return "yoil";	
	}

이번엔 required=true 이므로 @RequestParam을 붙여줘야 하고 year를 필수로 입력해야 한다.

입력하지 않으면 클라이언트 에러가 발생함(400번대)

 

 

@RequestMapping("/requestParam8") 
	public String main8(@RequestParam(required=false) int year) {   
	//	http://localhost/ch2/requestParam8        ---->> 500 java.lang.IllegalStateException: Optional int parameter 'year' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
	//	http://localhost/ch2/requestParam8?year   ---->> 400 Bad Request, nested exception is java.lang.NumberFormatException: For input string: "" 
		System.out.printf("[%s]year=[%s]%n", new Date(), year);
		return "yoil";
	}

필수입력이 아니므로(required = false) parameter에 아무것도 주지 않으면 year 는 null이 되고, null을 int로 변환할 수 없어서 500번대 Error가 발생함

 

이번엔 parameter에 year는 적었기 때문에 빈 문자열인 ""가 들어가게 되고, ""을 int로 변환할 수 없기 때문에 400번대 Error가 발생함(클라이언트가 잘못된 값을 입력했기 때문)

 

 

그래서, 필수입력이 아닐 때는 다음과 같이 기본값을 줘야함

@RequestMapping("/requestParam11")   
	public String main11(@RequestParam(required=false, defaultValue="1") int year) {   
//		http://localhost/ch2/requestParam11        ---->> year=1   
//		http://localhost/ch2/requestParam11?year   ---->> year=1   
		System.out.printf("[%s]year=[%s]%n", new Date(), year);
		return "yoil";
	}

빈 문자열이나 null일 때 기본값(defaultValue)이 들어가게 됨.

 

 

2. @ModelAttribute

적용 대상을 Model의 속성으로 자동 추가해주는 애너테이션

반환 타입 또는 컨트롤러 메소드의 매개변수에 적용 가능

 

컨트롤러 메소드의 매개변수에 @ModelAttribute 애너테이션을 붙이면

Model에 따로 값을 저장하지 않아도 자동으로 저장이 된다.(타입의 첫 글자를 소문자로 해서 저장)

 

그리고 getYoil 메소드에 @ModelAttribute 애너테이션을 붙이면

처리 작업을 따로 하지 않아도 되고 Model에 역시 자동으로 저장이 된다.

 

 

* 컨트롤러의 매개변수에 붙는 애너테이션 2가지, @RequestParam, @ModelAttribute 가 있는데

참조형 매개변수에는 ModelAttribute가 생략되었고

기본형 매개변수와 String인 경우에는 RequestParam이 생략되어있다고 보면 된다.

 

 

3. WebDataBinder

브라우저를 통해서 요청받은 값이 실제 객체에 바인딩 될 때 중간역할을 해주는게 WebDataBinder이다.

WebDataBinder는 2가지 작업을 하는데

먼저 타입 변환을 하고, 그 다음 데이터 검증을 하여 그 결과를 BindingResult에 저장한다.

BindingResult를 컨트롤러에 전달하여 컨트롤러가 그 결과를 볼 수 있도록 해준다.

 

 

 

 

<c:url>이 하는 일은 2가지가 있는데,

1. context root를 자동 추가(이 경우 /ch2를 추가해줌)

2. session id를 자동 추가

+ Recent posts