본문 바로가기
Web/Spring

Spring MVC(1)

by 미티치 2016. 5. 16.

『 목차 』
- Spring MVC 개요

- Spring MVC 프로젝트 생성방법

- Spring MVC 구조

- Spring MVC 기본 프로젝트 구조

 


 

 

 

Spring을 이용한 MVC2패턴 ( 요즘은 MVC패턴이라고 하면 정확하게는 MVC2패턴이다. ) 에 대해 공부해보자 :-)

 

 

 

■ Spring MVC 개요

 

스프링이 유명하게 된 계기는 아마도 웹 애플리케이션 제작에 적용되면서 웹 프레임워크로서의 우수성이 인정되었기 때문일 것입니다.

우선, 스프링 MVC 프로젝트를 생성하는 방법부터 정리해봅시다!

 

1 ) 이전에 스프링 프로젝트를 생성할때처럼 File - New - Spring Legacy Project 클릭!

 

2 ) 다음과 같은 화면에서 이전에 기본적인 스프링에 대해 공부할때는 Simple Spring Maven 또는 Simple Spring Web Maven을 선택했었지만 MVC패턴 스프링 프로젝트를 생성할 때는 Spring MVC Project 선택, Next 클릭

 

 

 

 

3 ) 프로젝트 세팅부분. 여기서 context name을 mvctest로 생성해줄건데, 여기서 주의할 부분은 패키지는 무조건 3단 이상으로!!!

3단계 미만으로하면 인식이 안된다. 이제 Finish!

 

 

 

 

 

■ Spring MVC 구조

 

스프링 MVC의 구조는 다음과 같다. Servlet & JSP를 이용해서 MVC2패턴을 짤때와 다른점이 보이나요?

Servlet & JSP에서는 Client가 호출하면 가장 먼저 Controller에서 Model과 View로 이어졌는데, Controller는 여러개 추가하여 사용하기 때문에 스프링에서는 제일 먼저 DispatcherServlet로 가서 Controller를 호출해준다.

 

 

 

스프링 MVC 프로젝트를 생성하면 기본적으로 MVC2패턴으로 프로젝트가 생성된다. 처음부터 이렇게 MVC패턴으로 만들어지기 때문에 우리가 이전에 Servlet & JSP에서처럼 일일이 컨트롤러며 액션이며 하나씩 다 만들어서 *.bo (게시판짤때)로 매핑해주고 다 연결해주는 수고를 하지 않아도 된다. 따라서 스프링 MVC 구조를 알지 못하면 만들수가 없다는 뜻이겠지?

 

- DispatcherServlet이 Client의 호출을 가장 먼저 받는다. 그럼 이 DispatcherServlet은 어디에있나?? 결론적으로 말하면 없다. 더 정확하게는 컨테이너가 호출을 받아서 Controller로 넘겨주기 때문에 Servlet & JSP에서는 Controller가 서블릿으로 존재(우리가 생성)했지만 스프링에서는 Controller 이전에 먼저 거치는 DispatcherServlet은 내부적으로 존재하기 때문에 눈에 보이는 파일이 아니다.

 

- DispatcherServlet에서 받은 호출을 Controller로 보내주고 Controller에서는 Model과 연동하여 전달값이 있으면 전달값을 가지고 View를 호출한다. 여기서 전달 값을 request뿐만 아니라 Model, ModelAndView를 이용해서 넘길 수 있다. 일단은 여기까지 알아두고 다음예제에서 각각 사용하는 방법을 보자.

 

- View는 호출되는 페이지이고, 그렇다면 ViewResolver는 무엇인가? 이것도 다음 예제에서 자세히 코드를 보아야 알겠지만 일단 정의하자면 컨트롤러가 리턴한 View 이름을 참고해서 적절한 View 오브젝트를 찾아주는 로직을 가진 오브젝트이다. 쉽게말해 View를 읽어주는 도구라고 생각하면 된다.

 

 예를들어 Servlet & JSP에서는 Client가 http://server/contextName/board/boardList.jsp 를 입력, 즉 BoardList.jsp를 호출하고 싶으면 Client는 boardList.bo를 호출한다. 서블릿이 매핑되어있는 web.xml에 *.bo가 BoardFrontController로 매핑되어 있기 때문에 BoardFrontController로 가고, BoardFrontController에서는 사용자가 호출한 URI값에서 /boardList.bo에 일치하는 if문으로 들어가서 action클래스를 생성한다.

 이 과정을 스프링에서는 사용자가 http://server/contextName/board/boardList.jsp 를 호출하면 ViewResolver는 URI에서 앞뒤 다떼고 board/boardList만 확인해서 해당하는 View를 보여준다.

 

- 위의 구조에서 HandelrMapping, HandlerAdapter는 잠시 생략.. ( 참고 http://kimddochi.tistory.com/86 )

 

 

 

■ Spring MVC 기본 프로젝트 구조

 

 Spring MVC Project를 생성하면 가장 기초적으로 생성된 모습이다.

기본적으로 제공되는 HomeController와 home.jsp의 위치에 각각 Controller와 view페이지를 추가하면 된다. 스프링 MVC 프로젝트는 처음에 프로젝트를 생성했을 때부터 이렇게 MVC 패턴으로 만들어지기 때문에 개발자가 하나하나 만들어서 설정하고 연결할 필요가 없다. 따라서 생성된 구조 자체를 활용해서 그대로 프로젝트를 완성하면 되기 때문에 개발 속도도 빨라지고 성능의 큰 손실이 없다는 장점이 있다!

그렇다면 반대로 이 Spring MVC 구조를 모르면 아예 프로젝트를 만들 수 없겠지?

 

 

[ servlet-context.xml ]

: 스프링 컨테이너 설정 파일로, DI는 여기에 생성 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 
    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
    
    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />
 
    <!-- resource 매핑하는 부분. 여기에 위치설정해주고 src/main/webapp/ 에 추가적인 폴더를 생성하면 여기에서 매핑해야한다 -->
    <resources mapping="/resources/**" location="/resources/" />
 
    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <!-- ViewResolver 객체 : 뷰를 불러오는 기능(도구)  -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- View페이지 경로를 항상 이렇게 읽을거야 라고 설정하는 부분. 
        View는 경로가 WEB-INF/views/로 설정되어있고, .jsp로 확장자 되어있다 알려줌 -->
        <!-- Server/Context/WEB-INF/views/test.jsp 를 부른다고 가정한다면
         Controller에서 View의 이름만 리턴하면 해당 View를 찾을 수 있게 설정함.
         prefix(경로)와 suffix(확장자)가 미리 설정되어 있다 -->
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>
    
    <!-- mvctest라는 context(작업폴더)를 스캔하라고 지정 -->
    <context:component-scan base-package="com.javalec.mvctest" />
    
</beans:beans>
cs

 

[ web.xml ]

: DispatcherServlet 서블릿 매핑, 스프링 설정 파일 위치 정의

 여기서 주목해야 할 부분은 DispatcherServlet이 매핑되어 있는 부분! 이전에 Jsp& Servlet에서 직접 Controller(Servlet)를 매핑해주었던 부분이 자동으로 지정되어 있다는 것이다. Spring에서는 클라이언트의 요청을 최초로 받는 부분이 Controller가 아니라 DispatcherServlet이기 때문에 servlet-class가 DispatcherServlet으로 지정되어 있다. 이때 servlet-context.xml에 저장되어있는 정보들을 다 파라미터로 가지고 넘어간다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 
    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>
    
    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
 
    <!-- Processes application requests -->
    <!-- DispatcherServlet 매핑 정보 : servlet-context.xml에 저장된 정보를 가지고 매핑됨-->
    <!-- url패턴이 /로 지정되어있음 -> url패턴 다른걸로 바꾸면 안된다. -->
    <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>
 
</web-app>
cs

 

 

[ home.jsp ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
    <title>Home</title>
</head>
<body>
<h1>
    Hello world!  
</h1>
 
<P>  The time on the server is ${serverTime}. </P>
</body>
</html>
cs

 

[ HomeController ]

: home.jsp를 호출하는 home메소드를 보자. return 값이 이전에 Jsp & Servlet에서처럼 /home.jsp가 아니라 view파일명 그 자체만 반환한다. 이렇게 리턴해도 제대로 home.jsp를 찾아서 보여줄 수 있는 이유는 위에 설명했던 ViewResolver가 설정되어 있기 때문이다. Controller에서 파일명만 리턴하면 Resolver에서 미리 지정되어 있는 경로와 확장자를 붙여서 직접 그 위치에 있는 view를 보여준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.javalec.mvctest;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
 * Handles requests for the application home page.
 */
// Controller라고 지정. 새로운 Controller를 생성하면 @Controller 지정 해주어야한다.
@Controller
public class HomeController {
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
    
    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);
        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
        
        String formattedDate = dateFormat.format(date);
        
        model.addAttribute("serverTime", formattedDate );
        
        return "home";
    }
}
cs

 

 

 

'Web > Spring' 카테고리의 다른 글

Spring MVC(3)_Annotation & @RequestMapping  (0) 2016.05.17
Spring MVC(2)  (0) 2016.05.16
Spring 한글처리  (0) 2016.05.16
Spring(4)_Environment,Properties  (0) 2016.05.13
Spring(3)  (1) 2016.05.12