본문 바로가기

학원/복기

[Spring] MVC2 예제 (Spring)

 

참고

https://dncjf64.tistory.com/288

 

@Controller와 @RestController의 차이점

1.개요 Spring MVC의 @RestController은 @Controller와 @ResponseBody의 조합입니다. Spring 프레임 워크에서 RESTful 웹 서비스를 보다 쉽게 개발할 수 있도록 Spring 4.0에서 추가되었습니다. 근본적인 차이점은 @Contr

dncjf64.tistory.com

 

xyz.itwill09.spring 패키지 생성

 

web.xml

 

web.xml은 WAS가 실행될 때 프로젝트를 웹자원으로 변환하기 위해 필요한 정보를 제공하는 환경설정 파일을 말한다.

web.xml에서는 Listener 설정, Filter 설정, Servlet 설정, ErrorPage 설정, WelcomeFile 설정 등을 할 수 있다. 

(클래스를 웹프로그램으로 동작할 수 있도록 만들거나 필터 클래스를 필터로 동작할 수 있도록 만들어 주는 등..)

 

 

web.xml 에서 사용하는 엘리먼트

  • context-param : 모든 웹프로그램에게 필요한 값을 제공
    • contextConfigLocation 이름으로 스프링 컨테이너(WebApplicationContext 객체)에게 Spring Bean Configuration File의 경로를 제공해준다.
  • listener : WAS 프로그램이 시작될 때 Listener 클래스를 제공받아 객체로 생성 
    • Listener 클래스 : ServletContextListener 인터페이스를 상속받은 자식클래스 
    • contextInitialized 메소드 : Listener 객체 생성 후 자동 호출되는 메소드 - 초기화 작업 
    • contextDestryed 메소드 : Listener 객체 소멸 전 자동 호출되는 메소드 - 마무리 작업 
  • listener-class : ServletContextListener 인터페이스를 상속받은 자식클래스를 설정하고 
    • WAS 프로그램이 시작될때 ContextListener 클래스를 객체로 생성하고 contextInitialized 메소드를 호출하여 초기화 작업
    • ContextLoaderListener 클래스의 contextInitialized 메소드에서 스프링 컨테이너(Root Spring Container)를 생성하여 Spring Bean Configuration File을 제공받아 클래스를 Spring Bean(객체)으로 등록

 


 

web.xml 설정으로 Spring 프레임워크의 라이브러리에 의해 제공되는 DispatcherServlet 클래스를 사용할 수 있다.

→ Front Controller 기능의 클래스에서만 사용할 수 있는 스프링 컨테이너를 생성한다. 

 

스프링 컨테이너가 객체를 만들어 줄 것이기 때문에 HandlerMapping, ViewResolver 객체를 직접 생성해주지 않아도 된다.

 

init-param 엘리먼트를 이용해 클래스에 필요한 값을 제공해줄 수 있다.

 

load-on-startup 엘리먼트로 WAS 프로그램이 시작될 때 서블릿 클래스를 객체로 미리 생성할 수 있다.

  • 엘리먼트의 내용으로 설정된 정수값이 작을수록 먼저 서블릿 객체로 생성된다.

 

...
	<servlet>
		<servlet-name>springMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<!-- contextConfigLocation 이름으로 스프링 컨테이너에게 Srping Bean Configuration File의 경로를 제공
			=> 스프링 컨테이너는 현재 서블릿(Front Controller)에게만 Spring Bean을 사용할 수 있도록 제공한다.
			=> Srping Bean Configuration File은 엔터(Enter) 또는 [,] 및 [;]으로 구분하여 여러개 제공 가능 -->
			<param-name>contextConfigLocation</param-name>
			<param-value>
				/WEB-INF/spring/springMVC/mvc-context1.xml
				/WEB-INF/spring/springMVC/mvc-context2.xml
			</param-value>
		</init-param>
		<!-- load-on-startup -->
		<load-on-startup>0</load-on-startup>
	</servlet>
...

 

 

mvc-context.xml에 HandlerMapping, ViewResolver를 등록하면 가져다 사용할 수 있다. (객체 생성 X)

 

 

생성한 서블릿을 사용하기 위해선 servlet-mapping 설정을 해주어야 한다.

<servlet-mapping>
	<servlet-name>springMVC</servlet-name>
	<url-pattern>*.do</url-pattern>  <!-- .do 라고 요청하면 실행 -->
</servlet-mapping>

 


 

 

 

root-context.xml은 모든 Front Controller에서 객체로 사용될 클래스를  Spring Bean으로 등록하기 위한 Spring BEan Configuration File이다.

  • DAO 클래스 작성에 필요한 클래스를 Spring Bean으로 등록한다.
  • DataSource, SqlSessionFactory, SqlSession, TransactionManager 등..

 


 

mvc-context1.xml 파일에 등록할 요청 처리 클래스(모델 기능 제공), 즉 Controller 클래스를 선언한다. 

이때 Spring 프레임워크의 라이브러리로 제공되는 Controller 인터페이스를 상속받아 작성할 수 있다.

 

 

ModelView는 처리결과 및 응답처리를 위한 응답 관련 정보를 저장하기 위한 객체이다.

 

ModelAndView.addObject(String attributeName, Object attributeValue)

  • ModelAndView 객체에 처리결과를 속성값으로 저장하는 메소드이다. - Request Scope 
  • request.setAttribute() 메소드와 유사한 기능을 제공한다. 

ModelAndView.setViewName(String viewName)

  • ModelAndView 객체에 뷰이름(VeiwName)을 저장하는 메소드이다.
  • 컨트롤러에 의해 View 이름을 JSP 문서로 변경하여 포워드 이동 시킬 것이다. (응답 처리를 위해 사용한다.)

 

Product

@AllArgsConstructor
@Data
public class Product {
	private int num;
	private String name;
}

 

ListController

//모델 기능을 제공하기 위한 클래스 - 요청 처리 클래스
// => 클라이언트가 [/list.do]의 URL 주소로 요청한 경우 컨트롤러에 의해 실행될 요청 처리 클래스
public class ListController implements Controller {
	//클라이언트 요청에 의해 자동 호출되는 요청 처리 메소드
	// => ModelAndView 객체에 응답 관련 정보를 저장하여 반환한다
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//처리결과 및 응답처리를 위한 응답 관련 정보를 저장
		ModelAndView modelAndView=new ModelAndView();
		
		//데이터 처리 - Service 클래스의 메소드 호출
		List<Product> productList=new ArrayList<Product>();
		productList.add(new Product(1000, "컴퓨터"));
		productList.add(new Product(2000, "노트북"));
		productList.add(new Product(3000, "테블릿"));
		
		//ModelAndView 객체에 처리결과를 속성값으로 저장
		modelAndView.addObject("productList", productList);
		
		//ModelAndView 객체에 VeiwName을 저장
		modelAndView.setViewName("product_list");
		
		return modelAndView;
		
	}
	
}

 

VeiwController

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;

//모델 기능을 제공하기 위한 클래스 - 요청 처리 클래스
//=> 클라이언트가 [/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;
	}
	
}

 


springMVC 폴더 생성해 xml 파일 작성

 

mvc-context1.xml 파일에는 요청 처리 클래스(Model)를 Spring Bean으로 등록한다.

 

 

mvc-context1.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">

	<!--Spring 프레임워크의 라이브러의 Controller 인터페이스를 상속받아 작성한 
	요청 처리 클래스(Model)을 Srping Bean으로 등록-->
	<bean class="xyz.itwill09.spring.ListController" id="listController"/>
	<bean class="xyz.itwill09.spring.ViewController" id="viewController"/>
</beans>

각각 listController, viewController라는 객체로 만들어 진다. (미리 생성된다.)

 

 

Srping 프레임워크 라이브러리의 SimpleUrlHandlerMapping 클래스를 Spring Bean으로 등록해준다.

  • SimpleUrlHandlerMapping는 컨트롤러(DispatcherServlet)에게 클라이언트의 요청정보를 전달받아 요청 처리 클래스(Controller)의 객체(Spring Bean)을 반환하는 기능을 제공하는 객체이다. 
    • → mappings 필드에 Map 객체를 저장하여 요청정보와 Controller 객체를 저장한 엔트리를 추가해주어야 한다. 
...
	<!-- Srping 프레임워크 라이브러리의 SimpleUrlHandlerMapping 클래스를 Spring Bean으로 등록  -->
	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<!-- 맵키(MapKey)에는 클라이언트의 요청정보(Stirng)를 전달하고 맵값(MapValue)에는 
			요청 처리 클래스에 대한 Spring Bean의 beanName(String)을 전달하여 엔트리를 생성 -->
			<!-- => map 엘리먼트 대신 props 엘리먼트를 사용하여 Map 객체를 생성하여 필드에 의존성 주입 -->
			<props>
				<prop key="/list.do">listController</prop>
				<prop key="/view.do">viewController</prop>
			</props>
		</property>
	</bean>
...

 

 

 Spring 프레임워크의 라이브러리의 InternalResourceViewResolver 클래스를 Srping Bean으로 등록한다.

  • InternalResourceViewResolver는 뷰이름(ViewName)을 전달받아 응답 처리할 JSP 문서의 경로로 변환하여 반환하는 기능을 제공해주는 객체이다. 
    • prefix 필드와 suffix 필드에 JSP 문서 경로를 만들기 위한 값을 전달해주어야 한다.
      • prefix 필드에는 뷰이름 앞부분에 추가될 문자열을 저장한다. - 폴더
      • suffix 필드에는 뷰이름 뒷부분에 추가될 문자열을 저장한다. - 확장자
...
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/mvc"/>
		<property name="suffix" value=".jsp"/>
	</bean>
...

=> mvc-context2.xml에 만들어주어도 상관 없다.

 

 

 

jsp 문서로 출력해보자

 

product_list

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@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>

product_view

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- 제품정보를 제공받아 출력하는 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>