본문 바로가기
스프링(부트)/스프링 내용 정리

[스프링] Spring Web MVC

by doflamingo 2020. 4. 3.

Spring MVC

Spring MVC 프레임워크는 MVC 디자인패턴을 사용하도록 되어있고 유연하고 느슨하게 연결된 웹 애플리케이션을 개발하는 데 사용할 수있는 준비된 구성 요소를 제공한다. 

 

Spring MVC 구조

 

MVC의 순서를 보면 다음과 같다. 

 

1. 클라이언트가 서버에게 어떤 요청을 보내면 DispatchServlet이 가로챈다. 

   DispatcherServlet은 web.xml파일에서 설정할 수 있는데 web.xml파일에 아래의 내용을 추가해주면 된다. 

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--        <init-param>-->
<!--            <param-name>contextConfigLocation</param-name>-->
<!--            <param-value>/WEB-INF/dispatcher-servlet.xml-->
<!--            </param-value>-->
<!--        </init-param>-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

 

주석처리한 부분은 dispatcher-servlet.xml 파일의 위치를 지정해주기 위해서 필요한 줄 알았으나 없어도 잘 찾아서 굳이 적어줄 필요는 없는거 같다. 

 

아직 스프링 짬이 부족해서 base경로는 어떻게 찾는지 공부를 해야할 것 같다..ㅎㅎ

 

저 web.xml에는 다른 servlet의 정보도 위와 같이 추가할 수 있는데 servlet-name과 url을 매핑해서 어떤 servlet이 어떤 url로 매핑이 되는지 지정할 수 있다. 여기서는 dispatcher-servlet이 모든 요청을 가로챌 것이기 때문에 기본 url인 '/' 을 매핑시켜주었다. 

 

2. 다음으로 Dispatcher Servlet은 Handler Mapping에게 들어온 요청에 대한 controller를 찾게 요청한다. 

그러면 Handler Mapping은 servlet의 설정을 해줬던 dispatcher-servlet.xml을 통해서 알 수 있다.

dispatcher-servlet.xml을 보면 component-scan을 통해서  base-package를 설정하는데

저 패키지 하위의 파일들을 스캔해서 어노테이션이 달린 것들을 빈으로 등록한다. 

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <context:component-scan base-package="me.bosuksh.springmvc" />
    <mvc:annotation-driven />
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

 

3. 그렇게 해당하는 url을 찾아서 controller로 들어오면 이제 각각의 java코드로 들어오게 된다.

여기서 예제의 controller을 보게되면 아래와 같다. 

http(s)://url/employee-module/getAllEmployees 라는 url을 통해 들어오게 되면 일련의 logic을 거쳐서 employeesListDisplay라는

jsp파일을 리턴해주는 구조로 되어있다. 여기서 model라는 변수를 통해 jsp파일에서 사용한 데이터를 attribute에 저장해서 넘겨줄 수 있다. 

 

@Controller
@RequestMapping("/employee-module")
public class EmployeeController
{
    @Autowired
    EmployeeService employeeService;

    @RequestMapping(value = "/getAllEmployees", method = RequestMethod.GET)
    public String getAllEmployees(Model model)
    {
        model.addAttribute("employees", employeeService.getAllEmployees());
        return "employeesListDisplay";
    }
}

 

여기서 Controller에서 받은 것을 주입된 Service를 찾아서 logic처리를 하고 오는데 그부분은 생략하겠다. 

 

4. Controller에서 넘겨준 View Template파일의 이름은 위에서 이야기한 View Resolve를 통해서 실제 view파일로 전달이 되는데 이 ViewResolve는 아까 위에서 지나간 dispatcher-serlvet.xml파일 내부에 포함되어 있다. 그 파일을 다시 가져오면

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

<!-- <context:component-scan base-package="me.bosuksh.springmvc" />
    <mvc:annotation-driven />
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> -->
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

※ 보기 편하게 하기위해 component-scan부분과 annotation-driven등은 주석처리를 하였으나 실제로 코드에선 들어가야한다. 

 

 

아무튼 InternalResourceViewResolve라는 빈으로 등록한 부분이 View Resolve의 역할을 하는데 여기서 prefix와 suffix를 통해 범위를 정해줘서 View Resolve는 Controller를 통해서 넘겨받은 해당 View의 이름을 찾아서 클라이언트에게 뿌려주게 되는 것이다. 

 

이러한 일련의 과정을 통해서 클라이언트에서 요청이 들어온 내용을 실제 view로 뿌려주게 되는 것이다. 이는 Spring Framework에서 제공해주고 있고 우리는 잘 사용하면 됩니다~~~!!

 

 

Reference:

https://devkingdom.tistory.com/7

https://gmlwjd9405.github.io/2018/12/20/spring-mvc-framework.html

 

code reference:

https://howtodoinjava.com/spring-mvc/spring-mvc-hello-world-example/

댓글