Spring

[Spring] 스프링 파헤쳐보기 - ViewResolever, Model

무모한 폴라베어 2021. 5. 27. 21:13

 

 

 

 

 

 

 

 

저번에 이어서 이번에는 ViewResolver 부분과 Model 부분에 대해서 공부할 차례이다.

 

 

 

 

 

ViewResolver

 

저번에 DispatcherServlet에 대해서 공부하면서 비즈니스 로직의 처리하고 결과를 View와 ViewResolver가 준다는 것을 알았다. 

ViewResolver는 DispatcherServlet이 WebApplicationContext에 적재할 빈들의 정보를 읽는 Servlet-context.xml에 정의되어있다.

InternalResourceViewResolver를 빈으로 가지고 prefix에서 설정하는 값 +  컨트롤러에서 주는 값 + suffix를 합친 경로에서 view를 찾는다. 

 

 

Model

 

클라이언트 부분에서 요청을 받고 DispatcherServlet이 그 요청을 처리할 컨트롤러를 HandlerMapping 이 찾아서 넘기면 컨트롤러는 비즈니스 로직을 통해서 요청을 처리한다. 그 결과는 위에 있는 ViewResolver에 넘기는데 여기서 Model 객체를 사용한다.

 

Model 객체는 컨트롤러의 비즈니스 로직을 통해서 받은 데이터를 view로 전달할때 사용하는데 내부에 있는 addAttribute 메서드를 통해서 key - value 형태로 값을 임시저장한다. 그리고 view에서는 여기서 저장한 데이터의 key 값으로 데이터를 사용한다.

 

package org.springframework.ui;

import java.util.Collection;
import java.util.Map;

import org.springframework.lang.Nullable;

public interface Model {

	/**
	 * 제공된 이름에 제공된 값을 더함
	 * @param attributeName - 모델 요소의 이름 (never {@code null})
	 * @param attributeValue - 모델 요소의 값 (can be {@code null})
	 */
     
	Model addAttribute(String attributeName, @Nullable Object attributeValue);

	/**
	 * 빈 컬렉션은 더해지지 않는데 왜냐면 정확한 관습적으로 명명하는 이름을 정의할수없기 때문
	 * view 코드는 이미 JSTL 태그에서 수행 한 것처럼 빈 컬렉션이 아닌 null을 확인해야합니다.
	 * @param attributeValue - 모델 요소의 값 (never {@code null})
	 */
	Model addAttribute(Object attributeValue);

	/**
	 * 각 요소에 대한 속성 이름 생성을 사용하여 제공된 콜렉션의 모든 속성을 이 맵에 복사
	 * @see #addAttribute(Object)
	 */
	Model addAllAttributes(Collection<?> attributeValues);

	/**
	 * 제공된 맵의 모든 속성을 이 맵에 복사
	 * @see #addAttribute(String, Object)
	 */
	Model addAllAttributes(Map<String, ?> attributes);

	/**
	 * 제공된 맵의 모든 속성을 이 맵에 복사하는데 같은 이름을 가진 객체를 우선 복사
	 */
	Model mergeAttributes(Map<String, ?> attributes);

	/**
	 * 모델이 주어진 이름을 가진 요소를 가지고 있는지 체크
	 * @param attributeName - 모델 요소 이름 (never {@code null})
	 * @return 모델이 값을 가지고 있는지 아닌지 여부
	 */
	boolean containsAttribute(String attributeName);

	/**
	 * 주어진 이름에 해당하는 값을 리턴
	 * @param attributeName - 모델 요소 이름 (never {@code null})
	 * @return 일치하는 값, 없다면 none
	 * @since 5.2
	 */
	@Nullable
	Object getAttribute(String attributeName);

	/**
	 * 현재 모델 속성 세트를 맵으로 리턴
	 */
	Map<String, Object> asMap();

}

 

  여러가지 메서드가 있지만 보통 addAttrubute로 값을 저장하고 view에서 받는 방식을 가장 많이 사용하는 것 같다. 직접 model 객체를 생성하지 않고 파라미터로 선언만 해주면 스프링이 알아서 만들어 준다는 점이 편하다.

 

혹은 이렇게 Model 객체를 생성해서 값을 담는 방법 말고 @ModelAttribute(key) 어노테이션을 통해서 객체의 이름과 값을 바로 넘길 수도 있다. 전역적인 값을 설정할 때 사용하면 좋을 것 같다.

 

 

 

ModelAndView

 

Model 과는 다르게 클래스로 구현되어있어서 직접 객체를 생성해서 사용해야하는데 이름처럼 Model과 view를 모두 저장할 수 있는 객체이다. 생각보다 코드가 길어서 Model처럼 올리진 않고 주요 메서드 정도만 정리해보면

 

view 관련 메서드 : setViewName, getViewName, setView, getView

model 관련 메서드 : addObject

 

그리고 생성해준 ModelAndView 객체를 리턴해주면 Model 과 View를 모두 사용할 수 있다.

 

 


 

Spring은 프레임워크라서 자바 같은 언어의 깊이가 상대적으로 덜하지 않을까? 라고 생각했었는데 이 역시 방대한 영역이다..... 그래도 요청과 응답에 대한 전체적인 흐름은 익혔으니 일단은 요정도에서 만족하고 다음번에 또 다른 주제가 생기면 올 예정이다.