반응형
- Spring 프레임워크에서는 Spring Container가 DispatcherServlet, HandlerMapping, ViewResolver을 만들어 제공해줌
- 하지만 사용하기 위해서는 몇 가지 설정이 필요함
- web.xml : DispatcherServlet을 서블릿 웹프로그램으로 등록
- Spring Bean Configuration File.xml : HandlerMapping , ViewResolver을 Spring Bean으로 등록
01. Spring프레임워크에서 MVC 패턴 만드는 단계
1) 문제점 - 스키마 기반의 SpringMVC
- Command 패턴을 이용함 : 하나의 요청에 대한 하나의 처리 객체
- 클라이언트의 요청이 많아질수록 요청을 처리하는 클래스(Controller를 상속받은 Model 클래스) 도 많아져야함
- 스프링 빈도 너무 많아짐
- URL 주소도 많이 매핑시켜야함
- 유지보수의 큰 문제가 발생할 수 있음
2) 해결법 - 어노테이션 기반의 SpringMVC
- 하나의 객체 내 다수의 메소드로 작성 (하나의 요청에 대한 하나의 메소드) 가능
- 어노테이션을 통해 수동 매핑을 이용함
02. 스프링빈 환경설정파일(Spring Bean Configuration File)
💖 [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>"
xmlns:tx="<http://www.springframework.org/schema/tx>"
xsi:schemaLocation="<http://www.springframework.org/schema/beans> <https://www.springframework.org/schema/beans/spring-beans.xsd>
<http://www.springframework.org/schema/tx> <http://www.springframework.org/schema/tx/spring-tx.xsd>">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- root-context.xml : 모든 Front Controller에서 객체로 사용될 클래스를 Spring Bean으로
등록하기 위한 Spring Bean Configuration File -->
<!-- => DAO 클래스 작성에 필요한 클래스를 Spring Bean으로 등록 -->
<!-- => DataSource, SqlSessionFactory, SqlSession, TransactionManager 등 -->
<!-- DataSource 관련 클래스를 Spring Bean으로 등록 - DBCP(DataBase Connection Pool) -->
<!-- => DataSource 객체 필드에 Connection 객체 생성에 필요한 값을 인젝션 처리 -->
<!--
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="username" value="scott"/>
<property name="password" value="tiger"/>
</bean>
-->
<!-- 퍼시스턴스 프레임워크(Persistence Framework)에서 발생되는 로그 이벤트를 전달받아
Spring Framework에서 처리하기 위해 driverClassName 필드값과 url 필드값을 log4jdbc-log4j2-jdbc4
라이브러리에서 제공하는 값으로 변경 -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"/>
<property name="url" value="jdbc:log4jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="username" value="scott"/>
<property name="password" value="tiger"/>
</bean>
<!-- SqlSessionFactory 관련 클래스를 Spring Bean으로 등록 -->
<!-- => SqlSessionFactoryBean 객체 필드에 객체 생성에 필요한 값을 인젝션 처리 -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactoryBean">
<!-- configLocation 필드에 Mybatis Framework의 환경설정파일의 경로가 저장되도록 인젝션 처리 -->
<!-- => SpringMVC Framework에서 사용하는 스프링 컨테이너(WebApplicationContext 객체)는
[src/main/webapp] 폴더를 웹자원의 최상위 폴더로 처리하여 환경설정파일의 경로를 제공 -->
<!-- <property name="configLocation" value="/WEB-INF/spring/mybatis-config.xml"/> -->
<!-- [src/main/java] 폴더 또는 [src/main/resources] 폴더에 환경설정파일을 작성한 경우
classpath 접두사를 사용하면 스프링 컨테이너(WebApplicationContext 객체)로 접근 가능 -->
<!-- => 폴더의 패키지에 작성된 환경설정파일은 파일 시스템 형식으로 경로를 표현하여 접근 가능 -->
<!-- <property name="configLocation" value="classpath:xyz/itwill/config/mybatis-config.xml"/> -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- dataSource 필드에 DataSource 관련 클래스의 Spring Bean이 저장되도록 인젝션 처리 - DI -->
<!-- => Mybatis 환경설정파일에서 environment 엘리먼트와 유사한 기능 제공 -->
<property name="dataSource" ref="dataSource"/>
<!-- typeAliasesPackage 필드에 DTO 클래스를 작성한 패키지가 저장되도록 인젝션 처리 -->
<!-- => XML 기반의 매퍼파일(MapperFile)에서 Java 자료형 대신 사용할 별칭을 제공하기 위한 기능 -->
<!-- => Mybatis 환경설정파일에서 typeAliases 엘리먼트의 package 엘리먼트와 유사한 기능 제공 -->
<property name="typeAliasesPackage" value="xyz.itwill10.dto"/>
<!-- mapperLocations 필드에 List 객체를 생성하여 저장되도록 인젝션 처리 -->
<!-- => List 객체에는 XML 기반의 매퍼 파일의 경로가 요소값으로 저장되도록 추가 - 매퍼 등록 -->
<!-- => Mybatis 환경설정파일에서 mappers 엘리먼트의 package 엘리먼트와 유사한 기능 제공 -->
<property name="mapperLocations">
<list>
<!-- [src/main/java] 폴더의 패키지에 매퍼 파일을 작성하기 위한 classpath 접두사 사용 -->
<value>classpath:xyz/itwill10/mapper/*.xml</value>
</list>
</property>
</bean>
<!-- SqlSession 관련 클래스를 Spring Bean으로 등록 -->
<!-- => SqlSessionTemplate 클래스로 객체를 생성하기 위한 생성자 매개변수에 SqlSessionFactoryBean
객체를 전달하여 필드 초기화 처리 - DI -->
<!-- destroy-method 속성을 사용하여 Spring Bean 소멸전 clearCache 메소드가 자동 호출되도록 설정 -->
<!-- => clearCache 메소드는 SqlSessionTemplate 객체 소멸전 SqlSessionTemplate 객체에 의해
사용된 JDBC 관련 객체를 정리하는 메소드 -->
<!-- => DAO 클래스의 메소드에서 SqlSession 객체 사용후 close() 메소드를 호출하지 않도록 설정 -->
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession" destroy-method="clearCache">
<constructor-arg ref="sqlSessionFactoryBean"/>
</bean>
<!-- TransactionManager 관련 클래스를 Spring Bean으로 등록 -->
<!-- => Spring Bean의 식별자(beanName)을 반드시 [transactionManager]로 설정 -->
<!-- => dataSource 필드에 DataSource 관련 클래스의 Spring Bean을 인젝션 처리 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- annotation-driven : @Transactional 어노테이션을 사용하여 TransactionManager 객체로
트렌젝션 처리 기능을 제공하기 위한 엘리먼트 -->
<!-- => tx 네임스페이스로 spring-tx.xsd 파일을 제공받아 엘리먼트 작성 -->
<tx:annotation-driven/>
</beans>
💖mvc-context1.xml (HandlerMapping등록)
<?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>">
<!--1. Model객체 Spring Bean으로 등록-->
<!-- Spring Framework 라이브러리 Controller 인터페이스를 상속받은 자식클래스를 Spring Bean으로 등록 -->
<bean class="xyz.itwill09.spring.ListController" id="listController"/>
<bean class="xyz.itwill09.spring.ViewController" id="viewController"/>
<!--2.HandlerMapping객체 Spring Bean으로 등록-->
<!-- Spring Framework 라이브러리의 SimpleUrlHandlerMapping 클래스를 Spring Bean으로 등록 -->
<!-- => SimpleUrlHandlerMapping 객체 : 컨트롤러(DispatcherServlet)에게 클라이언트의 요구사항을
전달받아 요청 처리 클래스의 객체(Spring Bean)를 반환하는 기능 제공 -->
<!-- => mappings 필드에 Map 객체를 저장하여 엔트리(Entry) 추가 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<!-- 맵키(MapKey)는 클라이언트의 요구사항(String)을 전달하고 맵값(MapValue)은
요청 처리 클래스에 Spring Bean에 대한 beanName(String)을 전달하여 Map 객체의
엔트리로 추가 - map 엘리먼트 대신 props 엘리먼트 사용 -->
<property name="mappings">
<props>
<prop key="/list.do">listController</prop>
<prop key="/view.do">viewController</prop>
</props>
</property>
</bean>
</beans>
💖mvc-context2.xml (ViewResolver등록)
<?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>">
<!--1.ViewResolver객체 Spring Bean으로 등록-->
<!-- Spring Framework 라이브러리 InternalResourceViewResolver 클래스를 Spring Bean으로 등록 -->
<!-- InternalResourceViewResolver 객체 : 뷰이름(ViewName)을 전달받아 JSP 문서로 변환하여
반환하는 기능을 제공하는 객체 -->
<!-- => prefix 필드와 suffix 필드에 JSP 문서로 변환하기 위한 정보를 저장 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- prefix 필드 : 뷰이름 앞부분에 추가될 문자열 - 디렉토리 -->
<property name="prefix" value="/WEB-INF/mvc/"/>
<!-- suffix 필드 : 뷰이름 뒷부분에 추가될 문자열 - 확장자 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
03. [DTO]
Product.java
package xyz.itwill09.spring;
import lombok.AllArgsConstructor;
import lombok.Data;
@AllArgsConstructor
@Data
public class Product {
private int num;
private String name;
}
04. [🖤Model]
ListController.java - Command 패턴
package xyz.itwill09.spring;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
//Model 역할을 제공하기 위한 클래스 - 요청 처리 클래스
//=> Spring Framework 라이브러리의 Controller 인터페이스를 상속받아 작성
//=> 클라이언트가 [/list.do]의 URL 주소로 요청한 경우 컨트롤러에 의해 동작될 요청 처리 클래스
public class ListController implements Controller{
//요청 처리 메소드 - 클라이언트 요청에 의해 컨트롤러에 자동 호출
// => ModelAndView 객체에 응답 관련 정보를 저장하여 반환
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//ModelAndView 객체 : 처리결과 및 이동 관련 정보를 저장하기 위한 객체
ModelAndView modelAndView = new ModelAndView();
//데이타 처리
List<Product> productList = new ArrayList<Product>();
productList.add(new Product(1000, "컴퓨터"));
productList.add(new Product(2000, "노트북"));
productList.add(new Product(3000, "핸드폰"));
//요청에 대한 처리결과를 ModelAndView 객체의 속성값으로 저장
//ModelAndView.addObject(String attributeName, Object attributeValue) :
// => ModelAndView 객체에 처리결과를 속성값으로 저장하는 메소드 - Request Scope
// => request.setAttribute()의 메소드와 유사한 기능 제공
modelAndView.addObject("productList",productList);
//응답에 대한 이동 관련 정보(View)를 ModelAndView 객체 필드에 저장
//ModelAndView.setViewName(String viewName) : 뷰이름(ViewName)을 변경하는 메소드
// => 컨트롤러에 의해 뷰이름(ViewName)은 JSP 문서로 변경되어 포워드 이동 - 응답
modelAndView.setViewName("product_list");
return modelAndView;
}
}
ViewController.java - Command 패턴
package xyz.itwill09.spring;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
//Model 역활을 제공하기 위한 클래스 - 요청 처리 클래스
//=> 클라이언트가 [/view.do]의 URL 주소로 요청한 경우 컨트롤러에 의해 동작될 요청 처리 클래스
public class ViewController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("product",new Product(4000,"프린트"));
modelAndView.setViewName("product_view");
return modelAndView;
}
}
05. [🖤View]
WEB-INF > mvc > product_list.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@taglib prefix="c" uri="<http://java.sun.com/jsp/jstl/core>" %>
//<%-- 회원목록을 제공받아 출력하는 JSP 문서 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SPRING</title>
</head>
<body>
<h1>제품목록</h1>
<hr>
<c:forEach var="product" items="${productList}">
<p>제품번호 = ${product.num }, 제품이름 = ${product.name }</p>
</c:forEach>
</body>
</html>
WEB-INF > mvc >product_view.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@taglib prefix="c" uri="<http://java.sun.com/jsp/jstl/core>" %>
//<%-- 회원정보를 제공받아 출력하는 JSP 문서 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SPRING</title>
</head>
<body>
<h1>제품정보</h1>
<hr>
<p>제품번호 = ${product.num }, 제품이름 = ${product.name }</p>
</body>
</html>
반응형
'framework > spring mvc' 카테고리의 다른 글
[springMVC] 6. Front Controller에 의해 JSP 문서로 포워드 이동하여 응답되도록 뷰이름을 제공하는 방법 @RequestMapping (0) | 2024.08.04 |
---|---|
[springMVC] 5. 어노테이션 기반의 SPRING MVC (servlet-context.xml 설정, log4j.xml 수정) (0) | 2024.08.03 |
[springMVC] 3. 웹프로그램으로 만들기 위해 필요한 환경설정파일 (web.xml) (0) | 2024.08.02 |
[springMVC] 2. Spring의 MVC 패턴 동작의 이해를 위한 MVC 프레임워크 직접 구현 (0) | 2024.08.02 |
[springMVC] 1. MVC 아키텍쳐의 개념 (0) | 2024.08.02 |