티스토리 뷰

Spring

[Spring]스프링 MVC

dev23 2024. 8. 17. 14:36
반응형

- 스프링 프레임워크는 애플리케이션 개발에 필요한 여러 가지 기능을 미리 만들어서 제공한다.

- MVC 기능도 그중 하나이다.

- 스프링에서 제공하는 기능 사용법을 익히고 나면 MVC 기능을 일일이 만들 필요 없이 편리하게 MVC 기능을 사용할 있다.

- 스프링 지원 MVC 기능의 특징

  • 모델2 아키텍처를 지원한다.
  • 스프링과 다른 모듈과의 연계가 쉽다.
  • 타일즈나 사이트메시 같은 View 기술과의 연계가 쉽다.
  • 태그 라이브러리를 통해 message 출력, theme 적용 그리고 입력 폼을 보다쉽게 구현할 있다.

스프링 프레임워크 MVC 구조도

MVC 구조

 

구성 요소 설명
DispatcherServlet 클라이언트의 요청을 전달 받아 해당 요청에 대한 컨트롤러를 선택하여 클라이언트의 요청을 전달한다.
또한 컨트롤러가 반환한 값을 View 전달하여 알맞은 응답을 생성한다.
HandlerMapping 클라이언트가 요청한 URL을 처리할 컨트롤러를 지정한다.
Controller 클라이언트의 요청을 처리한 후 그 결과를 DispatcherServlet에게 전달한다.
ModelAndView 컨트롤러가 처리한 결과 선택에 필요한 정보를 저장한다.
ViewResolver 컨트롤러의 처리 결과를 전달할 뷰를 지정한다.
View 컨트롤러의 처리 결과 화면을 생성한다.

MVC 기능 수행 과정

수행 과정

 

  1. 브라우저가 DispatcerServlet에 URL로 접근하여 해당 정보를 요청한다.
  2. HandlerMapping에서 해당 요청에 대해 메핑된 컨트롤러가 있는지 요청한다.
  3. 매핑된 컨트롤러에 대해 처리를 요청한다.
  4. 컨트롤러가 클라이언트의 요청을 처리한 결과와 View 이름을 ModelAndView에 저장해서 DispatcherServlet으로
    반환한다.
  5. DispatcherServlet에서는 컨트롤러에서 보내온 View 이름을 ViewResolver로 보내 해당 View를 요청한다.
  6. ViewResolver는 요청한 View를 보낸다.
  7. View의 처리 결과를 DispatcerServlet으로 보낸다.
  8. DsipatcerServlet은 최종 결과를 브라우저로 전송한다.

SimpleUrlController

- 브라우저의 요청 URL 대해 미리 매핑해 놓은 컨트롤러를 호출해 컨트롤러에서 지정한 JSP 브라우저로

 전송하는 과정을 실습한다.

- 브라우저에서 요청한 URL 대해 매핑된 컨트롤러를 선택하고 요청명에 대한 JSP 파일을 브라우저로 전송하는 과정

SimpleUrlController 실행 과정

 

  1.  브라우저에서 http://localhost:8080/spring/index.do 로 요청한다.
  2.  DispatcherServlet은 요청에 대해 미리 action-servlet.xml에 매핑된 SimpleUrlController를 요청한다.
  3.  컨트롤러는 요청에 대해 test 폴더에 있는 index.jsp를 브라우저로 전송한다.

- 서블릿에서는 브라우저 요청 처리 서블릿에서 제공하는 메서드를 이용해 요청명을 일일이 가져왔다.

( request.getPathInfo( ) )

- 그러나 스프링에서는 브라우저의 요청을 쉽게 가져올 있는 여러 가지 기능을 제공한다. 그중 SimpleUrlController

사용한다.

 

SimpleUrlController 사용 예

- 예제에 사용하는 파일은 다음과 같다.

파일 설명
web.xml 브라우저에서 *.do 요청 스프링의 DispatcherServlet 클래스가요청을 받을 있게
서블릿 매핑을 한다.
action-servlet.xml 스프링 프레임워크에서 필요한 빈들을 설정한다.
SimpleUrlController.java 매핑된 요청에 대해 컨트롤러의 기능을 수행한다.
index.jsp 요청에 대해 컨트롤러가 브라우저로 전송하는 JSP 이다.

 

* WebContent/WEB-INF/web.xml

 - 브라우저에서 *.do 요청하면 스프링의 DispatcerServlet 클래스가 요청을 받을 있게 서블릿 매핑을 설정한다.

- 또한 <load-on-startup> 태그를 이용해 톰캣 실행 미리 스프링의 DispatcherServlet 메모리에 로드한다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
	<servlet>
		<servlet-name>action</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup> <!-- 값이 1 이상이면 톰캣 실행 시 DispatcherServlet을 미리 메모리에 로드한다. -->
	</servlet>
	
	<servlet-mapping>
		<servlet-name>action</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
</web-app>

 

* WebContent/WEB-INF/action-servlet.xml

- SimpleUrlController클래스에 대해 id simpleUrlController 빈을 생성한다.

- SimpleHandlerMapping 클래스 빈을 생성하면 요청명 /test/index.do 대해 처리하는 컨트롤러를

SimpleUrlController 설정한다.

- 설정 파일 이름은 반드시 web.xml 서블릿 매핑 사용했던 <servlet-name> 태그 값인 action으로 시작해야 한다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	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-3.0.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<bean id="simpleUrlController" class="com.spring.SimpleUrlController"/>
<bean id="urlMapping"
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property  name="mappings">
    <props>
      <prop key="/test/index.do">simpleUrlController</prop>
    </props>
  </property>  
</bean>
</beans>

 

* com/spring/SimpleUrlController.java

 - 설정 파일의 요청을 처리하기 위해서는 반드시 Controller 인터페이스를 구현해야 하며, SimpleUrlController 클래스로

요청  ModelAndView 객체를 생성해 응답할 JSP 이름인 index.jsp 설정하여 반환한다.

package com.spring;

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 SimpleUrlController implements Controller{

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		return new ModelAndView("index.jsp");
	}
}

 

- 만약 위 코드를 가져올 때 HttpServlet* 클래스를 가져올 때 에러가 발생한다면 다음과 같이 설정한다(Eclipse 사용시).

  1. 프로젝트의 Properties 
  2. [Project Facets] 항목 선택
  3. 해당 화면 내 우측의 [Runtimes] 항목 선택
  4. "Apache Tomcat *" 체크 후 [Apply and Close] 버튼 클릭

Project Facet 설정

 

* WebContent/test/index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>spring Test</title>
</head>
<body>
	<h1>index.jsp 파일입니다.</h1>
	<p>Hello Spring!</p>
</body>
</html>

 

- 코드 작성 후 톰캣을 실행시킨 후 브라우저에서 loclahost:[port]/[project_name]/test/index.do 로  요청해 본다.

/test/index.do 요청 결과

 

MultiActionController

- SImpleUrlController 이용해 요청을 처리하려면 요청명에 대해 다시 스프링의 Controller 인터페이스를 구현

 각각의 컨트롤러 클래스를 만들어야만 한다.

- 하지만 MultiActionController 이용하면 여러 요청명에 대해 개의 컨트롤러에 구현된 메서드로 처리할 있어

편리하다.

클래스 설명
MultiActionController URL 요청명으로 바로 컨트롤러를 지정해서 사용할 있다.
PropertiesMethodNameResolver URL 요청명으로 컨트롤러의 설정 파일에서 미리 설정된 메서드를 바로 호출해서 사용 있다.
InternalResourceViewResolver JSP HTML 파일과 같이 애플리케이션의 내부 자원을 이용해 뷰를 생성하는 기능을 제공한다.
기본적으로 사용하는 View 클래스이며 prefix suffix 프로퍼티를 이용해 경로를 지정할 있다.

* 사용할 파일

파일 설명
web.xml 브라우저에서 *.do로요청하면스프링의 DispatcherServlet 클래스가 요청을 받을 있게 서블릿 매핑을 설정한다.
action-servlet.xml 스프링에서 필요한 빈들을 설정한다.
UserController.java 매핑된 요청에 대해 컨트롤러의 기능을 수행한다.
loginForm.jsp 로그인
result.jsp 로그인 결과를 보여주는 JSP

 

* WebContent/WEB-INF/action-servlet.xml

 - 브라우저에서 /test/*.do 호출하면 userUrlMapping 빈을 이용해 userController 빈을 호출한다.

- userController 빈의 methodNameResolver 프로퍼티에는 userMethodNameResover 주입되어 있으므로

/test/login.do요청하면 userController 빈의 login 메서드를 호출한다. 또한 userMethodNameResolver 

스프링의 PropertiesMethodNameResolver 클래스를 이용해요청명에 대해 호출할 메서드를 바로 지정한다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	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-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- 컨트롤러에서ModelAndView 인자로 뷰이름이 반환되면 InternalResourceViewResolver의 프로퍼티 prefix 속성에 지정된 /test 폴더에서
	ModelAndView 인자로넘어온 뷰이름에 해당되는 JSP를 선택해 DispatcherServlet으로 보낸다. -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
	<property name="prefix" value="/test/" />
	<property name="suffix" value=".jsp" />
</bean>

<bean id="userUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	<property name="mappings">
		<props>
			<prop key="/test/*.do">userController</prop>
		</props>
	</property>
</bean>

<bean id="userController" class="com.spring.UserController">
	<property name="methodNameResolver">
		<ref local="userMethodNameResolver" />
	</property> 
</bean>

<!-- PropertiesMethodNameResolver를 이용해 /test/login.do로 요청하면 userController의 login 메서드를 호출한다. -->
<bean id="userMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
	<property name="mappings">
		<props>
			<prop key="/test/login.do">login</prop>
		</props>
	</property>
</bean>
</beans>


* UserController.java

 - UserController 클래스는 MultiActionController 상속받음으로써 지정한 요청명에 대해 바로 메서드를 호출할

있으며 ModelAndView 객체에 JSP 전달할 값을 바인딩할 있다.

- ModelAndView 객체를 이용하면 이상 request 객체에 바인딩해서 포워딩할 필요가 없고, 문자열 이외의 다른

객체들도 ModelAndView 객체에 바인딩할 있다.

- 따라서 ModelAndView setViewName() 메서드를 이용해 JSP 이름을 설정한 반환한다.

package com.spring;

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

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class UserController extends MultiActionController{
	public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception{
		String userID = "";
		String passwd = "";
		ModelAndView mav = new ModelAndView();
		request.setCharacterEncoding("utf-8");
		
		userID = request.getParameter("userID");
		passwd = request.getParameter("passwd");
		
		mav.addObject("userID", userID);
		mav.addObject("passwd",passwd);
		mav.setViewName("result");
		
		return mav;
	}

}

 

* loginForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath }" />
<%
	request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
	<form name="frmLogin" method="post" action="${contextPath }/test/login.do">
		<table border="1" width="700" align="left">
			<tr align="center">
				<td>아이디</td>
				<td>비밀번호</td>
			</tr>
			<tr align="center">
				<td><input type="text" name="userID" value="" size="20"></td>
				<td><input type="password" name="passwd" value="" size="20"></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="로그인" />
					<input type="reset" value="다시 입력" />
				</td>
			</tr>
		</table>
	</form>
</body>
</html>

 

* reuslt.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>결과창</title>
</head>
<body>
	<table border="1" width="50%" align="center">
		<tr align="center">
			<td>아이디</td>
			<td>비밀번호</td>
		</tr>
		<tr align="center">
			<td>${userID }</td>
			<td>${passwd }</td>
		</tr>
	</table>
</body>
</html>

 

- 코드 작성 후 /test/loginForm.jsp 로 요청해 로그인폼에서 아이디와 비밀번호를 입력하고 [로그인]버튼을 눌러 본다.

로그인폼

 

login.do를 요청한 결과

 

정보 표시 예

- 위의 예제를 수정해 회원 정보 입력창에서 회원 정보를입력한 요청 전송된 회원 정보를 표시한다.

 

* action-servlet.xml

- id가 "userMethodNameResolver"인 빈의 property 태그 안에 prop을 추가한다.

<bean id="userMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
	<property name="mappings">
		<props>
			<prop key="/test/login.do">login2</prop>
			<prop key="/test/memberInfo.do">memberInfo</prop> <!-- URL 요청명과 메서드 이름을 동일하게 하여 회원 정보를 요청한다. -->
		</props>
	</property>
</bean>

 

* UserController.java

- memberInfo라는 이름의 메서드를 추가한다.

public ModelAndView memberInfo(HttpServletRequest request, HttpServletResponse response) throws Exception{
    String userID = request.getParameter("id");
    String passwd = request.getParameter("passwd");
    String name = request.getParameter("name");
    String email = request.getParameter("email");
    ModelAndView mav = new ModelAndView();
    request.setCharacterEncoding("utf-8");
    mav.addObject("userID", userID);
    mav.addObject("passwd",passwd);
    mav.addObject("name", name);
    mav.addObject("email", email);
    mav.setViewName("memberInfo");
    return mav;
}

 

* memberForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	request.setCharacterEncoding("utf-8");
%>
<c:set var="contextPath" value="${pageContext.request.contextPath }" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 가입창</title>
</head>
<body>
	<form method="post" action="${ contextPath}/test/memberInfo.do">
		<h1 style="text-align:center;">회원 가입창</h1>
		<table align="center">
			<tr align="center">
				<td width="200"><p align="right">아이디</p></td>
				<td width="400"><input type="text" name="id" /></td>
			</tr>
			<tr align="center">
				<td width="200"><p align="right">비밀번호</p></td>
				<td width="400"><input type="password" name="passwd" /></td>
			</tr>
			<tr align="center">
				<td width="200"><p align="right">이름</p></td>
				<td width="400"><input type="text" name="name" /></td>
			</tr>
			<tr align="center">
				<td width="200"><p align="right">이메일</p></td>
				<td width="400"><input type="text" name="email" /></td>
			</tr>
			<tr align="center">
				<td colspan="2"><input type="submit" value="가입하기"/></td>
			</tr>
		</table>
	</form>
</body>
</html>

 

* memberInfo.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
<%
	request.setCharacterEncoding("utf-8");
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보</title>
</head>
<body>
	<table border="1" width="50%" align="center">
		<tr align="center">
			<td>아이디</td>
			<td>비밀번호</td>
			<td>이름</td>
			<td>이메일</td>
		</tr>
		<tr align="center">
			<td>${userID }</td>
			<td>${passwd }</td>
			<td>${name }</td>
			<td>${email }</td>
		</tr>
	</table>
</body>
</html>

 

- 코드 작성 후 /test/memberForm.jsp 페이지에 접근하여 정보 입력 후 [가입하기] 버튼을 눌러 본다.

회정 정보 입력 폼

 

출력 결과

- 요청명에 따라 호출하는 메서드가 달라진다.

 /test/login.do : login()
 /test/memberInfo.do : memberInfo();

 

반응형

'Spring' 카테고리의 다른 글

[Spring]스프링 애너테이션  (0) 2024.08.17
[Spring]MyBatis 연동하기  (0) 2024.08.17
[Spring]JDBC 연동  (0) 2024.08.17
[Spring]의존성 주입  (0) 2024.08.16
[Spring]스프링이란?  (0) 2024.08.16
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
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
글 보관함