티스토리 뷰

반응형

강사 : 김호진 강사님

Spring 프레임워크: 교육 3일차

Spring MVC

Spring MVC의 개념

웹 개발을 위한 MVC 패턴이 적용된 Spirng Framework.

Spring 에서는 DispatcherServlet 클래스가 컨트롤러 역할을 수행하게 된다.

Spring MVC 의 주요 구성 요소

  • DispatcherServlet
  • HandlerMapping
  • Controller : 우리가 작성. 액션 처리.
  • ModelAndView
  • ViewResolver
  • View : 우리가 작성. 결과 출력.
  • web.xml : 우리가 작성. DispatcherServlet 서블릿 객체 등록.
  • dispatcher-servlet.xml : 우리가 작성.

※ MVC에서 주인공은 Controller다!!!

Spring MVC 실행 흐름

  • 사용자 요청        → DispatcherServlet
  • DispatcherServlet  → HandlerMapping 에 주소 분석 요청.
  • DispatcherServlet  → 특정 Controller 객체 호출 및 결과 수신. 결과는 ModelAndView 객체.
※ ModelAndView 객체 : View 객체 정보와 결과값이 들어있는 객체.
  • DispatcherServlet  → ViewResolver 에 View 객체 분석 요청.
  • DispatcherServlet  → 특정 View 객체에 Model 객체를 넘겨주고 결과 출력.

Spring MVC에서 내가 해야할 일

  • Controller : 액션 처리를 담당하는 Controller 클래스 작성. Controller 인터페이스를 구현하여 작성.
  • View : 결과 출력용 JSP 페이지 작성.
  • web.xml : 서블릿 주소와 DispatcherServlet 클래스 등록.
  • dispatcher-servlet.xml : 내가 작성한 사용자 정의 Controller 객체 등록. URL 매핑 주소 등록.


mvc01: Spring MVC 관련 실습

프로젝트 생성

mvc01 라는 이름의 Dynamic Web Project를 생성한다. (→ 실무에서는 Spring Project 생성)

톰캣 서버 등록

Java 하단의 Servers에서 Tomcat v8.5 Server at localhost > 마우스 오른쪽 버튼 클릭 > Add and Remove... 메뉴에서 기존에 있던 프로젝트들 모두 Remove All 하고, mvc01 Add해 다음과 같이 구성한다.

: port 8090

기타 환경 설정

폰트, 줄번호, 편집포맷, 인코딩 방식 등...

라이브러리 등록

WebContent > WEB-INF > lib 경로에 등록

경로1 : C:\spring-framework-with-docs\spring-framework-3.0.2.RELEASE\dist

  • 파일① → org.springframework.aop-3.0.2.RELEASE.jar
  • 파일② → org.springframework.asm-3.0.2.RELEASE.jar
  • 파일③ → org.springframework.beans-3.0.2.RELEASE.jar
  • 파일④ → org.springframework.context-3.0.2.RELEASE.jar
  • 파일⑤ → org.springframework.core-3.0.2.RELEASE.jar
  • 파일⑥ → org.springframework.expression-3.0.2.RELEASE.jar
  • 파일⑦ → org.springframework.jdbc-3.0.2.RELEASE.jar
  • 파일⑧ → org.springframework.transaction-3.0.2.RELEASE.jar
  • 파일⑨ → org.springframework.web.servlet-3.0.2.RELEASE.jar
  • 파일⑩ → org.springframework.web-3.0.2.RELEASE.jar

경로2 : C:\spring-framework-dependencies\org.apache.commons\com.springsource.org.apache.commons.logging\1.1.1

  • 파일⑪ → com.springsource.org.apache.commons.logging-1.1.1.jar

경로3 : C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib

  • 파일⑫ → ojdbc6.jar

경로4 : E:\Downloads\8. JSTL\jakarta-taglibs-standard-1.1.2\lib

  • 파일⑬ → jstl.jar
  • 파일⑭ → standard.jar

물리적 파일 구성

  • HelloController.java    → 사용자 정의 컨트롤러 : com.test.mvc 패키지 경로에 구성
  • Hello.jsp               → 뷰 : 일단은 WebContent 경로에 직접 구성
  • web.xml                 → DispatcherServlet 을 프론트 컨트롤러로 등록 → 서블릿 매핑 : WebContent > WEB-INF 경로에 구성
  • dispatcher-servlet.xml  → 사용자 정의 컨트롤러 매핑 : WebContent > WEB-INF 경로에 구성

※ 이전의 실습 과정에서 스프링 관련 환경 설정 파일(xml)은 파일 이름의 구성을 임의로 설정하는 것이 가능하였지만 지금과 같은 실습 환경에서는 DispatcherServlet 이 이 이름을 가지는 파일을 찾아서 해당 설정 내용을 읽어들이는 상황이기 때문에 임의로 이름을 변경해서는 안된다.

HelloController.java

/*=================================
   HelloController.java
   - 액션 처리 페이지
   - Controller 인터페이스 구현
=================================*/

package com.test.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class HelloController implements Controller
{
	
	// Controller 인터페이스가 가지고 있는 메소드 오버라이딩
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		// 결과값으로 반환해 줄 ModelAndView 객체 생성
		ModelAndView mav = new ModelAndView();
		
		// View 페이지에 대한 정보 설정
		//-- 실제 View 페이지의 주소 설정
		mav.setViewName("Hello.jsp");
		
		// Model 객체 정보 설정
		//-- mav.addObject("식별자", "데이터");
		mav.addObject("hello", "Hello, SpringMVC World~!!!");
		//-- addObject() 는 setAttribute 한 것과 같은 효과
		
		// 결과 반환 → ModelAndView 객체
		return mav;
	}
	
}

Hello.jsp

if (!window.T) { window.T = {} } window.T.config = {"TOP_SSL_URL":"https://www.tistory.com","PREVIEW":false,"ROLE":"guest","PREV_PAGE":"","NEXT_PAGE":"","BLOG":{"id":2859455,"name":"miiingo","title":"miiingo riiingo","isDormancy":false,"nickName":"miiingo","status":"open","profileStatus":"normal"},"NEED_COMMENT_LOGIN":false,"COMMENT_LOGIN_CONFIRM_MESSAGE":"","LOGIN_URL":"https://www.tistory.com/auth/login/?redirectUrl=https://miiingo.tistory.com/35","DEFAULT_URL":"https://miiingo.tistory.com","USER":{"name":null,"homepage":null,"id":0,"profileImage":null},"SUBSCRIPTION":{"status":"none","isConnected":false,"isPending":false,"isWait":false,"isProcessing":false,"isNone":true},"IS_LOGIN":false,"HAS_BLOG":false,"IS_SUPPORT":false,"TOP_URL":"http://www.tistory.com","JOIN_URL":"https://www.tistory.com/member/join","ROLE_GROUP":"visitor"}; window.T.entryInfo = {"entryId":35,"isAuthor":false,"categoryId":669280,"categoryLabel":"교육 및 세미나"}; window.appInfo = {"domain":"tistory.com","topUrl":"https://www.tistory.com","loginUrl":"https://www.tistory.com/auth/login","logoutUrl":"https://www.tistory.com/auth/logout"}; window.initData = {}; window.TistoryBlog = { basePath: "", url: "https://miiingo.tistory.com", tistoryUrl: "https://miiingo.tistory.com", manageUrl: "https://miiingo.tistory.com/manage", token: "I7rcAfkLRUM6b3a1O4i3N0E7bPKNJHvfDBIKvyy+duAZ49V6OWMQuj25PcEZ7xIO" }; var servicePath = ""; var blogURL = ""; \n\nHello.jsp\n \n\n\n

기본적인 페이지 구성

\n\n\n

${hello }

\n\n\n\n"}}" data-ve-attributes="{"typeof":"mw:Extension/syntaxhighlight","about":"#mwt3"}">
<%@ page contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello.jsp</title>
</head>
<body>

<h1>기본적인 페이지 구성</h1>

<!-- EL 표현 -->
<h1>${hello }</h1>

</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<display-name>mvc01</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>

	<!-- Spring MVC 프레임워크 등록 -->
	<!-- - DispatcherServlet 객체 등록 -->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	</servlet>

	<!-- 요청하는 서블릿 주소를 확장자 형태로 등록 -->
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>*.nds</url-pattern>
	</servlet-mapping>


</web-app>

dispatcher-servlet.xml

\n\t\n\t\n\t\n\t\n\n\n"}}" data-ve-attributes="{"typeof":"mw:Extension/syntaxhighlight","about":"#mwt3"}">
<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation=" http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	<context:component-scan base-package="org.springframework.samples.petclinic.web" />

	<!-- ※ 『dispatcher-servlet.xml』 파일의 기본 설정 내용을 작성하는 과정에서
            스프링에서 제공하는 Document 를 참조해서 작성할 수 있도록 한다.
            → C:\spring-framework-with-docs\spring-framework-3.0.2.RELEASE\docs\spring-framework-reference\pdf
               경로의 spring-framework-reference.pdf 파일에서 
               페이지 이동 메뉴 450 페이지 (pdf 425 페이지) 의 내용을 기본 내용으로 작성할 수 있도록 한다. -->
               
	<!-- 이곳에서 해야 할 일은 각각의 사용자 정의 컨트롤러 객체 등록 및 URL 매핑을 하는 것이다. -->
	
	<!-- 사용자 정의 컨트롤러 객체 등록 -->
	<!-- - 『name=""』 속성에 URL 매핑 주소를 등록한다. -->
	<!--    이 때, 확장자는 web.xml 에 등록한 『.nds』 으로 구성한다. -->
	<!-- - 『class=""』 속성은 Controller 객체의 클래스 이름을 패키지 경로를 포함하여 등록한다. -->
	<bean name="/hello.nds" class="com.test.mvc.HelloController"></bean>
	<!-- → 사용자가 hello.nds 을 요청하면 HelloController 가 일을 할 수 있도록 해줘라~!!! 라는 의미 -->
</beans>

실행 테스트

코드 작성이 완료되면 Tomcat을 시작하고 웹 페이지에 접속해 출력 결과를 확인한다.

hello.nds

http://localhost:8090/mvc01/hello.nds

Hello.jsp

http://localhost:8090/mvc01/Hello.jsp

Hello.jsp 파일 이동

WebContent 경로에 위치한 Hello.jsp 파일을 /WEB-INF/view/Hello.jsp 경로에 위치시킨다.

-> view를 클라이언트에서 직접 이동 못함.


소스 수정

HelloController.java 파일에서 실제 View 페이지의 주소를 변경해준다.

"Hello.jsp" -> "/WEB-INF/view/Hello.jsp"

/*=================================
   HelloController.java
   - 액션 처리 페이지
   - Controller 인터페이스 구현
=================================*/

package com.test.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class HelloController implements Controller
{
	
	// Controller 인터페이스가 가지고 있는 메소드 오버라이딩
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		// 결과값으로 반환해 줄 ModelAndView 객체 생성
		ModelAndView mav = new ModelAndView();
		
		// View 페이지에 대한 정보 설정
		//-- 실제 View 페이지의 주소 설정
		mav.setViewName("/WEB-INF/view/Hello.jsp");
		
		// Model 객체 정보 설정
		//-- mav.addObject("식별자", "데이터");
		mav.addObject("hello", "Hello, SpringMVC World~!!!");
		//-- addObject() 는 setAttribute 한 것과 같은 효과
		
		// 결과 반환 → ModelAndView 객체
		return mav;
	}
	
}

실행 테스트 2

코드 작성이 완료되면 Tomcat을 시작하고 웹 페이지에 접속해 출력 결과를 확인한다.

hello.nds

http://localhost:8090/mvc01/hello.nds

Hello.jsp

http://localhost:8090/mvc01/WEB-INF/view/Hello.jsp


mvc02: Spring MVC 관련 실습

프로젝트 생성

mvc02 라는 이름의 Dynamic Web Project를 생성한다. (→ 실무에서는 Spring Project 생성)

: 데이터 송신 / 수신 실습 프로젝트

라이브러리 등록

WebContent > WEB-INF > lib 경로에 ... mvc01에서 등록했던 항목들 복사&붙여넣기

물리적 파일 구성

  • SendController.java    → 사용자 정의 컨트롤러 : com.test.mvc 패키지 경로에 구성
  • Send.jsp                → 뷰 : WebContent > WEB-INF > view 경로에 직접 구성
  • ReceiveController.java → 사용자 정의 컨트롤러 : com.test.mvc 패키지 경로에 구성
  • Receive.jsp            → 뷰 : WebContent > WEB-INF > view 경로에 직접 구성
  • web.xml                  → DispatcherServlet 을 프론트 컨트롤러로 등록 → 서블릿 매핑 : WebContent > WEB-INF 경로에 구성 → mvc01 에서 사용했던 파일 복사&붙여넣기
  • dispatcher-servlet.xml  → 사용자 정의 컨트롤러 매핑 : WebContent > WEB-INF 경로에 구성 → mvc01 에서 사용했던 파일 복사&붙여넣기 후 수정

SendController.java

/*============================
   SendController.java
   - 사용자 정의 컨트롤러
============================*/

package com.test.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class SendController implements Controller
{

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		// 결과값으로 반환할 ModelAndView 객체 생성
		ModelAndView mav = new ModelAndView();
		
		// 뷰 지정
		mav.setViewName("/WEB-INF/view/Send.jsp");

		// 결과값 반환
		return mav;
	}
	
}

Send.jsp

if (!window.T) { window.T = {} } window.T.config = {"TOP_SSL_URL":"https://www.tistory.com","PREVIEW":false,"ROLE":"guest","PREV_PAGE":"","NEXT_PAGE":"","BLOG":{"id":2859455,"name":"miiingo","title":"miiingo riiingo","isDormancy":false,"nickName":"miiingo","status":"open","profileStatus":"normal"},"NEED_COMMENT_LOGIN":false,"COMMENT_LOGIN_CONFIRM_MESSAGE":"","LOGIN_URL":"https://www.tistory.com/auth/login/?redirectUrl=https://miiingo.tistory.com/35","DEFAULT_URL":"https://miiingo.tistory.com","USER":{"name":null,"homepage":null,"id":0,"profileImage":null},"SUBSCRIPTION":{"status":"none","isConnected":false,"isPending":false,"isWait":false,"isProcessing":false,"isNone":true},"IS_LOGIN":false,"HAS_BLOG":false,"IS_SUPPORT":false,"TOP_URL":"http://www.tistory.com","JOIN_URL":"https://www.tistory.com/member/join","ROLE_GROUP":"visitor"}; window.T.entryInfo = {"entryId":35,"isAuthor":false,"categoryId":669280,"categoryLabel":"교육 및 세미나"}; window.appInfo = {"domain":"tistory.com","topUrl":"https://www.tistory.com","loginUrl":"https://www.tistory.com/auth/login","logoutUrl":"https://www.tistory.com/auth/logout"}; window.initData = {}; window.TistoryBlog = { basePath: "", url: "https://miiingo.tistory.com", tistoryUrl: "https://miiingo.tistory.com", manageUrl: "https://miiingo.tistory.com/manage", token: "I7rcAfkLRUM6b3a1O4i3N0E7bPKNJHvfDBIKvyy+duAZ49V6OWMQuj25PcEZ7xIO" }; var servicePath = ""; var blogURL = ""; \n\nSend.jsp\n \n\n\n
\n\t

데이터 전송 실습

\n\t
\n
\n\n
\n\t\n\t
\n\t\t이름 : \n\t\t
\n\t\t\n\t
\n
\n\n\n\n"}}" data-ve-attributes="{"typeof":"mw:Extension/syntaxhighlight","about":"#mwt3"}">
<%@ page contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Send.jsp</title>
</head>
<body>

<div>
	<h1>데이터 전송 실습</h1>
	<hr>
</div>

<div>
	<!-- form 엘리먼트의 action 속성은 데이터를 넘기며 요청하게 되는 페이지 -->
	<form action="receive.nds" method="post">
		이름 : <input type="text" name="userName">
		<br>
		<button type="submit">전송</button>
	</form>
</div>

</body>
</html>

ReceiveController.java

/*============================
   ReceiveController.java
   - 사용자 정의 컨트롤러
============================*/

package com.test.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class ReceiveController implements Controller
{

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		// 결과값으로 반환할 ModelAndView 객체 생성
		ModelAndView mav = new ModelAndView();
		
		// Send.jsp 로부터 넘어온 데이터 수신
		request.setCharacterEncoding("UTF-8");
		String userName = request.getParameter("userName");
		
		// 뷰에 값을 넘겨주기 위해서 객체 추가
		mav.addObject("userName", userName);
		
		// 뷰 지정
		mav.setViewName("/WEB-INF/view/Receive.jsp");
		
		// 결과값 반환
		return mav;
	}

}

Receive.jsp

if (!window.T) { window.T = {} } window.T.config = {"TOP_SSL_URL":"https://www.tistory.com","PREVIEW":false,"ROLE":"guest","PREV_PAGE":"","NEXT_PAGE":"","BLOG":{"id":2859455,"name":"miiingo","title":"miiingo riiingo","isDormancy":false,"nickName":"miiingo","status":"open","profileStatus":"normal"},"NEED_COMMENT_LOGIN":false,"COMMENT_LOGIN_CONFIRM_MESSAGE":"","LOGIN_URL":"https://www.tistory.com/auth/login/?redirectUrl=https://miiingo.tistory.com/35","DEFAULT_URL":"https://miiingo.tistory.com","USER":{"name":null,"homepage":null,"id":0,"profileImage":null},"SUBSCRIPTION":{"status":"none","isConnected":false,"isPending":false,"isWait":false,"isProcessing":false,"isNone":true},"IS_LOGIN":false,"HAS_BLOG":false,"IS_SUPPORT":false,"TOP_URL":"http://www.tistory.com","JOIN_URL":"https://www.tistory.com/member/join","ROLE_GROUP":"visitor"}; window.T.entryInfo = {"entryId":35,"isAuthor":false,"categoryId":669280,"categoryLabel":"교육 및 세미나"}; window.appInfo = {"domain":"tistory.com","topUrl":"https://www.tistory.com","loginUrl":"https://www.tistory.com/auth/login","logoutUrl":"https://www.tistory.com/auth/logout"}; window.initData = {}; window.TistoryBlog = { basePath: "", url: "https://miiingo.tistory.com", tistoryUrl: "https://miiingo.tistory.com", manageUrl: "https://miiingo.tistory.com/manage", token: "I7rcAfkLRUM6b3a1O4i3N0E7bPKNJHvfDBIKvyy+duAZ49V6OWMQuj25PcEZ7xIO" }; var servicePath = ""; var blogURL = ""; \n\nReceive.jsp\n \n\n\n\t
\n\t\t

데이터 전송 실습 → 데이터 수신

\n\t\t
\n\t
\n\n\t
\n\t\t

안녕하세요 [${userName }]님

\n\t\t

매우매우 반갑습니다~!!!

\n\t
\n\n\n\n"}}" data-ve-attributes="{"typeof":"mw:Extension/syntaxhighlight","about":"#mwt3"}">
<%@ page contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Receive.jsp</title>
</head>
<body>

	<div>
		<h1>데이터 전송 실습 → 데이터 수신</h1>
		<hr>
	</div>

	<div>
		<h2>안녕하세요 [${userName }]님</h2>
		<h2>매우매우 반갑습니다~!!!</h2>
	</div>

</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<display-name>mvc01</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>

	<!-- Spring MVC 프레임워크 등록 -->
	<!-- - DispatcherServlet 객체 등록 -->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	</servlet>

	<!-- 요청하는 서블릿 주소를 확장자 형태로 등록 -->
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>*.nds</url-pattern>
	</servlet-mapping>


</web-app>

dispatcher-servlet.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation=" http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	<context:component-scan base-package="org.springframework.samples.petclinic.web" />

	<!-- ※ 『dispatcher-servlet.xml』 파일의 기본 설정 내용을 작성하는 과정에서
            스프링에서 제공하는 Document 를 참조해서 작성할 수 있도록 한다.
            → C:\spring-framework-with-docs\spring-framework-3.0.2.RELEASE\docs\spring-framework-reference\pdf
               경로의 spring-framework-reference.pdf 파일에서 
               페이지 이동 메뉴 450 페이지 (pdf 425 페이지) 의 내용을 기본 내용으로 작성할 수 있도록 한다. -->
               
	<!-- 이곳에서 해야 할 일은 각각의 사용자 정의 컨트롤러 객체 등록 및 URL 매핑을 하는 것이다. -->
	
	
	<bean name="/send.nds" class="com.test.mvc.SendController"></bean>
	
	<bean name="/receive.nds" class="com.test.mvc.ReceiveController"></bean>
	
	
</beans>

실행 테스트

http://localhost:8090/mvc02/send.nds

이름 항목에 값을 입력하고 전송 버튼을 클릭하면 해당 이름이 화면에 출력된다.


mvc03: Spring MVC 관련 실습

프로젝트 생성

mvc03 이라는 이름의 Dynamic Web Project를 생성한다. (→ 실무에서는 Spring Project 생성)

: 데이터 송신 / 수신 실습 프로젝트 (데이터베이스 연동 실습)

라이브러리 등록

SpringMVC 환경 설정을 위한 라이브러리 등록 및 기본 설정들을 mvc00에 있는 src 와 WebContent 를 복사&붙여넣기(덮어쓰기) 로 대체.

구현할 기능

  • 이름, 전화번호를 입력받아 데이터베이스에 저장.
  • 해당 리스트를 읽어다가 화면에 출력.

화면 구성

회원관리

--------------------------------------

이름 : [          ] → <input type="text">

전화 : [          ] → <input type="text">

<  전 송       >    → <button>

전체 인원 수 2명

------------------------------------

번호       이름         전화번호

1        최진규      010-1111-1111

2        김준협      010-2222-2222

물리적 파일 구성

  • mvc03_scott.sql              → 데이터베이스 관련 객체 구성
  • MemberDTO.java               → 사용자 정의 자료형 클래스(DTO)
  • IMemberDAO.java              → 인터페이스
  • MemberDAO.java               → 데이터베이스 액션 처리 전용 클래스. Connection 객체에 대한 의존성 주입(DI). setter 메소드 구성(의존성 주입을 위한 준비)
  • MemberListController.java    → 사용자 정의 컨트롤러 : com.test.mvc 패키지 경로에 구성. 리스트 출력 액션 처리 클래스. DAO 객체에 대한 의존성 주입(DI). setter 메소드 구성(의존성 주입을 위한 준비)
  • MemberList.jsp               → 뷰 : WebContent > WEB-INF > view 경로에 구성. 회원 리스트 출력을 위한 뷰. 회원 정보를 추가할 수 있도록 폼 화면 구성.
  • MemberInsertController.java  → 사용자 정의 컨트롤러 : com.test.mvc 패키지 경로에 구성. 리스트 출력 액션 처리 클래스. DAO 객체에 대한 의존성 주입(DI). setter 메소드 구성(의존성 주입을 위한 준비)
  • dispatcher-servlet.xml       → 사용자 정의 컨트롤러 매핑 : WebContent > WEB-INF 경로에 구성. 사용자 요청 주소 등록. SimpleDriverDataSource 객체 등록. (기본 JDBC 로 구성해도 무방함). 의존객체 주입 설정. DAO 객체 등록
  • web.xml                      → DispatcherServlet 을 프론트 컨트롤러로 등록 → 서블릿 매핑 : WebContent > WEB-INF 경로에 구성

mvc03_scott.sql

SELECT USER
FROM DUAL;
--==>> SCOTT


-- 데이터베이스 준비

--○ 테이블 생성
CREATE TABLE TBL_MEMBERLIST
( MID   NUMBER
, NAME  VARCHAR2(30)
, TEL   VARCHAR2(40)
, CONSTRAINT MEMBERLIST_MID_PK PRIMARY KEY(MID)
);
--==>> Table TBL_MEMBERLIST이(가) 생성되었습니다.

--○ 시퀀스 생성
CREATE SEQUENCE MEMBERLISTSEQ
NOCACHE;
--==>> Sequence MEMBERLISTSEQ이(가) 생성되었습니다.

--○ 데이터 입력
INSERT INTO TBL_MEMBERLIST(MID, NAME, TEL) VALUES(MEMBERLISTSEQ.NEXTVAL, '명소희', '010-1111-1111');
--==>> 1 행 이(가) 삽입되었습니다.

--○ 커밋
COMMIT;

--○ 확인
SELECT MID, NAME, TEL FROM TBL_MEMBERLIST;
--==>> 1	임미영	010-3047-7557

--○ 레코드 수 확인
SELECT COUNT(*) AS COUNT FROM TBL_MEMBERLIST;
--==>> 1

MemberDTO.java

package com.test.mvc;


public class MemberDTO
{
	public String mid, name, tel;

	public String getMid()
	{
		return mid;
	}

	public void setMid(String mid)
	{
		this.mid = mid;
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getTel()
	{
		return tel;
	}

	public void setTel(String tel)
	{
		this.tel = tel;
	}
	
	
}

IMemberDAO.java

package com.test.mvc;

import java.sql.SQLException;
import java.util.ArrayList;

public interface IMemberDAO
{
	public ArrayList<MemberDTO> lists() throws SQLException, ClassNotFoundException;
	public int memberInsert(MemberDTO member) throws SQLException, ClassNotFoundException;
	public int count() throws SQLException, ClassNotFoundException;
	
}

MemberDAO.java

package com.test.mvc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.sql.DataSource;


public class MemberDAO implements IMemberDAO
{
	private DataSource dataSource;

	public void setDataSource(DataSource dataSource)
	{
		this.dataSource = dataSource;
	}

	// 전체 리스트 출력 메소드
	@Override
	public ArrayList<MemberDTO> lists() throws SQLException, ClassNotFoundException
	{
		ArrayList<MemberDTO> result = new ArrayList<MemberDTO>();

		// DB 연결
		/*
		Class.forName("oracle.jdbc.driver.OracleDriver");
		String url = "jdbc:oracle:thin:scott/tiger@localhost:1521:xe";
		Connection conn = DriverManager.getConnection(url);
		*/
		Connection conn = dataSource.getConnection();

		String sql = "SELECT MID, NAME, TEL FROM TBL_MEMBERLIST ORDER BY MID";

		PreparedStatement pstmt = conn.prepareStatement(sql);

		ResultSet rs = pstmt.executeQuery();

		while (rs.next())
		{
			MemberDTO dto = new MemberDTO();
			dto.setMid(rs.getString("MID"));
			dto.setName(rs.getString("NAME"));
			dto.setTel(rs.getString("TEL"));

			result.add(dto);
		}

		rs.close();
		pstmt.close();

		return result;
	}

	// 멤버 추가 메소드
	@Override
	public int memberInsert(MemberDTO member) throws SQLException, ClassNotFoundException
	{
		int result = 0;

		// DB 연결
		/*
		Class.forName("oracle.jdbc.driver.OracleDriver");
		String url = "jdbc:oracle:thin:scott/tiger@localhost:1521:xe";
		Connection conn = DriverManager.getConnection(url);
		*/
		Connection conn = dataSource.getConnection();

		String sql = "INSERT INTO TBL_MEMBERLIST(MID, NAME, TEL) VALUES(MEMBERLISTSEQ.NEXTVAL, ?, ?)";

		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, member.getName());
		pstmt.setString(2, member.getTel());

		result = pstmt.executeUpdate();
		
		pstmt.close();

		return result;
	}

	@Override
	public int count() throws SQLException, ClassNotFoundException
	{
		int result = 0;

		// DB 연결
		/*
		Class.forName("oracle.jdbc.driver.OracleDriver");
		String url = "jdbc:oracle:thin:scott/tiger@localhost:1521:xe";
		Connection conn = DriverManager.getConnection(url);
		*/
		Connection conn = dataSource.getConnection();
		
		String sql = "SELECT COUNT(*) AS COUNT FROM TBL_MEMBERLIST";
		
		PreparedStatement pstmt = conn.prepareStatement(sql);
		
		ResultSet rs = pstmt.executeQuery();
		
		while (rs.next())
		{
			result = rs.getInt("COUNT");
		}
		
		rs.close();
		pstmt.close();
		
		return result;
	}

}

MemberListController.java

package com.test.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class MemberListController implements Controller
{
	// 인터페이스 자료형 속성 구성
	private IMemberDAO dao;

	public void setDao(IMemberDAO dao)
	{
		this.dao = dao;
	}

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		ModelAndView mav = new ModelAndView();

		// 뷰에 값을 넘겨주기 위해서 객체 추가
		mav.addObject("lists", dao.lists());
		mav.addObject("count", dao.count());

		// 뷰 지정
		mav.setViewName("/WEB-INF/view/MemberList.jsp");

		return mav;
	}

}

MemberList.jsp

if (!window.T) { window.T = {} } window.T.config = {"TOP_SSL_URL":"https://www.tistory.com","PREVIEW":false,"ROLE":"guest","PREV_PAGE":"","NEXT_PAGE":"","BLOG":{"id":2859455,"name":"miiingo","title":"miiingo riiingo","isDormancy":false,"nickName":"miiingo","status":"open","profileStatus":"normal"},"NEED_COMMENT_LOGIN":false,"COMMENT_LOGIN_CONFIRM_MESSAGE":"","LOGIN_URL":"https://www.tistory.com/auth/login/?redirectUrl=https://miiingo.tistory.com/35","DEFAULT_URL":"https://miiingo.tistory.com","USER":{"name":null,"homepage":null,"id":0,"profileImage":null},"SUBSCRIPTION":{"status":"none","isConnected":false,"isPending":false,"isWait":false,"isProcessing":false,"isNone":true},"IS_LOGIN":false,"HAS_BLOG":false,"IS_SUPPORT":false,"TOP_URL":"http://www.tistory.com","JOIN_URL":"https://www.tistory.com/member/join","ROLE_GROUP":"visitor"}; window.T.entryInfo = {"entryId":35,"isAuthor":false,"categoryId":669280,"categoryLabel":"교육 및 세미나"}; window.appInfo = {"domain":"tistory.com","topUrl":"https://www.tistory.com","loginUrl":"https://www.tistory.com/auth/login","logoutUrl":"https://www.tistory.com/auth/logout"}; window.initData = {}; window.TistoryBlog = { basePath: "", url: "https://miiingo.tistory.com", tistoryUrl: "https://miiingo.tistory.com", manageUrl: "https://miiingo.tistory.com/manage", token: "I7rcAfkLRUM6b3a1O4i3N0E7bPKNJHvfDBIKvyy+duAZ49V6OWMQuj25PcEZ7xIO" }; var servicePath = ""; var blogURL = ""; \n\nMemberList.jsp\n \n\n\n\t
\n\t\t

회원 관리

\n\t\t
\n\t
\n\n\t
\n\t\t
\n\t\t\t이름 :
\n\t\t\t전화 :
\n\t\t\t
\n\t\t
\n\t\t${alert }\n\t
\n\n\t
\n\t\t

전체 인원 수 ${count }명

\n\t\t
\n\t
\n\n\t
\n\t\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t
번호이름전화번호
${dto.mid} ${dto.name} ${dto.tel}
\n\n\t
\n\n\n\n"}}" data-ve-attributes="{"typeof":"mw:Extension/syntaxhighlight","about":"#mwt3"}">
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MemberList.jsp</title>
</head>
<body>

	<div>
		<h1>회원 관리</h1>
		<hr>
	</div>

	<div>
		<form action="memberinsert.nds" method="post" id="memberForm">
			이름 : <input type="text" name="name" id="name"><br> 
			전화 : <input type="text" name="tel" id="tel"><br>
			<button type="submit" id="submitBtn">전송</button><br>
		</form>
		${alert }
	</div>

	<div>
		<h2>전체 인원 수 ${count }명</h2>
		<hr>
	</div>

	<div>
		<table border="1" width="250">
		<tr>
			<th>번호</th>
			<th>이름</th>
			<th>전화번호</th>
		</tr>
		
		<c:forEach var="dto" items="${lists}">
		<tr>
			<td> ${dto.mid} </td>
			<td> ${dto.name} </td>
			<td> ${dto.tel} </td>
		</tr>
		</c:forEach>
		
		</table>

	</div>

</body>
</html>

MemberInsertController.java

package com.test.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class MemberInsertController implements Controller
{
	// 인터페이스 자료형 속성 구성
	private IMemberDAO dao;

	public void setDao(IMemberDAO dao)
	{
		this.dao = dao;
	}

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		ModelAndView mav = new ModelAndView();
		
		MemberDTO dto = new MemberDTO();

		// MemberList.jsp 로부터 넘어온 데이터 수신
		request.setCharacterEncoding("UTF-8");
		dto.setName(request.getParameter("name"));
		dto.setTel(request.getParameter("tel"));
		
		int result = dao.memberInsert(dto);
		
		if(result == 1)
			mav.addObject("alert", "전송이 완료되었습니다.");
		else
			mav.addObject("alert", "전송이 실패했습니다.");
		
		// 뷰 지정
		mav.setViewName("memberlist.nds");

		return mav;
	}

}

dispatcher-servlet.xml

\n\t\t -->\n\n\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\n\n\t\n\t\t\n\t\t\t\n\t\t\n\t\n\n\t\n\t\t\n\t\t\t\n\t\t\n\t\n\n\t\n\t\t\n\t\t\t\n\t\t\n\t\n\t\n\n\n"}}" data-ve-attributes="{"typeof":"mw:Extension/syntaxhighlight","about":"#mwt3"}">
<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation=" http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	<context:component-scan base-package="org.springframework.samples.petclinic.web" />

	<!-- 이곳에서 해야 할 일은 각각의 사용자 정의 컨트롤러 객체 등록 및 URL 매핑을 하는 것이다. -->

	<!-- <bean id="memberDAO" class="com.test.mvc.MemberDAO"></bean> <bean name="/member.nds" 
		class="com.test.mvc.MemberListController"> <property name="dao"> <ref bean="memberDAO"/> 
		</property> </bean> -->

	<bean id="localDataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="tiger"></property>
	</bean>

	<bean id="memberDAO" class="com.test.mvc.MemberDAO">
		<property name="dataSource">
			<ref bean="localDataSource" />
		</property>
	</bean>

	<bean name="/memberlist.nds" class="com.test.mvc.MemberListController">
		<property name="dao">
			<ref bean="memberDAO" />
		</property>
	</bean>

	<bean name="/memberinsert.nds" class="com.test.mvc.MemberInsertController">
		<property name="dao">
			<ref bean="memberDAO" />
		</property>
	</bean>
	
</beans>

web.xml

dd<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<display-name>mvc01</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>

	<!-- Spring MVC 프레임워크 등록 -->
	<!-- - DispatcherServlet 객체 등록 -->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	</servlet>

	<!-- 요청하는 서블릿 주소를 확장자 형태로 등록 -->
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>*.nds</url-pattern>
	</servlet-mapping>


</web-app>


반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함