[IntelliJ] Spring Web MVC 프로젝트 생성 및 세팅 - 자바 설정 사용

2021. 4. 22. 03:09 Spring Framework/Spring MVC

[IntelliJ] Spring Web MVC 프로젝트 생성 및 세팅 - 자바 설정 사용

1. 프로젝트 생성

새로운 Maven 프로젝트를 생성한다.

Create from archetype 체크, maven-archetype-webapp을 선택하고 Next 클릭

 

프로젝트 정보 입력하고 Next 클릭

 

사용할 Maven 선택 후 Finish 클릭

 

기본으로 생성되는 pom.xml

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

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.atoz_develop</groupId>
  <artifactId>project03</artifactId>
  <version>1.0-SNAPSHOT</version> 
  <packaging>war</packaging>

  <name>project03 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>project03</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

maven-archetype-webapp으로 프로젝트 생성 시 기본으로 생성되는 pom.xml은 위와 같다.

 

2. 자바 버전 설정

먼저 자바 컴파일러 버전을 변경한다.

여기서는 8로 변경하도록 하겠다.

 

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <maven.compiler.source>8</maven.compiler.source>
  <maven.compiler.target>8</maven.compiler.target>
</properties>

pom.xml의 <maven.compiler.source>, <maven.compiler.target>을 8로 변경한다.

 

IntelliJ Project Structure에서 프로젝트/모듈의 Language level을 8로 변경한다.

 

Preferences에서 Build, Execution, Deployment - Compiler - Java Compiler 클릭하고 프로젝트/모듈의 Target bytecode version을 8로 변경한다.

이렇게 세 가지를 설정하면 자바 버전 설정은 완료된다.

 

3. 의존성 설정

다음으로 Spring MVC, Servlet/JSP API, jstl 라이브러리 의존성을 추가한다.

아래와 같이 <properties>와 <dependencies>를 변경하면 된다.

이 중 Spring MVC는 필수이고 Servlet/JSP API, jstl은 선택사항이다.

JSP 외의 다른 뷰 템플릿을 사용한다면 해당 라이브러리를 추가한다.

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <maven.compiler.source>8</maven.compiler.source>
  <maven.compiler.target>8</maven.compiler.target>
  <spring-webmvc-version>5.2.6.RELEASE</spring-webmvc-version>
  <javax.servlet-api-version>4.0.1</javax.servlet-api-version>
  <javax.servlet.jsp-api-version>2.3.3</javax.servlet.jsp-api-version>
  <javax.servlet.jsp.jstl-api-version>1.2.2</javax.servlet.jsp.jstl-api-version>
  <taglibs-standard-impl-version>1.2.5</taglibs-standard-impl-version>
  <junit-version>4.11</junit-version>
</properties>

<dependencies>
  <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring-webmvc-version}</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>${javax.servlet-api-version}</version>
    <scope>provided</scope>
  </dependency>

  <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>${javax.servlet.jsp-api-version}</version>
    <scope>provided</scope>
  </dependency>

  <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/javax.servlet.jsp.jstl-api -->
  <dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>javax.servlet.jsp.jstl-api</artifactId>
    <version>${javax.servlet.jsp.jstl-api-version}</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
  <dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-impl</artifactId>
    <version>${taglibs-standard-impl-version}</version>
  </dependency>

  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit-version}</version>
    <scope>test</scope>
  </dependency>
</dependencies>

 

4. 웹 어플리케이션 설정

XML로 스프링 MVC 설정을 할 때 web.xml에 한 설정들은 자바로 설정할 때는 AbstractAnnotationConfigDispatcherServletInitializer를 상속하던지 WebApplicationInitializer 인터페이스를 구현하는 방법으로 설정할 수 있다.

AbstractAnnotationConfigDispatcherServletInitializer를 상속하는 방법이 더 쉽고 간단하지만 설정의 자유도가 떨어지는 특징이 있다.

 

WebApplicationInitializer 인터페이스를 구현하는 방법을 기준으로 보고 뒤에서 AbstractAnnotationConfigDispatcherServletInitializer를 상속하는 방법을 살펴볼 것이다.

 

1) WebApplicationInitializer 인터페이스를 구현하는 방법

config 패키지와 WebConfig, WebContext, RootContext 클래스를 새로 생성한다.

각각 web.xml, web context config, root context config 역할을 한다.

먼저 WebConfig 클래스는 다음과 같이 작성한다.

 

WebConfig

public class WebConfig implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

    }
}

 

① DispatcherServlet 설정

public class WebConfig implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        // DispatcherServlet 설정 -s
        // 1. DispatcherServlet WebApplicationContext 객체 생성
        AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
        webContext.register(WebContext.class);

        // 2. DispatcherServlet 객체 생성 및 추가
        DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
        ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", dispatcherServlet);

        // 3. 서블릿 매핑 및 부가 설정
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
        // DispatcherServlet 설정 -e
    }
}

 

이 코드는 web.xml의 다음 설정과 동일한 내용이다.

<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/config/webmvc-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>

 

② Root Context Config 설정

 

public class WebConfig implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        // DispatcherServlet 설정 -s
        // ...
        // DispatcherServlet 설정 -e
        
        // Root Context Config 설정 -s
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(RootContext.class);

        ContextLoaderListener listener = new ContextLoaderListener(rootContext);
        servletContext.addListener(listener);
        // Root Context Config 설정 -e
    }
}

 

이 코드는 web.xml의 다음 설정과 동일한 내용이다.

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/config/root-context.xml</param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

 

③ Filter 설정

public class WebConfig implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        // DispatcherServlet 설정 -s
        // ...
        // DispatcherServlet 설정 -e

        // Root Context Config 설정 -s
        // ...
        // Root Context Config 설정 -e

        // Filter 설정 -s
        FilterRegistration.Dynamic filter = servletContext.addFilter("encodingFilter", CharacterEncodingFilter.class);
        filter.setInitParameter("encoding", "UTF-8");
        filter.addMappingForServletNames(null, false, "dispatcher");
        // Filter 설정 -e
    }
}

 

이 코드는 web.xml의 다음 설정과 동일한 내용이다.

<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>

 

최종 WebConfig 클래스

public class WebConfig implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        // DispatcherServlet 설정 -s
        // 1. DispatcherServlet WebApplicationContext 객체 생성
        AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
        webContext.register(WebContext.class);

        // 2. DispatcherServlet 객체 생성 및 추가
        DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
        ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", dispatcherServlet);

        // 3. 서블릿 매핑 및 부가 설정
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
        // DispatcherServlet 설정 -e

        // Root Context Config 설정 -s
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(RootContext.class);

        ContextLoaderListener listener = new ContextLoaderListener(rootContext);
        servletContext.addListener(listener);
        // Root Context Config 설정 -e

        // Filter 설정 -s
        FilterRegistration.Dynamic filter = servletContext.addFilter("encodingFilter", CharacterEncodingFilter.class);
        filter.setInitParameter("encoding", "UTF-8");
        filter.addMappingForServletNames(null, false, "dispatcher");
        // Filter 설정 -e
    }
}

 

2) AbstractAnnotationConfigDispatcherServletInitializer를 상속하는 방법

지금까지 WebApplicationInitializer 인터페이스를 구현하는 방법을 통해 설정한 것을 AbstractAnnotationConfigDispatcherServletInitializer를 상속하는 방법으로 설정하면 다음과 같다.

public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {

	// DispatcherServlet 설정
	@Override
	protected String[] getServletMappings() {
		return new String[] {"/"};
	}

	// Web Context Config 설정
	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class[] {WebContext.class};
	}

	// Root Context Config 설정
	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class[] {RootContext.class};
	}

	// Filter 설정
	@Override
	protected Filter[] getServletFilters() {
		CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
		encodingFilter.setEncoding("UTF-8");
		return new Filter[] {encodingFilter};
	}
}

더 쉽고 간단하지만 설정의 자유도가 떨어진다.

 

5. Web Context 설정

1) Controller 설정

WebContext 클래스를 다음과 같이 작성한다.

 

WebContext

@Configuration
@EnableWebMvc
@ComponentScan("com.atoz_develop.project04.controller")
public class WebContext implements WebMvcConfigurer {
    
}

 

이 코드는 web.xml의 다음 설정과 유사한 내용이다.

<!-- @Controller 애노테이션 사용 -->
<annotation-driven/>

<!-- Component Scan 패키지 설정 -->
<context:component-scan base-package="com.atoz_develop.project03.controller"/>

 

2) ViewResolver 설정

@Configuration
@EnableWebMvc
@ComponentScan("com.atoz_develop.project03.controller")
public class WebContext implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        WebMvcConfigurer.super.configureViewResolvers(registry);
        // ViewResolver 설정
        registry.jsp("/WEB-INF/views/", ".jsp");
    }
}

configureViewResolvers()를 override하여 ViewResolver를 설정한다.

 

이 코드는 xml의 다음 설정과 유사한 내용이다.

<!-- 뷰 prefix, suffix 설정 -->
<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>

 

3) Static Resources 설정

@Configuration
@EnableWebMvc
@ComponentScan("com.atoz_develop.project03.controller")
public class WebContext implements WebMvcConfigurer {

    //...

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        WebMvcConfigurer.super.addResourceHandlers(registry);
        // Static Resources 설정
        registry.addResourceHandler("/**").addResourceLocations("/resources/");
    }
}

addResourceHandlers()를 override하여 정적 리소스를 설정한다.

 

이 코드는 xml의 다음 설정과 유사한 내용이다.

<!-- 정적 리소스 경로 설정 -->
<resources mapping="/**" location="/resources/"/>

 

최종 WebContext 클래스

@Configuration
@EnableWebMvc
@ComponentScan("com.atoz_develop.project03.controller")
public class WebContext implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        WebMvcConfigurer.super.configureViewResolvers(registry);
        // ViewResolver 설정
        registry.jsp("/WEB-INF/views/", ".jsp");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        WebMvcConfigurer.super.addResourceHandlers(registry);
        // Static Resources 설정
        registry.addResourceHandler("/**").addResourceLocations("/resources/");
    }
}

 

6. Root Context 설정

Root Context 설정 클래스는 초기에 설정할 것이 없다.

@Configuration을 붙여서 설정 클래스로 선언하고 추후 프로젝트를 진행하며 필요한 빈을 등록하면 된다.

 

RootContext

@Configuration
public class RootContext {
    
}

 

7. 테스트

설정이 제대로 됐는지 테스트해보자.

 

위 그림에서 선택되어 있는 파일과 디렉토리를 새로 생성한다.

resources 안에는 테스트용 이미지를 아무거나 하나 넣어둔다.

 

HelloController

package com.atoz_develop.project03.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

 

hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Hello Spring Web MVC</title>
</head>
<body>
<h1>Hello Spring Web MVC</h1>
<img src="spring.png"/>
</body>
</html>

 

🖥 실행 결과

위와 같이 /hello로 요청했을 때 실행이 잘 되고 이미지가 잘 뜨면 모든 설정이 정상적으로 완료된 것이다.

 

관련 글

[IntelliJ] Spring Web MVC 프로젝트 생성 및 세팅 - XML 설정 사용

 

출처 : atoz-develop.tistory.com/entry/IntelliJ-Spring-Web-MVC-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%83%9D%EC%84%B1-%EB%B0%8F-%EC%84%B8%ED%8C%85-%EC%9E%90%EB%B0%94-%EC%84%A4%EC%A0%95-%EC%82%AC%EC%9A%A9?category=869241