티스토리 뷰

Chapter03. 첫 번째 스프링 MVC 애플리케이션 분석 : '도서 쇼핑몰' 시작 페이지 만들기

 

 

 

 

3-1. 스프링 MVC의 프로젝트 구조

 

 

프로젝트 구조

 

 

 

서블릿 관련 폴더

서블릿과 관련된 클래스 생성되면 src/main/java 폴더에 등록하여 관리한다.

보통 자바 클래스 파일들을 scr/main/java 폴더에 패키지로 생성하여 등록한다.

개발자가 만든 예외 클래스나 기타 유틸 클래스 파일 등도 src 폴더에 저장한다.

 

 

웹 관련 폴더

웹과 관련된 jsp, 리소스, 스프링 MVC 환경 설정 파일, 웹 프로젝트 환경 설정 파일 등이 생성되면 scr/main/webapp 폴더에 등록하여 관리한다.

 

 

  • resrouces 폴더는 웹에 관련된 이미지, 자바스크립트, css 등 정적 리소스 파일을 관리한다.
  • spring 폴더는 빈(Bean) 객체들을 등록하는 서블릿 설정 파일인 스프링 MVC 설정 파일(기본형 : 서블릿 이름-servlet.xml)을 관리한다. 그리고 스프링 시큐리티 설정 파일 같은 스프링 관련 설정 파일들이 이곳에 저장된다. (=설정파일)
  • views 폴더는 웹 페이지인 jsp 파일을 관리한다.
  • web.xml 파일은 웹 프로젝트의 설정 파일로 여기에 리스너, 서블릿 필터 등을 설정할 수 있다. 이 파일은 반드시 scr/main/webapp/WEB-INF 폴더에 위치해야 한다.
  • pom.xml은 메이븐 관련 환경 설정 파일로 필요한 라이브러리를 추가하여 사용할 수 있게 한다.

 

 

 

프로젝트 실행 과정

chap02를 실행하면 웹 브라우저에 home.jsp 파일이 실행된다.

이때 home.jsp 파일이 실행되는 과정을 학습해보았다.

 

 

 

① web.xml 파일은 가장 먼저 클라이언트의 웹 요청 url을 전달받는다. web.xml 파일에 설정된 디스패처 서블릿이 클라이언트의 웹 요청 url을 제어한다.

 

② servlet-context.xml 파일에서 웹 요청 url을 컨트롤러에 해당하는 클래스를 검색한다. (=핸들러 매핑)

 

③ HomeController 컨트롤러는 클라이언트의 웹 요청 url을 처리하고 결과를 출력할 뷰 이름을 디스패처 서블릿에 반환한다.

(모델 앤 뷰에 담아서 이동함)

 

④ 컨트롤러에서 보내온 뷰 이름을 토대로 처리할 뷰를 검색한다. 

(=뷰 리졸브 / 뷰 리졸브에서 url 완성 시킴)

 

⑤ 처리 결과가 포함된 뷰를 디스패처 서블릿에 반환하고 최종 결과를 출력한다.

 

 

* Servlet-context.xml

디스패처 서블릿 설정파일로 디스패처는 핸들러 매핑, 뷰 리졸브이다.

 

 

 

 

 


 

3-2. 환경 설정 파일 살펴보기 : web.xml

 

 

 

web.xml 파일의 환경 설정

스프링 웹 프로젝트가 실행되면 가장 먼저 web.xml 파일을 읽어 들이고 위부터 차례로 태그를 해석한다.

 

 

 

 

 

네임 스페이스와 스키마 선언

xml 문서를 작성할 때 요소가 중복되는 것을 피하려면 web.xml 파일 맨 위에 네임 스페이스와 스미카를 정의해야 한다.

네임 스페이스는 코드에서 이름은 같지만 내ㅇ이 전혀 다른 요소와 충돌하지 않도록 요소를 구별하는데 사용한다.

스키마는 코드의 구조와 요소, 속성의 관계를 정의하여 다양한 자료형을 사용할 수 있도록 정의된 문서 구조, 틀을 의밈한다.

* 해석기 같은 역할로 예를 들어 폰트어썸과 같다. 직접 작성하는 것이 아닌 복사해서 사용한다.

 

 

 

 

루트 컨텍스트 설정

루트 컨텍스트(root-context)는 서블릿과 필터가 공유할 수 있는 루트 스프링 컨테이너 설정으로 공통 빈(Service, Repository(DAO),DB, Log 등)을 설정한다. 주로 View 지원을 제외한 bean을 설정한다.

기본 설정 파일 외에 사용자가 직접 제어하는 xml 파일(=root-context.xml)을 지정하려면 <context-param> 요소를 사용해 설정한다.

 

 

 

 

서블릿 컨텍스트 설정

(Servlte-context)는 서블릿 하나가 서블릿 컨테이너와 통신할 때 사용하는 메서드들을 가지고 있는 클래스이다. 웹 애플리케이션 안에 있는 모든 서블릿을 관리하며 정보를 공유할 수 있게 도와준다.

* 서블릿 컨테이너는 서블릿 생명주기를 관리한다.

* 사용자마다 하나씩 제공한다. ( 루트 컨텍스트와 다르게 개별로 제공 )

 

<!-- Processes application requests -->
	<servlet>
    	<servlet-name>applServlet</servlet-name>
        <servlet-class>

 

 

 

 


 

3-3. 스프링 MVC 환경 설정 파일

 

스프링 MVC 환결 설정 파일은 빈 객체를 정의하는 root-context.xml 과 servlet-context.xml 두 개가 있다.

root-context.xml 파일에 등록된 빈(=객체)들은 모든 컨텍스트에서 공유되어 사용된다.

하지만 servlet-context.xml 파일에 등록된 빈들은 서블렛 컨텍스트에서만 사용된다. (ex)세션은 각각 제공된다. (로그인))

 

root-context.xml 파일은 뷰(jsp 웹 페이지)와 관련 없는 빈 객체를 설정한다.

그리고 서비스, 저장소, 데이터베이스, 로그 등 웹 애플리케이션의 비즈니스 로직(=model)을 위한 컨텍스트를 설정한다.

servlet-context.xml 파일은 뷰(jsp 웹 페이지)와 관련 있는 빈 객체를 설정한다.

컨트롤러, MultipartResolver, Interceptor, URI와 관련 설정을 담는 클래스를 설정한다.

 

 

 

루트 컨텍스트 파일 살펴보기 : root-context.xml

root-context.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"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- Root Context: defines shared resources visible to all other web components -->

</beans>

 

 

 

 

 

서블릿 컨텍스트 파일 살펴보기 : Servlet-context.xml

 

servlet-context.xml 파일에는 웹 요청을 직접 처리할 컨트롤러매핑을 설정( Handler Mapping )하거나 뷰를 어떻게 처리할지 설정( ViewResolver )할 수 있다.

* 크게 보면 디스패처 서블렛에 핸들러매핑과 뷰리졸버가 속한다.

servlet-context.xml



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



<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->

<resources mapping="/resources/**" location="/resources/" />



<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->

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

<context:component-scan base-package="com.myspring.pro29" />

</beans:beans>

 

 

 

 

 

- 컨트롤러 매핑 설정하기

 

요청 url을 처리하는 컨트롤러에 매핑할 수 있도록 하기 위해 설정으로 요청 url과 같은 컨트롤러의 @RequestMapping 애너테이션에 저장된 url을 매핑한다

<!-- Enables the Spring MVC @Controller progamming model -->
<annotation-driven />

<annotation-driven> 요소는 @Controller, @RequestMapping 같은 애너테이션을 사용할 떄 필요한 빈 객체들을 자동으로 등록한다.

또한, 핸들러 매핑과 핸들러 어댑터의 빈 객체도 대신 등록한다.

 

만약 요소를 사용하지 않으면 핸들러 매핑과 핸들러 어댑터의 빈객체를 직접 작성하여 등록해야만 한다.

아래는 직접 작성하여 beans (객체)를 등록하는 코드이다.

<!-- HandlerMaping -->
<benas:bean class="org.springframework.web.servlet.mvc.method.annotiaion.RequestMappingHandlerMapping" />

<!-- HandlerAdapter -->
<benas:bean class="org.springframework.web.servlet.mvc.method.annotiaion.RequestMappingHandlerAdapter" />

 

 

 

 

 

- 정적 리소스 설정하기

요청에 대해 JS, CSS 이미지 등 리소스 파일을 매핑(url)하려면 아래와 같이 설정해야한다.

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->

<resources mapping="/resources/**" location="/resources/" />

 

 

<resources> 요소는 서버에서 앞서 처리될 필요 없는 정적 리소스 파일을 처리하는 역할을 한다.

앞에서 작성한 코드를 보면 모든 주소들이 무조건 디스패처 서블렛으로 가도록 설정하였다. 하지만 정적 리소스 설정은 소스 코드나 웹 브라우저의 주소창에서 해당 리소스의 경로를 사용해 직접 접속할 수 있다.

즉, 디스패처 서블렛을 거치지 않는다는 뜻이다.

 

속성 설명
mapping 웹 요청 경로 패턴을 설정한다. 컨텍스트 경로를 제외한 나머지 부분의 경로와 매핑한다. (=조건)
location 웹 애플리케이션 내에서 실제 요청 경로의 패턴에 해당하는 자원 위치를 설정한다.
위치가 여러 곳이면 각 위치를 쉼표로 구분한다. 
cache-period 웹 브라우저에 캐시 시간 관련 응답 헤더를 전송한다. 초 단위로 캐시 시간을 지정한다. 값이 0이면 웹 브라우저가 캐시하지 않도록 하고, 값을 설정하지 않으면 캐시 관련 응답 헤더를 전송하지 않는다.

 

 

 

 

 

 

 

- 뷰 매핑 설정하기

 

사용자에게 응답 결과를 보여 주려고 컨트롤러가 모델을 반환하고 디스패처 서블릿이 jsp 파일을 찾을 수 있게 설정한다.

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->

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

컨트롤러에서 설정한 뷰 이름으로 실제 사용할 뷰를 선택하는 뷰 리졸버 객체를 설정한다.

이때 url주소가 완성되는데 url은 설정한 뷰 이름 앞 뒤로 prefix 프로퍼티와 suffix 프로퍼티를 추가한 값이다.

이것이 실제 사용될 뷰의 경로가 된다.

만약 컨트롤러에서 설정한 뷰의 이름이 home이라면 뷰의 실제 경로는 /WEB-INF/views/home.jsp가 된다.

 

 

 

 

- 자바 클래스의 빈 객체 설정하기

<context:component-scan base-package="com.myspring.controller" />

 

<component-scna> 요소는 스프링 MVC에서 사용할 빈 객체를 일일이 xml에 등록하지 않아도 필요한 애너테이션을 자동으로 만들어 인식할 수 있게한다.

 

<component-scan> 요소를 사용하지 않으면 @Controller가 선언된 HomeController 컨트롤러를 빈 객체로 등록해야 한다. 또한 의존 관계가 있는 자바 클래스가 있다면 <bean> 요소를 이용해 빈 객체를 직접 등록해야한다.

 

아래는 수동으로 빈즈를 등록하는 코드이다.

<!-- Controller" -->
<beans:bean class="com.springmvc.controller.HomeController"/>

* 단위는 패키지이다.

* 패키지 단위로 스캔해서 가져온다. (com.myspring.controller)

* @Controller 일 경우 자동으로 만들어준다.

 

 

 

* context:component-scan요소가 자동으로 인식하는 애너테이션

애너테이션 설명
@Component 특별히 역할 구분 없이 컴포넌트라고 알려 주는 역할을 한다.
@Repository, @Service, @Controller 각각 DB 작업 관련, 서비스 관련, MVC 컨트롤러 컴포넌트를 의미한다. 어떤 종류의 컴포넌트인지 알려 주는 역할을 한다.
@Required 필수 프로퍼티임을 명시하는데 사용한다.
@Qutowired 의존 관계를 자동 설정할 떄 사용하며, 타입을 이용하여 의존하는 객체를 삽입해 준다. (전역변수에 객체 채우는데 사용된다.)
@Inject 특정 프레임워크에 종속되지 않는 애플리케이션을 구성하는데 사용한다.

 

 

 

 

 

3-4. 컨트롤러 :HomeController.java

 

package com.spring.pro29;

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
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
//	value = "/" 이니까 전부를 뜻한다.
	@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);
		//request대신 model쓴다.
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
}

 

 

3-5. 뷰 : hello.jsp

사용자가 보는 뷰 결과 화면은 jsp 파일이다.

이전에는 jstl을 사용하고자하면 파일은 다운 받아 lib 폴더에 넣어주어야했다.

하지만 여기서는 태그를 사용하여 다운받아와 따로 폴더에 넣어줄 필요가 없다.

 

EL을 사용해 컨트롤러에서 전송한 모델 데이터를 출력한다.

${}형식으로 사용하고 이것은 out.print와 <%= %>와 같은 역할을 한다.

<%@ page contentType="text/html; cahrset=utf-8" %>
<%@ tagelib uti="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
Html>
<head>
<title>Home</title>

<body>
    <h1>Hello world!</h1>
    <p>The time on the server is ${serverTime}. </p>
</body>
</html>

 

 

 

 

3-6. 메이븐 환경 설정 파일 :pom.xml

pom.xml 파일은 POM을 설정하는 부분으로 프로젝트 내 빌드 옵션을 설정한다.

xml 태그를 사용해 프로젝트에 필요한 메이븐 라이브러리를 설정한다.

메이븐은 프로젝트 내에 사용할 라이브러리뿐 아니라 해당 라이브러리가 자곧ㅇ하는데 필요한 다르 라이브러리까지 프로젝트의 전체적인 라이프 사이클을 관리하는 도구이다.

이전까지는 web-INF의 lib 폴더에 직접 넣어주었다 하지만 이제는 링크를 삽입하면 자동으로 설정이된다.

 

이때 라이브러리는 메이븐 리파지토리에서 소스를 다운받아 링크를 삽입한다. 그리고 alt+F5를 클릭하여 설정을 완료해야 한다.

 

 

 

프로젝트 정보 : <project>

프로젝트 전체에 적용되는 모든 정보를 기술할 때는 pom.xml 파일의 <project> 루트 요소 안에 설정한다.

 

*그룹 ID는 com.naver과 같이 큰 그룹을 말한다.

* 아티팩트 ID는 news ,sports, webtooon과 같이 큰 그룹 안에 속하는 작은 그룹을 말한다. 프로젝트 이름과 유사하다.

 

<?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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
  <groupId>com.itedunet</groupId>
  <artifactId>example</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
		<java-version>17</java-version>
		<org.springframework-version>4.1.1.RELEASE</org.springframework-version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
		<org.slf4j-version>1.6.6</org.slf4j-version>
  </properties>

 

 

 

속성 정보 : <properties>

properties는 속성 정보를 정의하는데 이때 정의된 정보들은 나중에 변수처럼 사용이 가능하다.

<org.aspectj-version>1.9.6</org.aspectj-version> 일 경우 변수로 사용하려면 <version>${org.aspectj-version}</version>으로 불러와 출력할 수 있다.

 

  <properties>
		<java-version>17</java-version>
		<org.springframework-version>4.1.1.RELEASE</org.springframework-version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
		<org.slf4j-version>1.6.6</org.slf4j-version>
  </properties>

 

 

 

의존성 라이브러리 정보 : <dependencies>

의존성 라이브러리 정보는 pom.xml 파일 내 <dependencies> 요소 안에 설정한다.

또한 각각의 의존성 라이브러리 정보는 <dependency> 요소를 사용해 작성한다.

원하는 만큼 <dependencies> 요소 안에 설정한다.

 

  <dependencies>
		<dependency>
        	<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
         </dependency>     
  </dependencies>

 

 

 

빌드 정보 : <build>

프로젝트를 빌드할때 필요한 요소들을 불러오고 싶다면 <build> 요소 안에 설정한다.

<plugins> 요소를 이용하여 빌드에서 사용할 플러그인을 설정한다.

 

 

	<build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday