본문으로 바로가기

스프링MVC 서브(sub)프로젝트 

-https://spring.io/projects 를 보면 Spring Framwork라는 메인 프로젝트 외에도 여러 종류의 프로젝트가 존재함,스프링 MVC역시이러한 프로젝트 중 일부임.


스프링은 하나의 기능을 위해서만 만들어진 프레임워크가 아니라 '코어'라고 할 수 있는 프레임워크에 여러 서브 프로젝틀르 결합해서 다양한 상황에 대처할 수 있도록 개발되었음. 서브 프로젝트의 의미를 개발자의 입장에서 가장 쉽게 이해할 수 있는 방법은 '별도의 설정이 존재할 수 있다' 라는 개념.

Spring Legacy Project로 생성한 예제의 경우도 servlet-context.xml 과 root-context.xml 로 설정 파일이 분리된 것을 볼 수 있음.스프링  MVC가 서브 프로젝트이므로 구성 방식이나 설정 역시 조금 다르다고 볼 수 있음.


제가 하고 있는 예제의 구조는 다음 그림과 같음.



▶스프링MVC 프로젝트의 내부 구조

-스프링MVC 프로젝트를 구설해서 사용한다는 의미는 내부적으로 root-context.xml로 사용하는 일반 Java 영역(흔히 POJO)과 servlet-context.xml로 설정하는 Web관련 영역을 같이 연동해서 구동하게 됨. 그림으로 간단히 보면 



바깥쪽에 있는 WebApplicationContext라는 존재는 기존의 구조에 MVC 설정을 포함하는 구조로 만들어 짐.스프링은 원래 목적 자체가 웹 애플리케이션을 목적으로 나온 프레임워크가 아니기 때문에 달라지는 영역에 대해서는 완전히 분리하고 연동하는 방식으로 구현되어있음.

Eclipse(STS) 내'Spring Legacy Project'를 이용해서 'ex01'프로젝트 생성함. 프로젝트는 'Spring MVC Project'로 생성함. 패키지명 'org.zerock.controller'. 





3버전을 5.0.7버전으로 pom.xml에서 변경

1
2
3
4
5
6
7
8
9
10
    <name>ex01</name>
    <packaging>war</packaging>
    <version>1.0.0-BUILD-SNAPSHOT</version>
    <properties>
        <java-version>1.6</java-version>
        <org.springframework-version>5.0.7.RELEASE</org.springframework-version>
        <org.aspectj-version>1.6.10</org.aspectj-version>
        <org.slf4j-version>1.6.6</org.slf4j-version>
    </properties>
    <dependencies>
cs


Lombok+speing-test 추가 나중에 사용할 것들 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
    <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
            <scope>provided</scope>
        </dependency>
        
        <!-- spring-test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
cs

 


Spring Legacy Project로 생성된 프로젝트는 서블릿 버전이 2.5버전을 사용하는데 ,Java 설정 등을 이용하려면 서블릿 3.0이상을 사용하는 것이 좋음.

 기존것을 주석처리하고 3.1.0으로 바꿔준다 . 


1
2
3
4
5
6
7
8
9
10
11
12
13
    <!-- Servlet -->
    <!--     <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency> -->
        
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
cs

Maven의 컴파일 옵션은 1.8으로 변경하고 프로젝트의 'Maven' 메뉴에서 'updateproject' 를 실행.


1
2
3
4
5
6
7
8
9
10
11
12
  <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
cs


이상 없는지 확인.


웹 프로젝트는 가능하면 절대 경로를  이용하는 구조를 사용하는 것이 바람직하므로,Tomcat의 'Modules'메뉴를 이용해서 '/'경로로 프로젝가 실행될 수 있도록 처리함.

(혹은 해당프로젝트 Propertise의 'Web Project Settings'속성을 '/'로 지정합니다)




프로젝트 경로(Context Path)를 수정한 뒤에는 '/'경로가 인식되는지 Tomcat을 재시작해서 확인.


<Java설정을 이용하는 경우> 

'jex01'로 생성 하고  web.xml과 servlet-context.xml,root-context.xml을 제거 (패키지명 전과 동일 )


pom.xml 에서 web.xml이 없다는 설정을 추가해야 함.pom.xml에 <plugin> 설정을 추가함.

1
2
3
4
5
6
7
8
             <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
cs

해당 프로젝트 내에 존재하는 servlet-context.xml,root-context.xml,web.xml은 삭제하고 시작.

servlet-context.xml이 없는 상태에서 프로젝트를 시작하게 되므로 'org.zerock.config'패키지를 만들고 ,WebConfig,RootConfig클래스를 만들어 준다 



RootConfig클래스 이번에 별다른 역할이 없기 때문에 내용없이 작성


1
2
3
4
5
6
7
8
9
package org.zerock.config;
 
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class RootConfig {
 
}
 
cs


WebConfig클래스를 AbstractAnnotationConfigDispatcherServletInitializer상속함

AbstractAnnotationConfigDispatcherServletInitializer를 사용할 시 5.0.7버전과  1.8로 되었는지 확인 해야함 아니면 안됨.


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
package org.zerock.config;
 
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
 
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer  {
 
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {RootConfig.class};
    
    }
 
    @Override
    protected Class<?>[] getServletConfigClasses() {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    protected String[] getServletMappings() {
        // TODO Auto-generated method stub
        return null;
    }
 
}
 
cs


Spring MVC를 이용하는 경우에는 servlet-context.xml을 대신하는 별도의 ServletConfig 클래스 작성.



ServletConfig 클래스는 기존의 servlet-context.xml에 설정된 모든 내용을 담아야하는데 ,이때는 주로 다음과 같은 방식으로 이용.


-@EnableWebMvc 어노테이션과 WebMvcConfigurer인터페이스를 구현하는 방식

(과거에는 WebMvcConfigurerAdapter 추상 클래스를 이용했으나,스프링 5.0버전 부터는 Deprecated되었으므로 주의)

-@Configuration과 WebMvcConfigurationSupport클래스를 상속하는 방식-일반@Configuration 우선 순위가 구분되지 않는경우에 사용


예제는 EnableWebMvc 를 이용해서 제작.기존에 servlet-context.xml의 내용을 아래 코드를 통해서 설정.


ServletConfig클래스 


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
package org.zerock.config;
 
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
 
@EnableWebMvc
@ComponentScan(basePackages= {"org.zerock.controller"})
public class ServletConfig implements WebMvcConfigurer{
 
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        
        InternalResourceViewResolver bean =new InternalResourceViewResolver();
        bean.setViewClass(JstlView.class);
        bean.setPrefix("/WEB-INF/views");
        bean.setSuffix(".jsp");
        registry.viewResolver(bean);
    }
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }
}
 
cs


WebMvcConfigurer는 스프링 MVC와 관련된 설정을 메서드로 오버라이드 하는 형태를 이용할 때 사용함.ServletConfig클래스 역시 

@ComponentScan을 이용해서 다른 패키지에 작성된 스프링의 객체(Bean)를 인식할 수 있음.


작성된 ServletConfig클래스를 정상적으로 실행하려면 WebConfig의 설정은 아래와 같이 ServletConfig를 이용하고 ,스프링 MVC의 기본 경로도'/'로 변경되어야함.

(위에 설명처럼 바꿔 주면됨.)

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
package org.zerock.config;
 
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
 
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer  {
 
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {RootConfig.class};
    
    }
 
    @Override
    protected Class<?>[] getServletConfigClasses() {
        
        return new Class[] {ServletConfig.class} ;
    }
 
    @Override
    protected String[] getServletMappings() {
        
        return new String[] {"/"};
    }
 
}
 
cs

설정이후 XML방식과 동일하게 Tomcat에서 실행하면됨.( 오터또는 배먹은 것이 없는지 확인!!!)