관리 메뉴

거니의 velog

(7) 스프링 MVC 기능 2 본문

Java_Spring Framework part1

(7) 스프링 MVC 기능 2

Unlimited00 2023. 10. 4. 20:42

3. MultiActionController 이용해 스프링 MVC 실습하기

* SImpleUrlController를 이용해 요청을 처리하려면 각 요청명에 대해 다시 스프링의 Controller 인터페이스를 구현한 각각의 컨트롤러 클래스를 만들어야만 한다. 하지만 MultiActionController를 이용하면 여러 요청명에 대해 한 개의 컨트롤러에 구현된 각 메서드로 처리할 수 있어 편리하다.

* 이번에는 MultiActionController를 이용해 스프링 MVC를 실습해 보자. 우리가 실습에 사용할 클래스들은 다음 표와 같다.

<실습에 사용되는 스프링 클래스들>

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

* 또한 MultiActionController를 이용한 실습에 필요한 파일들은 다음 표와 같다.

<MultiActionController 실습에 사용되는 파일들>

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

* 그럼 브라우저의 요청명에 따라 실행되는 컨트롤러와 메서드를 각각 지정해서 사용해 보자.

1. com.spring.ex02 패키지를 만들고 UserController 클래스를 추가한다. 그리고 loginForm.jsp, result.jsp 등 필요한 파일을 준비한다.

2. action-servlet.xml을 다음과 같이 수정한다. 브라우저에서 /test/*.do로 호출하면 userUrlMapping 빈을 이용해 userController 빈을 호출한다.

* userController 빈의 methodNameResolver 프로퍼티에는 userMethodNameResolver가 주입되어 있으므로 /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">

	<!-- id가 simpleUrlController인 빈을 생성한다. -->
	<!-- <bean id="simpleUrlController" class="com.spring.ex01.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>  -->
	
	<!-- SimpleUrlHandlerMapping 클래스를 이용해 /test/index.do로 요청 시 simpleUrlController를 호출하도록 매핑한다. -->
 	<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> <!-- 컨트롤러에서 ModelAndView 인자로 뷰이름이 반환되면 InternalResourceResolver의 프로퍼티 prefix 속성에 지정된 /test 폴더에서 ModelAndView 인자로 넘어온 뷰이름에 해당되는 JSP를 선택해 DispatcherServlet으로 보낸다. -->

	<bean id="userUrlMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/test/*.do">userController</prop> <!-- URL 요청명이 /test/*.do로 시작되면 userController를 요청한다. -->
			</props>
		</property>
	</bean>

	<bean id="userController" class="com.spring.ex02.UserController">
		<property name="methodNameResolver">
			<ref local="userMethodNameResolver" />
		</property> <!-- methodNameResolver 프로퍼티에 userMethodNameResolver를 주입해서 지정한 요청명에 대해 직접 메서드를 호출하게 한다. -->
	</bean>

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

</beans>

3. UserController 클래스를 다음과 같이 작성한다. UserController 클래스는 MultiActionController를 상속받음으로써 지정한 요청명에 대해 바로 메서드를 호출할 수 있으며 ModelAndView 객체에 JSP에 전달할 값을 바인딩할 수 있다. ModelAndView 객체를 이용하면 더 이상 request 객체에 바인딩해서 포워딩할 필요가 없고, 문자열 이외의 다른 객체들도 ModelAndView 객체에 바인딩할 수 있다. 따라서 ModelAndview의 setViewName() 메서드를 이용해 JSP 이름을 설정한 후 반환한다.

package com.spring.ex02;

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 { // 설정 파일의 userMethodNameResolver 프로퍼티를 사용하려면 반드시 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;
	}*/
	
	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");
		String viewName=getViewName(request);
		
		mav.addObject("userID", userID);
		mav.addObject("passwd", passwd); // ModelAndView에 로그인 정보를 바인딩한다.
		mav.setViewName("result"); // ModelAndView 객체에 포워딩할 JSP 이름을 설정한다.
		//mav.setViewName(viewName); 
	    System.out.println("ViewName:" + viewName);
		return mav;
	}

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

	    mav.addObject("id",id);
	    mav.addObject("pwd",pwd);
	    mav.addObject("name",name);
	    mav.addObject("email",email);
	    mav.setViewName("memberInfo");
	    return mav;
	}
	
	private  String getViewName(HttpServletRequest request) throws Exception {
      String contextPath = request.getContextPath();
      String uri = (String)request.getAttribute("javax.servlet.include.request_uri");
      if(uri == null || uri.trim().equals("")) {
         uri = request.getRequestURI();
      }
      
      //http://localhost:8090/member/listMember.do로 요청시
      int begin = 0;  //
      if(!((contextPath==null)||("".equals(contextPath)))){
         begin = contextPath.length();  // 전체 요청명 의 길이를 구함
      }

      int end;
      if(uri.indexOf(";")!=-1){
         end=uri.indexOf(";");  //요청 uri에 ';'가 있을 경우 ';'문자 위치를 구함
      }else if(uri.indexOf("?")!=-1){
         end=uri.indexOf("?");   //요청 uri에 '?'가 있을 경우 '?' 문자 위치를 구함
      }else{
         end=uri.length();
      }

      //http://localhost:8090/member/listMember.do로 요청시 먼저 '.do'를 제거한 http://localhost:8090/member/listMember를 구한 후,
      //다시 http://localhost:8090/member/listMember에서 역순으로 첫번째 '/' 위치를 구한 후, 그 뒤의 listMember를 구한다.
      String fileName=uri.substring(begin,end);
      if(fileName.indexOf(".")!=-1){
         fileName=fileName.substring(0,fileName.lastIndexOf("."));  //요청명에서 역순으로 최초 '.'의 위치를 구한후, '.do' 앞에까지의 문자열을 구함
      }
      if(fileName.lastIndexOf("/")!=-1){
         fileName=fileName.substring(fileName.lastIndexOf("/"),fileName.length()); //요청명에서 역순으로 최초 '/'의 위치를 구한후, '/' 다음부터의 문자열을 구함  
      }
      return fileName;
   }
	
}

4. loginForm.jsp를 다음과 같이 작성한다. 로그인창에서 ID와 비밀번호를 입력하고 로그인을 클릭하면 /test/login.do로 DispatcherServlet에 요청한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    isELIgnored="false" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ 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"> <!-- /test/login.do로 DispatcherServlet에 요청한다 -->
        <table border="1" width="80%" align="center">
            <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 align="center">
                <td colspan="2">
                    <input type="submit" value="로그인">
                    <input type="reset" value="다시입력">
                </td>
            </tr>
        </table>
    </form>
</body>

</html>
* DispatcherServlet 클래스는 ModelAndView에 설정된 뷰이름("result")과 action-servlet.xml의
  InternalResourceViewResolver에 설정한 뷰이름을 조합하여 /test 폴더에서 뷰이름에 해당하는
  JSP("result.jsp")를 찾아 브라우저로 전송한다.

5. result.jsp를 다음과 같이 작성한다. 로그인창에서 전송된 ID와 비밀번호를 컨트롤러에서 바인딩해 넘긴 후 결과창에서 출력한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ 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>

6. 다음의 주소로 요청한다. 로그인창에서 ID와 비밀번호를 입력하고 로그인을 클릭하면 /test/login.do로 요청하여 결과를 출력한다.

- http://localhost:8080/pro21/test/loginForm.jsp

'Java_Spring Framework part1' 카테고리의 다른 글

(9) 스프링 JDBC 기능  (0) 2023.10.28
(8) 스프링 MVC 기능 3  (0) 2023.10.26
(6) 스프링 MVC 기능 1  (0) 2023.10.03
(5) 스프링 AOP 기능  (0) 2023.10.03
(4) 스프링 의존성 주입과 제어 역전 기능 3  (0) 2023.10.03