본문 바로가기
JAVA/Spring

Spring MVC 설정

by 설총이 2018. 9. 11.

- Spring MVC


-------------- 설치과정 ------------------


서버 아파치 톰캣 설치 -> 라이브러리에 server runtime 추가


new 메이븐 프로젝트 -> webapp 으로 되어있는것 생성.


프로젝트 우클릭 -> build path - > missing으로 난것들 전부 삭제후 java 다시 생성


- 메이븐 웹 버전 올리기


1. 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_3_1.xsd" version="3.1">


<!-- 서블릿 설정 -->



</web-app>



2. pom.xml에 build 추가



 <build>

    ...

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-compiler-plugin</artifactId>

                <version>3.3</version>

                <configuration>

                    <source>1.8</source>

                    <target>1.8</target>

                    <encoding>UTF-8</encoding>

                </configuration>

            </plugin>

        </plugins>

  </build>



3. 프로젝트 우클릭 > Maven > Update Project 클릭


4. 프로젝트 Facet 변경

    - 프로젝트 Properties > Project Facets 에서 Dynamic Web Module을 3.1으로, Java 1.8 변경

    위 방법으로 할 때

    "Cannot change version of project facet Danymic Web Module to 3.1"이란 메시지가 나오는 경우

    ==> window-> show view-> Navigator에서 프로젝트/.settings/org.eclipse.wst.common.project.facet.core.xml 파일 직접 수정



<?xml version="1.0" encoding="UTF-8"?>

<faceted-project>

  <fixed facet="wst.jsdt.web"/>

  <installed facet="jst.web" version="3.1"/>

  <installed facet="wst.jsdt.web" version="1.0"/>

  <installed facet="java" version="1.8"/>

</faceted-project>




5. 프로젝트 우클릭 > Maven > Update Project 클릭


6. 프로젝트 우클릭 > properties > deployment Assembly > Maven Dependencies 있는지 확인

없으면 > add > java build path entries 추가






- Spring MVC 동작방식


1. [web.xml]


서블릿과 그 서블릿에 맞는 URL 패턴을 가진 매핑을 두개 만든다.



1
2
3
4
5
6
7
8
9
10
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 첫번째 요청엔 똑같은 이름의 servlet-name을 찾아 xml파일을 읽어들인다. -->
</servlet>
 
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
cs



맨 처음 서버 스타트를 할때, servlet-class에서 읽어들이면서


<servlet-name>dispatcher</servlet-name>

이 서블릿 네임과 똑같은 이름의 dispatcher-servlet.xml찾아서 읽어들인다.


ex)서블릿 네임을 java라고 저장했다면 java-servlet.xml을 찾는다



2. [dispatcher-servlet.xml]


1
2
<bean id="helloController"
    class="spring.controller.HelloController" />
cs


이러한 클래스를 bean 컨테이너에 올리게되고, 그 클래스를 쭉 읽는다.



3. [HelloController.java]



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
@Controller
public class HelloController {
    @RequestMapping("/hello.do")
    public ModelAndView hello() {
        ModelAndView mav = new ModelAndView();
        //view 정보 저장
        mav.setViewName("hello");
        //model 데이터 저장(key,value)
        mav.addObject("greeting", getGreeting());
        return mav;
    }
    
    private String getGreeting() {
        int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
        if(hour >= 6 && hour <=10) {
            return "좋은 아침입니다.";
        }else if(hour >= 12 && hour <= 15) {
            return "점심 식사는 하셨나요?";
        }else if(hour >=18 && hour <=22) {
            return "좋은 밤 되세요";
        }
        return "안녕하세요";
    }
    
}
cs



HelloController라는 클래스를 bean객체로 올리면서 이 클래스의 모든 정보가 로딩이된다,

ModelAndView Hello()메서드와, String getGreeting() 메서드가 로딩이 된다.


동시에


어노테이션으로 @Controller라고 걸음으로써, 컨트롤러 객체로도 동시에 생성이 된다.

컨트롤러로 건 클래스 객체는 RequestMapping("/hello.do") 을 사용할 수 있게 된다.





-------- 이 상태에서 Client가 /hello.do를 요청으로 인해, 클라이언트의 요청이 DispacherServlet에 전달된다


DispacherServlet이 클라이언트의 요청을 처리할 컨트롤러객체를 구해서,

컨트롤러 객체를 이용해서 클라이언트의 요청을 처리한다.


즉,

===> DispacherServlet -> Controller에게 Request!!!!











web.xml에 있는 .do로 요청을 받음으로써, 프로젝트명/hello.do가 남고, 

Contextroot가 삭제되고 /hello.do가 남게 된다. 


RequestMapping으로 걸린 publicModelAndView hello() 가 실행된다.


1. ModelAndView에 setViewName으로 ("hello")라는 이름으로 저장이 하나되고

2. ModelAndView에 addObject로

 "greeting"이라는 스트링(key)로 getGreeting()의 (value)값이 저장이 되어


리턴한다.


그 리턴은 DispacherServlet이 요청했으므로

저장된 값을 DispacherServlet로 리턴함을 기억하자


DispacherServlet이


setViewName("hello") 과 addObject("greeting",getGreeting())을 가진채로


저 두가지의 정보(Model)을 들고 viewResolver로 'Request' 한다





2. [dispatcher-servlet.xml] 추가한내용



1
2
3
4
5
6
7
8
<!-- hello라는 setName을 리졸버가 받는다 그것을,
/WEB-INF/views/hello.jsp 로 만들어주고 이 완성값을 디스페쳐에게 돌려준다. -->
<bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>
<!-- property들을 앞에 붙히고 뒤에붙혀서 뷰 경로를 만들어준다 -->
cs




기존에 setViewName("hello")라는 이름을 들고, viewResolver를 찾아간다.

prefix는 setName앞에 붙혀질 값이고,

suffix는 setName뒤에 붙혀질 값이다.


완성되는것은


/WEB-INF/views/hello.jsp 가 되는 것이다.


hello라는 setName 앞뒤로 prefix 값, suffix 값이 붙혀진다.


즉, /WEB-INF/views/hello.jsp 라는 경로의 view 를 다시 DispacherServlet으로 '리턴' 한다.


DispatcherServlet은 viewResolver가 만드는 경로의 페이지를 실행하고 그 뷰 페이지에 

+ 아까만든 addObject("greeting",getGreeting()) 라는 정보(model)도 가지고 페이지를

Open 하는 것이다



4. [/WEB-INF/views/hello.jsp]



1
2
3
4
5
6
7
8
9
10
<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<head>
<title>인사</title>
</head>
<body>
인사말:
<strong> ${greeting}</strong>
</body>
</html>
cs


greeting이라는 정보를 담아 view를 요청했으므로, EL로 꺼낼 수 있게된다.














★★Spring MVC 동작방식 요약★★








1. 클라이언트의 요청이 DispacherServlet에 전달된다.

2. DispatcherServlet은 HandlerMapping을 사용하여

클라이언트의 요청을 처리할 컨트롤러객체를 구한다.

3. 컨트롤러 객체를 이용해서 클라이언트의 요청을 처리한다.

4. 컨트롤러는 클라이언트의 요청 처리 결과 정보를 담은 ModelAndView 객체를 리턴한다.

5. DispatcherServlet은 ViewResolver로부터 응답 결과를 생성할 뷰 객체를 구한다.

6. 뷰는 클라이언트에 전송할 응답을 생성한다.


 - view 페이지를 WEB-INF로 넣은이유


URL로 바로 jsp페이지를 실행하지 못하도록 하기위해