컨트롤러 추가 및 View페이지 공통분모 집중화와 필요성
컨트롤러 추가
IndexController.java
public class ListController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView("notice/list");
return mv;
}
}
dispatcher-servlet.xml
<bean name="/notice/list" class="com.newlecture.web.controller.notice.ListController" />
같은 방법으로 detailController도 추가하였다.
View페이지 공통분모 집중화와 필요성
페이지에서 공통된부분을 분리한다.
페이지에서 공통된 부분을 분리하고 집중화하는 것은 코드의 유지 보수성과 재사용성을 높이는데 도움이 됩니다. Tiles를 사용하여 이러한 작업을 수행하는 것은 특히 유용하다.
사용자 요청이 오면 컨트롤러가 뷰를 반환하는 경우, 스프링은 해당 뷰 리졸버로부터 뷰를 찾아 사용자에게 반환한다. 이 때, 컨트롤러가 반환하는 형태가 notice.list와 같은 Tiles 형태라면, 스프링은 Tiles를 호출하여 해당하는 Tiles 정의를 찾고 페이지의 조각들을 조합하여 최종 결과물을 생성한다. 이를 위해 Tiles에게 어떤 조각을 어떤 위치에 둘 것인지 지시하는 Tiles 지시서를 작성해야 한다.
Tiles 지시서를 활용하는 것은 우선순위가 높은 방법이며, 이를 통해 다양한 페이지에서 공통된 요소를 효율적으로 관리할 수 있다. 이는 코드를 중복 작성하지 않고도 일관된 디자인과 기능을 적용할 수 있게 해준다. 페이지의 레이아웃이나 공통된 요소를 변경해야 할 경우, Tiles 지시서만 수정하여 전체적인 페이지 구조를 쉽게 업데이트할 수 있다. 이로써 코드의 유지보수성이 향상되고 개발 시간을 단축할 수 있다.
disaptcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 디스패처 서블릿 설정 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- /index URL 요청에 대한 매핑 -->
<!-- "/index" 이름을 가진 빈을 정의하고 IndexController 클래스와 연결 -->
<!-- id 속성은 주요 빈 식별자이며 name 속성은 선택적인 별칭을 제공 -->
<!-- 빈 정의는 컨테이너 내에 포함됩니다. -->
<!-- name="/index"은 실제 index폴더가 있는것이 아니라 단지 url이름이다. -->
<bean name="/index" class="com.newlecture.web.controller.IndexController" />
<bean name="/notice/list" class="com.newlecture.web.controller.notice.ListController">
<!-- name="service" : ListController의 setNoticeService() -->
<!-- ref="noticeService" : noticeService을 주입 -->
<!--
public void setNoticeService(NoticeService noticeService) {
this.noticeService = noticeService;
} -->
<property name="service" ref="noticeService" />
</bean>
<bean name="/notice/detail" class="com.newlecture.web.controller.notice.DetailController" />
<bean
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.tiles3.TilesView" />
<!-- 뷰리졸버보다 우선순위를 높게하였다. -->
<property name="order" value="1" />
</bean>
<bean
class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions" value="/WEB-INF/tiles.xml" />
</bean>
<!-- 이름 또는 id를 지정하지 않고 IndexController의 또 다른 인스턴스를 등록 -->
<bean class="com.newlecture.web.controller.IndexController" />
<!-- 뷰 리졸버 설정을 통해 뷰 이름을 JSP 파일에 매핑 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 뷰 파일 위치의 접두사 설정 -->
<property name="prefix" value="/WEB-INF/view/"></property>
<!-- 뷰 파일 확장자 설정 -->
<property name="suffix" value=".jsp"></property>
<property name="order" value="2" />
</bean>
<!-- mapping="/resource/**" : /**안에 들어오는 url은 location="/resource/"에 두겠다. -->
<mvc:resources location="/static/" mapping="/**"></mvc:resources>
<bean id="noticeService" class="com.newlecture.web.service.NoticeService" />
</beans>
tiles.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="root.*" template="/WEB-INF/view/customer/inc/layout.jsp">
<put-attribute name="title" value="공지사항" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="visual" value="/WEB-INF/view/customer/inc/visual.jsp" />
<put-attribute name="aside" value="/WEB-INF/view/customer/inc/aside.jsp" />
<!-- notice.* 은 패턴화한것이다. 따라서 *은 {1}로 받고 여기엔 list,detail이 오든 여기에서 받는다. -->
<put-attribute name="body" value="/WEB-INF/view/{1}.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>
<definition name="notice.*" template="/WEB-INF/view/customer/inc/layout.jsp">
<put-attribute name="title" value="공지사항" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="visual" value="/WEB-INF/view/customer/inc/visual.jsp" />
<put-attribute name="aside" value="/WEB-INF/view/customer/inc/aside.jsp" />
<!-- notice.* 은 패턴화한것이다. 따라서 *은 {1}로 받고 여기엔 list,detail이 오든 여기에서 받는다. -->
<put-attribute name="body" value="/WEB-INF/view/customer/notice/{1}.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>
<!-- <definition name="noitce.detail" template="WEB-INF/view/customer/inc/layout.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
<put-attribute name="visual" value="/WEB-INF/view/customer/inc/visual.jsp" />
<put-attribute name="aside" value="/WEB-INF/view/customer/inc/aside.jsp" />
<put-attribute name="body" value="/WEB-INF/view/customer/notice/detail.jsp" />
<put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition> -->
</tiles-definitions>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>코딩 전문가를 만들기 위한 온라인 강의 시스템</title>
<meta charset="UTF-8">
<title>공지사항목록</title>
<link href="/css/layout.css" type="text/css" rel="stylesheet" />
<link href="/css/index.css" type="text/css" rel="stylesheet" />
</head>
<body>
<!-- header 부분 -->
<!-- --------------------------- <body> --------------------------------------- -->
<!-- content 부분 -->
<div id="visual" class="">
<div class="content-container">
<h2 class="hidden">신규 강좌목록</h2>
<!-- <ul class="mov-button">
<li class="prev-button">이전</li>
<li class="next-button">다음</li>
</ul> -->
<ul class="banner">
<li class="banner1">
<a href="customer/event/1">
<img src="admin/board/event/1/banner-java.png" data-id="1" style="cursor: pointer;" />
</a>
</li>
</ul>
<ul class="banner-button-list" style="color:#ffff00; font-size:20px;position:absolute; left:10px; bottom:5px; z-index: 100px; display: flex; flex-direction: row;">
<li></li>
</ul>
</div>
</div>
<div id="notice">
<div class="content-container">
<span class="title">제대로된 전문가들이 만들어가는 <span style="color:yellow;font-size:15px;">IT PROFESSIONAL <span style="color:#00ffff;">NEW</span>
ONLINE <span style="color:#00ffff;">LECTURE</span> MARKET</span></span>
<!--<a class="detail-button">자세히</a>-->
</div>
</div>
<!-- ----- 공지사항 줄 ------------------------------------------------------------------------------ -->
<div id="information">
<div class="content-container">
<section class="guide">
<h1 class="title">강의 플레이어 사용방법 안내</h1>
<div class="margin-top">
<a href="customer/faq/1"><img src="images/customer/installInfo.png" /></a>
</div>
<!-- <div>
2
</div>
<div>
3
</div> -->
</section>
<section class="course-info">
<h1 class="title text-center">뉴렉처 하이브리드 과정 모집</h1>
<ul class="list">
<li>현재 모집 과정이 없습니다.</li>
</ul>
</section>
<section class="notice">
<h1 class="title">공지사항</h1>
<ul class="list margin-top">
<li>
<span class="notice-title">
<a href="notice/detail.html">스프링 8강까지의 예제 코드</a>
</span>
<span>2019-08-18</span>
</li>
<li>
<span class="notice-title">
<a href="notice/detail.html">스프링 DI 예제 코드</a>
</span>
<span>2019-08-15</span>
</li>
<li>
<span class="notice-title">
<a href="notice/detail.html">뉴렉쌤 9월 초 국기과정 모집 안내</a>
</span>
<span>2019-06-11</span>
</li>
<li>
<span class="notice-title">
<a href="notice/detail.html">뉴렉처 강의 수강 방식 안내</a>
</span>
<span>2019-05-24</span>
</li>
<li>
<span class="notice-title">
<a href="notice/detail.html">자바 구조적인 프로그래밍 강의 예제 파일</a>
</span>
<span>2019-04-24</span>
</li>
</ul>
</section>
</div>
</div>
<!-- ----- 커뮤니티 시작 줄 -------------------------------------------------------------------------------------------- -->
<!-- ----- 커뮤니티 시작 줄 -------------------------------------------------------------------------------------------- -->
<!-- <div class="margin-top">
<div style="height: 170px; margin-top:10px;" class="content-container border">
</div>
</div> -->
<!-- ----- 강좌 목록 시작 줄 --------------------------------------------------------------------------------------------------------- -->
<main id="course">
<section class="content-container list list-horizontal list-course list-course-index">
<h1>온라인 <span class="color-orange">단과 과정</span></h1>
<div>
</div>
<ul>
<!-- <li class="item-course normal new">
<div>
<a href="course/16"><img src="images/course/landing page.png" /></a>
</div>
<div>
<div>
<a href="course/16"><span class="text-strong text-ellipsis">멋진 프로그래머가 되기 위한 사전지식</span></a>
</div>
<div class="price">
<span class="normal ">
<span class="text-orange text-strong">
0
</span> 원
</span> <span class="event">
</span>
</div>
<div class="footer text-strong">
<span class="writer">선생님 : newlec </span>
<span class="update">개설일 : 2019-09-07
</span>
</div>
</div>
</li>
<li class="item-course normal new">
<div>
<a href="course/10"><img src="images/course/html5.png" /></a>
</div>
<div>
<div>
<a href="course/10"><span class="text-strong text-ellipsis">웹 표준기반의 웹 퍼블리싱 HTML5 편</span></a>
</div>
<div class="price">
<span class="normal ">
<span class="text-orange text-strong">
45,000
</span> 원
</span> <span class="event">
</span>
</div>
<div class="footer text-strong">
<span class="writer">선생님 : newlec </span>
<span class="update">개설일 : 2019-09-07
</span>
</div>
</div>
</li>
<li class="item-course normal event">
<div>
<a href="course/8"><img src="images/course/oracle.png" /></a>
</div>
<div>
<div>
<a href="course/8"><span class="text-strong text-ellipsis">Oracle SQL 프로그래밍</span></a>
</div>
<div class="price">
<span class="normal deprecated">
<span class="text-gray">
44,000
</span> 원
</span> <span class="event">
<span class="color-red text-strong">
0
</span>원
</span>
</div>
<div class="footer text-strong">
<span class="writer">선생님 : newlec </span>
<span class="update">개설일 : 2019-09-07
</span>
</div>
</div>
</li>
<li class="item-course normal normal">
<div>
<a href="course/7"><img src=images/course/spring.png" /></a>
</div>
<div>
<div>
<a href="course/7"><span class="text-strong text-ellipsis">스프링 3.x MVC 웹 프로그래밍</span></a>
</div>
<div class="price">
<span class="normal ">
<span class="text-orange text-strong">
33,600
</span> 원
</span> <span class="event">
</span>
</div>
<div class="footer text-strong">
<span class="writer">선생님 : newlec </span>
<span class="update">개설일 : 2019-09-07
</span>
</div>
</div>
</li> -->
<li class="item-course normal event">
<div>
<a href="course/2"><img src="images/course/java.png" /></a>
</div>
<div>
<div>
<a href="course/2"><span class="text-strong text-ellipsis">자바 프로그래밍</span></a>
</div>
<div class="price">
<span class="normal deprecated">
<span class="text-gray">
22,000
</span> 원
</span> <span class="event">
<span class="color-red text-strong">
0
</span>원
</span>
</div>
<div class="footer text-strong">
<span class="writer">선생님 : newlec </span>
<span class="update">개설일 : 2019-09-07
</span>
</div>
</div>
</li>
</ul>
<div class="more">
<!-- <span class="border padding">단과 과정 목록 더보기</span> -->
</div>
</section>
<!-- ------- 온라인 패키지 과정 ------------------------------------------------------------------------------------------------- -->
<div class="content-container">
<h3 class="-text- center green bold -margin- top">협력업체</h3>
<ul class="-list- horizontal center -margin- bottom top b20">
<li><a target="_blank" href="http://www.notepubs.com"><img src="images/notepubs.png" alt="노트펍스" /></a></li>
<li><a target="_blank" href="http://www.namoolab.com"><img src="images/namoolab.png" alt="나무랩연구소" /></a></li>
</ul>
</div>
</main>
<script>
</script>
<!-- ------------------- <footer> --------------------------------------- -->
</body>
</html>
layout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><tiles:getAsString name="title" /></title>
<link href="/css/customer/layout.css" type="text/css" rel="stylesheet" />
<style>
#visual .content-container{
height:inherit;
display:flex;
align-items: center;
background: url("../../images/customer/visual.png") no-repeat center;
}
</style>
</head>
<body>
<!-- --------------------------- <header부분> --------------------------------------- -->
<tiles:insertAttribute name="header" />
<!-- visual부분 -->
<tiles:insertAttribute name="visual" />
<!-- --------------------------- <body> --------------------------------------- -->
<div id="body">
<div class="content-container clearfix">
<!-- --------------------------- aside --------------------------------------- -->
<!-- aside 부분 -->
<tiles:insertAttribute name="aside" />
<!-- --------------------------- main --------------------------------------- -->
<tiles:insertAttribute name="body" />
</div>
</div>
<!-- ------------------- <footer> --------------------------------------- -->
<tiles:insertAttribute name="footer" />
</body>
</html>
header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<header id="header">
<div class="content-container">
<!-- ---------------------------<header>--------------------------------------- -->
<h1 id="logo">
<a href="/index.html">
<img src="/images/logo.png" alt="뉴렉처 온라인" />
</a>
</h1>
<section>
<h1 class="hidden">헤더</h1>
<nav id="main-menu">
<h1>메인메뉴</h1>
<ul>
<li><a href="/guide">학습가이드</a></li>
<li><a href="/course">강좌선택</a></li>
<li><a href="/answeris/index">AnswerIs</a></li>
</ul>
</nav>
<div class="sub-menu">
<section id="search-form">
<h1>강좌검색 폼</h1>
<form action="/course">
<fieldset>
<legend>과정검색필드</legend>
<label>과정검색</label>
<input type="text" name="q" value="" />
<input type="submit" value="검색" />
</fieldset>
</form>
</section>
<nav id="acount-menu">
<h1 class="hidden">회원메뉴</h1>
<ul>
<li><a href="/index.html">HOME</a></li>
<li><a href="/member/login.html">로그인</a></li>
<li><a href="/member/agree.html">회원가입</a></li>
</ul>
</nav>
<nav id="member-menu" class="linear-layout">
<h1 class="hidden">고객메뉴</h1>
<ul class="linear-layout">
<li><a href="/member/home"><img src="/images/txt-mypage.png" alt="마이페이지" /></a></li>
<li><a href="/notice/list"><img src="/images/txt-customer.png" alt="고객센터" /></a></li>
</ul>
</nav>
</div>
</section>
</div>
</header>
aside.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<aside class="aside">
<h1>고객센터</h1>
<nav class="menu text-menu first margin-top">
<h1>고객센터메뉴</h1>
<ul>
<li><a class="current" href="/customer/notice">공지사항</a></li>
<li><a class="" href="/customer/faq">자주하는 질문</a></li>
<li><a class="" href="/customer/question">수강문의</a></li>
<li><a class="" href="/customer/event">이벤트</a></li>
</ul>
</nav>
<nav class="menu">
<h1>협력업체</h1>
<ul>
<li><a target="_blank" href="http://www.notepubs.com"><img src="/images/notepubs.png" alt="노트펍스" /></a></li>
<li><a target="_blank" href="http://www.namoolab.com"><img src="/images/namoolab.png" alt="나무랩연구소" /></a></li>
</ul>
</nav>
</aside>
visual.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<div id="visual">
<div class="content-container"></div>
</div>
footer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<footer id="footer">
<div class="content-container">
<h2 id="footer-logo"><img src="images/logo-footer.png" alt="회사정보"></h2>
<div id="company-info">
<dl>
<dt>주소:</dt>
<dd>서울특별시 </dd>
<dt>관리자메일:</dt>
<dd>admin@newlecture.com</dd>
</dl>
<dl>
<dt>사업자 등록번호:</dt>
<dd>111-11-11111</dd>
<dt>통신 판매업:</dt>
<dd>신고제 1111 호</dd>
</dl>
<dl>
<dt>상호:</dt>
<dd>뉴렉처</dd>
<dt>대표:</dt>
<dd>홍길동</dd>
<dt>전화번호:</dt>
<dd>111-1111-1111</dd>
</dl>
<div id="copyright" class="margin-top">Copyright ⓒ newlecture.com 2012-2014 All Right Reserved.
Contact admin@newlecture.com for more information</div>
</div>
</div>
</footer>
ListController
public class ListController implements Controller {
// NoticeService를 인터페이스로 두면
private NoticeService noticeService;
// 의존성 주입을 위한 setter 메서드
public void setService(NoticeService noticeService) {
this.noticeService = noticeService;
}
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ModelAndView 객체 생성, 해당 요청에 대한 응답을 구성하기 위해 사용
ModelAndView mv = new ModelAndView("notice.list");
// NoticeService를 사용하여 공지사항 목록을 가져옴
List<Notice> list= noticeService.getList(1, "TITLE", "");
// 가져온 목록을 ModelAndView 객체에 추가
mv.addObject("list", list);
// 구성된 ModelAndView 객체 반환
return mv;
}
}
참고 자료 출처 :
(37~45)
https://www.youtube.com/watch?v=jRMxW-dKN34&list=PLq8wAnVUcTFUHYMzoV2RoFoY2HDTKru3T&index=45