ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 13. Spring MVC Framework를 이용한 데이터 조회
    Back-end Developer/Spring Framework, 설정 및 실습 2019. 1. 13. 15:58

    STS(Spring Tool Suite)를 사용한다면 이런 귀찮은 행동은 필요 없겠지만, 우리는 Eclipse를 쓰니까요...

    설정 조금만 하고 넘어갑시다.

    뭔 설정이 반인 것 같아요.



    버전 설정


    우선 web.xml 버전은 2.5로 되어있어요.

    귀찮으면 그대로 쓰셔도 되고, 저는 그래도 새로운 버전 써보려구요. 3.1로 바꿨습니다.


    web.xml 3.1 version

    1
    2
    3
    4
    5
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
             version="3.1">
    cs


    더 최신으로 쓰고싶으면 구글링 해보면 잘 나오니까 찾아서 써보세요.



    초기화


    이제 새로운 기능을 구현해야하니  HomeController, home.jsp 파일에 이전에 있던 기능들 있죠?

    현재 시간 출력하는 기능이었던 것 같아요. 그거 다 지워줄게요.


    HomeController.java

    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
    package kr.ac.snut.controller;
     
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
     
    /**
     * Handles requests for the application home page.
     */
    @Controller
    public class HomeController {
        
        private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
        
        @RequestMapping(value = "/", method = RequestMethod.GET)
        public String showHome() {
            
            
            return "home";    // view logical name
        }
        
    }
    cs


    home.jsp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ page session="false" %>
    <html>
    <head>
        <title>Home</title>
    </head>
    <body>
     
    </body>
    </html>
    cs



    이렇게 준비하시구요.

    우린 이제부터 Offer 테이블의 데이터를 조회하는 기능을 만들겁니다.



    home.jsp 링크 생성


    home.jsp에서 2개의 링크를 만들어주세요.


    home.jsp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ page session="false" %>
    <html>
    <head>
        <title>Home</title>
    </head>
    <body>
     
    <p> <a href = "${pageContext.request.contextPath}/offers"> show current offers </a>
    <p> <a href = "${pageContext.request.contextPath}/createoffer"> add a new offer </a>
     
    </body>
    </html>
     
    cs


    place holder를 이용해서 contextPath root 경로를 잡아주고 

    하위의 테이블 파일로 접근 가능하도록 해당 파일 이름을 뒤에 붙여주면 됩니다.

    이름을 보시면 아시겠지만, 하나는 테이블 조회 하나는 데이터 추가를 하는 클래스 입니다.


    실행은 해보나마나 링크는 잘 떠도, 따로 클래스 생성을 안해놨기 때문에, Not Found가 발생할겁니다.

    그래도 안하면 섭하니까 한번 실행해보세요.


    'https://localhost:8080/helloSpringMVC/'라고 경로가 잡힌게 보이네요.

    contextPath root가 잘 잡힌거죠. 링크도 정상적으로 떠있구요.



    OfferController 생성


    이제 끄고 우리가 생성한 링크의 기능을 수행할 Controller를 만들어봅시다.

    우선 web이라고 되어있던 패키지 명을 controller로 변경해주세요.

    그리고 model, dao, service 패키지도 하나씩 생성해줍시다.



    컨트롤러 패키지에 OfferController로 클래스하나 생성해주세요.

    이 클래스에선 offers, createoffer url을 처리하는 기능을 구현할 예정입니다.


    showOffers, createOffer 메소드 추가하고 

    offers, createoffer 이름으로 view에 jsp파일도 추가해주세요.


    OfferController.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package kr.ac.snut.controller;
     
    import java.util.List;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
     
    import kr.ac.snut.model.Offer;
    import kr.ac.snut.service.OffersService;
     
    @Controller
    public class OffersController {
        @RequestMapping("/offers")
        public String showOffers(Model model) {
            return "offers";
        }
        
        @RequestMapping("/createoffer")
        public String createOffer(Model model) {        
            return "createoffer";
        }
    }
    cs



    이제 링크도 반응은 합니다.



    라이브러리 추가


    DB에 접근을 해야하니까 이전 프로젝트에서 했던 helloDB에서 추가해줬던 라이브러리를 똑같이 추가해주세요.

    추가 하신 후에 pom.xml에서 추가된 spring jdbc 버전도 어차피 같은 버전이니까 place holder를 통해 접근 할 수 있도록 바꿔주세요.


    pom.xml

    1
    2
    3
    4
    5
    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework-version}</version>
    </dependency>
    cs



    Model 호출 준비


    Model 호출 구조도


    모델은 이런 방식으로 호출됩니다.

    우리는 컨트롤러 까지 꺼내와서 사용해야합니다.

    따라서 DAO서비스 객체 생성을 해서 DB에 접근 할 수 있도록 유도해야해요.


    우선 OfferService 클래스부터 해당 패키지에 생성해주세요.

    그리고 나머지 OfferMapper, OfferDAO, Offer 모델들은 helloDB 프로젝트에서 그대로 가져와주세요.


    복사 경로

    Offer(model): model package

    DAO, Mapper: dao package


    좌측 워킹트리에서 각 파일이 어디로 배치되었는지 확인하고 옮겨주세요.^^


    서비스 객체에는 '@Service'를 추가해주시고, DAO에는 '@Repository'를 붙여주세요.

    (@Component보단 대부분 @Repository를 사용하니까, 대세를 따르겠습니다. ㅎㅅㅎ)


    이제 OfferController에서 서비스 객체를 가져와 필드를 생성하구요.

    이에대한 setter도 정의해주세요.

    setter에는 '@Autowired' 잊지마시구요.

    이렇게 OfferService를 가진 bean이 주입되었습니다.


    OfferController.java

    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
    32
    33
    package kr.ac.snut.controller;
     
    import java.util.List;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
     
    import kr.ac.snut.model.Offer;
    import kr.ac.snut.service.OffersService;
     
    @Controller
    public class OffersController {
        private OffersService offersService;
        
        @Autowired
        public void setOffersService(OffersService offersService) {
            this.offersService = offersService;
        }
     
        @RequestMapping("/offers")
        public String showOffers(Model model) {
        
            return "offers";
        }
        
        @RequestMapping("/createoffer")
        public String createOffer(Model model) {
            
            return "createoffer";
        }
    }
    cs



    서비스 객체에서는 DAO를 가져와서 필드 생성하고, 

    마찬가지로 setter 정의하고 bean 등록을 해주세요.


    OfferService.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package kr.ac.snut.service;
     
    import java.util.List;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
     
    import kr.ac.snut.dao.OfferDAO;
    import kr.ac.snut.model.Offer;
     
    @Service
    public class OffersService {
        private OfferDAO offerDao;
        
        @Autowired
        public void setOfferDao(OfferDAO offerDao) {
            this.offerDao = offerDao;
        }
    }
     
    cs



    테이블 데이터 조회


    이제 본격적으로 데이터를 긁어오는 작업을 해볼게요.

    우선 현재 테이블의 상태를 받아올 getCurrent라는 메소드를 서비스 객체에 구현해주세요.

    생각해보니 이전에 만든 OfferDao 객체의 getOffers 메소드와 같기 때문에 그대로 가져와 쓰면 될 듯 합니다.


    OfferService.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package kr.ac.snut.service;
     
    import java.util.List;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
     
    import kr.ac.snut.dao.OfferDAO;
    import kr.ac.snut.model.Offer;
     
    @Service
    public class OffersService {
        private OfferDAO offerDao;
        
        @Autowired
        public void setOfferDao(OfferDAO offerDao) {
            this.offerDao = offerDao;
        }
        
        public List<Offer> getCurrent(){
            return offerDao.getOffers();
        }
    }
     
    cs



    이제 이 메소드를 showOffers에서 호출해줍니다.

    그래서 해당 메소드는 서비스 객체에서 getCurrent 메소드로 offer의 값들을 받아와 리스트에 하나씩 저장하고,

    이를 model attribute에 추가해 offer view로 넘겨주게 됩니다.


    OffersController.java

    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
    32
    33
    34
    35
    36
    37
    package kr.ac.snut.controller;
     
    import java.util.List;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
     
    import kr.ac.snut.model.Offer;
    import kr.ac.snut.service.OffersService;
     
    @Controller
    public class OffersController {
        private OffersService offersService;
        
        @Autowired
        public void setOffersService(OffersService offersService) {
            this.offersService = offersService;
        }
     
        @RequestMapping("/offers")
        public String showOffers(Model model) {
            List<Offer> offers = offersService.getCurrent();
            
            model.addAttribute("offers", offers);
            return "offers";
        }
        
        @RequestMapping("/createoffer")
        public String createOffer(Model model) {
            
            
            return "createoffer";
        }
    }
     
    cs



    View 구현


    뷰에서 결과를 보여줄 코드도 작성해야합니다.

    전에 사용했던 jstl을 이용해 반복문을 돌리고 출력해주고싶어요.

    따라서 jstl 코어 코드를 입력하시고, for each 문 및 c:out을 통해 결과를 뽑아 낼 수 있도록 해줍시다.


    offers.jsp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        
        <c:forEach var = "offer" items = "${offers}">
            <p
                <c:out value = "${offer}"> </c:out>
            </p>
        </c:forEach>
        
    </body>
    </html>
    cs


    이미 많이 봤던 코드기 때문에 이젠 익숙하셔야 합니다.



    service, dao context 파일 생성 및 등록


    Service와 DAO가 포함되어있는 Spring container, ContextLoadListener에 대한 처리도 필요합니다.

    따라서 이에 해당하는 xml 파일도 만들어줍시다.


    'WEB-INF/spring/appServlet/'에서

    new -> other -> bean configuration file 생성

    (service-context.xml, dao-context.xml)


    서비스 파일에서는 서비스 패키지를 읽어와 @Service를 가진 녀석을 bean으로 등록하는 작업을 합니다.

    namespace 탭에서 context 탭 활성화 하시고, 

    annotation-config, component-scan을 추가해주세요.


    service-context.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?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:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
     
        <context:annotation-config></context:annotation-config>
        <context:component-scan base-package="kr.ac.snut.service"></context:component-scan>
    </beans>
     
    cs



    DAO 파일도 동일하게 실시합니다.

    다만, 이전 helloDB에서 bean.xml의 place holder 부분 코드와 dataSource에 관련된 태그를 그대로 복사해 넣어주세요.

    그리고 파일 내용을 보니 property도 필요해보이니, WEB-INF 폴더에 props 폴더 생성하고, properties도 복사해서 넣어주세요.

    그리고 경로도 해당 프로젝트에 맞게 바꿔주세요.


    dao-context.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?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:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
     
        <context:property-placeholder
            location="/WEB-INF/props/jdbc.properties " />
     
        <context:annotation-config></context:annotation-config>
        <context:component-scan base-package="kr.ac.snut.dao"></context:component-scan>
        
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="${jdbc.driverClassName}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
        </bean>
    </beans>
     
    cs



    마지막으로 web.xml에서 service-context.xml와 dao-context.xml도 인자로 추가해줍시다.


    web.xml

    1
    2
    3
    4
    5
    6
    7
    8
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/root-context.xml
            /WEB-INF/spring/appServlet/service-context.xml
            /WEB-INF/spring/appServlet/dao-context.xml
        </param-value>
    </context-param>
    cs



    실행 결과


    문제없이 잘 되네요.

    다음엔 테이블에 데이터 추가하는 작업을 해보도록 할게요. ㅎㅁㅎ!!

    반응형

    댓글

Designed by minchoba.