[spring] 스프링 프레임워크 MVC

sang·2024년 4월 11일

스프링 프레임워크 MVC

모델2 아키텍처 지원
다른 모듈과 쉬운 연계
View 기술과 쉬운 연계 (tiles, sitemesh)
태그 라이브러리를 통한 쉬운 구현 (message, theme, input)

구성 요소

DispatcherServlet: 클라이언트 요청에 대한 컨트롤러 선택, 요청 전달, View에 반환값 전달
HandlerMapping: 클라이언트 URL 요청을 처리할 컨트롤러 지정
Controller: 서블릿(DispatcherServlet)으로 요청 처리 결과 전달
MultiActionController: URL 요청명에 따른 컨트롤러 지정
PropertiesMethodNameResolver: 메소드 호출
ModelAndView: 처리 결과 및 필요 정보 저장
ViewResolver: 처리 결과를 전달할 뷰 지정
View: 처리 결과 화면 생성
InternalResourceViewResolver: 뷰 생성, 경로 지정 가능

수행 과정

  1. 요청 전달: 웹 브라우저 -> DispatcherServlet -> HandlerMapping -> Controller
  2. 결과 전달: Controller -> DispatcherServlet
  3. 결과 출력: DispatcherServlet -> ViewResolver -> View


SimpleUrlController

pro21/WebContent/WEB-INF/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">

  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup> <!-- 양수: 미리 로드 // 음수: 요청 시 로드 -->
  </servlet>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

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

bean 설정

<?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">

<!-- simpleUrlController bean 생성 -->
<bean id="simpleUrlController" class="com.spring.ex01.SimpleUrlController"/>
<!-- SimpleUrlHandlerMapping: 매핑 -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
      <props>
        <prop key="/test/index.do">simpleUrlController</prop> <!-- index.do 요청 시 simpleUrlController 호출 -->
      </props>
    </property>
  </bean>

pro21/src/com/spring/ex01/SimpleUrlController.java

컨트톨러

package com.spring.ex01;
...
public class SimpleUrlController implements Controller {
  @Override
  public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    return new ModelAndView("index.jsp"); //작업 결과 반환
  }
}

pro21/WebContent/test/index.jsp

출력 (요청 결과)

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


MultiActionController

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

bean 설정

<?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">

  <!-- InternalResourceViewResolver: 뷰 선택 경로 지정 및 전달 -->
  <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>
  
  <!-- SimpleUrlHandlerMapping: 매핑 -->
  <bean id="userUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
      <props>
        <prop key="/test/*.do">userController</prop>
      </props>
    </property>
  </bean>
  
  <!-- userMethodNameResolver 주입 -->
  <bean id="userController" class="com.spring.ex02.UserController">
    <property name="methodNameResolver">
        <ref local="userMethodNameResolver"/>
    </property>
  </bean>

  <!-- PropertiesMethodNameResolver: 메소드 호출 -->
  <bean id="userMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
    <property name="mappings">
      <props>
        <prop key="/test/login.do">login</prop> <!-- login.do 요청 시 login 메소드 호출 -->
      </props>
    </property>
  </bean>
</beans>

pro21/WebContent/test/loginForm.jsp

로그인 창

...
<form name="frmLogin" method="post" action="${contextPath}/test/login.do"> <!-- -->
  <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>
    ...
  </table>
</form>
</body>
</html>

pro21/WebContent//test/login.jsp

로그인 결과창

...
  <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>
...

pro21/src/com/spring/ex02/UserController.java

...
public class UserController extends MultiActionController {
  public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception {
    String userID = "";
    String passwd = "";
    
    String viewName=getViewName(request); //요청 이름
    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(viewName); //포워딩할 JSP 이름
    System.out.println("ViewName:"+viewName);
    
    return mav;
  }
 
  private String getViewName(HttpServletRequest request) throws Exception { //요청명에서 view 이름 가져오기
    String contextPath = request.getContextPath();
    
    String uri = (String)request.getAttribute("javax.servlet.include.request_uri");
    if(uri == null || uri.trim().equals("")) {
      uri = request.getRequestURI();
    }

    int begin = 0;
    if( !((contextPath==null)||("".equals(contextPath))) ){
      begin = contextPath.length();
    }

    int end;
    if(uri.indexOf(";")!=-1){ end=uri.indexOf(";"); }
    else if(uri.indexOf("?")!=-1){ end=uri.indexOf("?"); }
    else{ end=uri.length(); }

    String fileName=uri.substring(begin,end);
    if(fileName.indexOf(".")!=-1){
      fileName=fileName.substring(0, fileName.lastIndexOf("."));
    }
    if(fileName.lastIndexOf("/")!=-1){
      fileName=fileName.substring(fileName.lastIndexOf("/"),fileName.length());
    }
    
    return fileName;
  }
}


스프링 JDBC

Java Database Connectivity
자바 데이터 엑세스 기술

DB 연결

pro22/WebContent/WEB-INF/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">

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> <!-- 설정파일 사용을 위해 필요 -->
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value> <!-- 설정 파일 -->
      /WEB-INF/config/action-service.xml
      /WEB-INF/config/action-dataSource.xml
    </param-value>
  </context-param>

  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

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

<?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">

  <!-- InternalResourceViewResolver: 뷰 선택 경로 지정 및 전달 -->
  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
  </bean>
  
  <!-- memberController: methodNameResolver, memberService 주입 -->
  <bean id="memberController" class="com.spring.member.controller.MemberControllerImpl">
    <property name="methodNameResolver"> <ref local="methodResolver"/> </property>
    <property name="memberService" ref="memberService"/>
  </bean>

  <!-- PropertiesMethodNameResolver: 메소드 호출 -->
  <bean id="methodResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver" >
    <property name="mappings" >
      <props>
        <prop key="/member/listMembers.do" >listMembers</prop>
        <prop key="/member/addMember.do" >addMember</prop>
        <prop key="/member/memberForm.do" >memberForm</prop>
        <prop key="/member/memberDetail.do">memberDetail</prop>
      </props>
    </property>
  </bean>

  <!-- SimpleUrlHandlerMapping: 매핑 -->
  <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >
    <property name="mappings" >
      <props>
        <prop key="/member/*.do" >memberController</prop>
      </props>
    </property>
  </bean>
  
  <!-- memberService: memberDAO bean 주입 -->
  <bean id="memberService" class="com.spring.member.service.MemberServiceImpl">
    <property name="memberDAO" ref="memberDAO"/>
  </bean>
</beans>

pro22/WebContent/WEB-INF/config/action-dataSource.xml

스프링 JDBC 설정에 필요한 정보 설정

...
  <!-- DB 연결에 필요한 설정 정보 가져오기 -->
  <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
  <property name="locations" >
      <list>
        <value>/WEB-INF/config/jdbc.properties</value> 
      </list>
    </property>
  </bean>
  
  <!-- SimpleDriverDataSource 생성 시 DB 연결 -->
  <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
    <property name="driverClass" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
  </bean>
  
  <!-- memberDAO: dataSource bean 주입 -->
  <bean id="memberDAO" class="com.spring.member.dao.MemberDAOImpl" >
    <property name="dataSource" ref="dataSource" />
  </bean>
...

pro22/WebContent/WEB-INF/config/jdbc.properties

DB 연결 정보

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:XE
jdbc.username=scott
jdbc.password=tiger

pro22/WebContent/WEB-INF/config/action-service.xml

서비스 빈 생성 설정

bean 주입 과정

memberController <- memberService <- memberDAO <- dataSource

DB 사용

JDBC Template

pro22/src/com/spring/member/controller/MemberControllerImpl.java

...
public class MemberControllerImpl extends MultiActionController implements MemberController {
  private MemberService memberService;
  
  public void setMemberService(MemberService memberService) {
    this.memberService = memberService;
  }
 
  public ModelAndView listMembers(HttpServletRequest request, HttpServletResponse response) throws Exception {
    String viewName = getViewName(request);
    List membersList = memberService.listMembers(); //MemberService에서 정보 가져오기
    ModelAndView mav = new ModelAndView(viewName);
    mav.addObject("membersList", membersList); //정보 바인딩
    
    return mav;
  }
  ...
}

pro22/src/com/spring/member/service/MemberServiceImpl.java

package com.spring.member.service;
...
public class MemberServiceImpl implements MemberService {
  private MemberDAO memberDAO;
  
  public void setMemberDAO(MemberDAO memberDAO) {
    this.memberDAO = memberDAO;
  }
  
  @Override
  public List listMembers() throws DataAccessException {
    List membersList = null;
    membersList = memberDAO.selectAllMembers(); //MemberDAO에서 정보 가져오기
    
    return membersList;
  }
}

pro22/src/com/spring/member/dao/MemberDAOImpl.java

...
public class MemberDAOImpl implements MemberDAO {
  private JdbcTemplate jdbcTemplate;

  public void setDataSource(DataSource dataSource) {
    this.jdbcTemplate = new JdbcTemplate(dataSource);
  }
  
  @Override
  public List selectAllMembers() throws DataAccessException {
    String query = "select id,pwd,name,email,joinDate" + " from t_member " + " order by joinDate desc";
    List membersList = new ArrayList();

    membersList = this.jdbcTemplate.query(query, new RowMapper() { //JdbcTemplate에서 정보 가져오기
      public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
        MemberVO memberVO = new MemberVO();
        memberVO.setId(rs.getString("id"));
        memberVO.setPwd(rs.getString("pwd"));
        memberVO.setName(rs.getString("name"));
        memberVO.setEmail(rs.getString("email"));
        memberVO.setJoinDate(rs.getDate("joinDate"));
        return memberVO;
      }
    });
    
    return membersList;
  }

  @Override
  public int addMember(MemberVO memberVO) throws DataAccessException {
    String id = memberVO.getId();
    String pwd = memberVO.getPwd();
    String name = memberVO.getName();
    String email = memberVO.getEmail();
    
    String query = "insert into t_member(id,pwd, name,email) values (" + "'" + id + "' ," + "'" + pwd + "' ," + "'" + name + "' ," + "'" + email + "') ";
    System.out.println(query);
    
    int result = jdbcTemplate.update(query); //JdbcTemplate에 정보 넣기
    System.out.println(result);
    
    return result;
  }
}

pro22/WebContent/WEB-INF/views/listMembers.jsp

...
  <table border="1" align="center" width="80%">
    <tr align="center" bgcolor="lightgreen">
      <td ><b>>아이디</b></td>
      <td><b>>비밀번호</b></td>
      <td><b>>이름</b></td>
      <td><b>>이메일</b></td>
      <td><b>>가입일</b></td>
    </tr>
  <c:forEach var="member" items="${membersList}" >
    <tr align="center">
    <td>${member.id}</td>
      <td>${member.pwd}</td>
      <td>${member.name}</td>
      <td>${member.email}</td>
      <td>${member.joinDate}</td>
    </tr>
  </c:forEach>
  </table>
...


*자바 웹을 다루는 기술

profile
CS 메모장

0개의 댓글