티스토리 뷰
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>
'코딩 > spring' 카테고리의 다른 글
[15주 3일차] 컨트롤러 구현 (0) | 2024.01.17 |
---|---|
[15주 3일차] 스프링 MVC 애플리케이션의 계층적 구조 (0) | 2024.01.17 |
[15주 2일차] 도서 쇼핑몰 프로젝트 (0) | 2024.01.16 |
[15주 1일차] 스프링 MVC 개발 환경 설정 (0) | 2024.01.15 |
[15주 1일차] 스프링과 스프링 MVC (1) | 2024.01.15 |
- Total
- Today
- Yesterday