[Spring] MVC model 1, 2 - 개념 및 설계구조
2019. 5. 17. 00:44ㆍSpring
MVC model 1
- 사용자로부터 받은 REQUEST 화면을 처리하는 기능을 SERVICE라 칭하고,
해당 SERVICE를 수행할 때 필요한 데이터베이스를 찾아가는 역할은 DAO가 수행한다. - 하지만 하나의 문서에 HTML과 JAVA 소스가 함께 작성되어 유지보수나 협업 시 어려움이 발생하는 단점이 있다.
MVC model 2
- 컨트롤러가 요청을 받고, 그에 맞는 SERVICE를 연결한다. 일종의 모듈화로써 여러 컨트롤러들이 같은 요청을 받는 경우 해당 서비스를 공유하며 사용한다.
- MODEL1과 동일하게 DAO를 활용하여 DB에 접근하나 이또한 각각의 기능을 공유할 수 있도록 모듈화한다.
- 각각의 기능들이 분리되어 있어 유지보수가 용이하고, 협업 시 작업 영역이 겹치지 않는 장점이 있어 거의 모든 웹 프로젝트는 해당 MODEL 2 방식을 사용하고 있다.
SPRING MVC FRAMEWORK 설계구조
- 클라이언트로 부터 요청을 받고 그 요청이 어떤 컨트롤러와 매핑할 것인가를 HANDLER MAPPING 이 선택하며,
선택된 컨트롤러의 어떤 메서드를 실행할지 HANDLER ADAPTER가 판별하여 DISPATCHER SERVLET 에게 회신한다. - 최종선택 된 메서드가 실행되고 결과값으로 MODEL을 받은 후 어떠한 VIEW에 연결할 것인지 VIEW RESOLVER가 체크하여 데이터를 VIEW에 입혀주고 최종적인 화면을 클라이언트에게 돌려준다.
DISPATCHER SERVLET 설정
- 웹 어플리케이션의 첫 관문으로 전체적인 웹 프로그램의 설정을 책임진다.
- WEB-INF/web.xml 의 파일에 springframework 패키지 안에있는 DispatcherServlet 클래스를 참조한다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- log4J -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/config/log4j.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
- 루트 경로에 들어온 모든 요청을 처리하도록 기본 설정되어 있으며,
이 위치에서 filter 태그를 이용하여 페이지에서 처리되는 글자의 charset을 정하거나
스프링 컨테이너의 위치, log4j의 경로 등의 전반적인 웹 프로그램의 환경설정을 책임진다. - (스프링 컨테이너를 설정하지 않은 경우 기본적으로 appServlet-context.xml을 참조하게 된다.)
- DISPATCHER SERVLET이 HANDLER ADAPTER를 통해 CONTROLLER를 찾기 위해서는
아래의 그림처럼 어노테이션을 읽어내는 용도의 태그를 servlet-context.xml에 정의해야한다.
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
- DISPATCHER SERVLET이 HANDLER ADAPTER를 통해 CONTROLLER를 찾기 위해서는
아래의 그림처럼 어노테이션을 읽어내는 용도의 태그를 servlet-context.xml에 정의해야한다. - 이후 컨트롤러를 찾기위해 HANDLER ADAPTER는 각 컨트롤러 파일들을 탐색하며 매핑시켜줄 컨트롤러를 찾는다.
@Controller
@RequestMapping("/member/")
public class LoginController {
Logger log = Logger.getLogger(this.getClass());
@Resource
private CustomerService memberService;
@RequestMapping(value={"", "/", "/login"})
public String login() {
return "member/login";
}
- 위 처럼 member로 요청된 모든 요청을 해당 컨트롤러가 처리하겠다고 어노테이션을 설정해주면 핸들러 어댑터가 이 컨트롤러를 찾게 된다.
[ 로컬 서버에 /member/login 으로 요청하였을 때, loginCheck 페이지로 매핑된 화면 ]
- 아래의 고객정보 리스트는 하드코딩되어진 값이 아닌 데이터베이스를 조회하여 얻어낸 데이터인데
이때 이러한 데이터들을 컨트롤러로부터 뷰가 받기 위해선 모델이라는 역할이 필요하다. - model은 controller에서 직접 키, 값의 쌍으로 데이터를 셋팅해주고 view로 보내게 되는데,
model에 값을 담아 지정된 뷰로 보내는 과정이 항상 반복되어지기 때문에 이를 ModelAndView 객체를 사용하여 처리할 수 있다.
@RequestMapping(value={"loginCheck","memberList"}, method=RequestMethod.POST)
public ModelAndView loginCheck(@ModelAttribute Customer customer, HttpSession session) throws Exception {
ModelAndView mav = null;
int rtn = 0;
try {
mav = new ModelAndView();
rtn = memberService.selectLoginCheckCustomer(customer);
} catch (Exception e) {
e.printStackTrace();
}
if(rtn < 1){
mav.setViewName("member/login");
mav.addObject("resultMsg", "failure");
return mav;
}else{
return memberList();
}
}
[ loginCheck 으로 요청이 들어온 경우 mav라는 객체를 만들어 매핑할 데이터와 뷰를 한번에 리턴시켜 처리하는 화면 ]
- 이때 list 라는 값을 member/login 뷰에 넘겨주게 되는데 login이라는 뷰의 경로는
아래 설정을 통해 /WEB-INF/views/member/login.jsp 라는 경로를 완성시킨 후 전달한다.
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
'Spring' 카테고리의 다른 글
리다이렉트, 인터셉트 (0) | 2019.05.16 |
---|---|
세션, 쿠키 (0) | 2019.05.16 |
DI(Dependency injection) (0) | 2019.05.16 |