Dispatcher Servlet이 Controller를 호출하기 전과 후에 요청 또는 응답을 가로채는 객체
Client
↔️ Filter
↔️ Dispatcher Servlet
↔️ Interceptor
↔️ Controller
(전처리)
Dispatcher Servlet
->Controller
사이
(후처리)
Controller
->Dispatcher Servlet
사이
(뷰 완성 후)
ViewResolver
->Dispatcher Servlet
사이
-- 게시판 종류
CREATE TABLE "BOARD_TYPE"(
"BOARD_CODE" NUMBER CONSTRAINT "PK_BOARD_TYPE" PRIMARY KEY,
"BOARD_NAME" VARCHAR2(30) NOT NULL
);
COMMENT ON COLUMN "BOARD_TYPE"."BOARD_CODE"
IS '게시판 코드(SEQ_BOARD_CODE)';
COMMENT ON COLUMN "BOARD_TYPE"."BOARD_NAME"
IS '게시판 이름';
CREATE SEQUENCE SEQ_BOARD_CODE NOCACHE;
-- 게시판 종류 추가
INSERT INTO "BOARD_TYPE" VALUES(SEQ_BOARD_CODE.NEXTVAL, '공지사항');
INSERT INTO "BOARD_TYPE" VALUES(SEQ_BOARD_CODE.NEXTVAL, '자유 게시판');
INSERT INTO "BOARD_TYPE" VALUES(SEQ_BOARD_CODE.NEXTVAL, '테스트 게시판');
INSERT INTO "BOARD_TYPE" VALUES(SEQ_BOARD_CODE.NEXTVAL, '질문 게시판');
INSERT INTO "BOARD_TYPE" VALUES(SEQ_BOARD_CODE.NEXTVAL, '점심 게시판');
COMMIT;
-- [게시판 DB 설정]
CREATE TABLE "BOARD" (
"BOARD_NO" NUMBER NOT NULL,
"BOARD_TITLE" VARCHAR2(150) NOT NULL,
"BOARD_CONTENT" VARCHAR2(4000) NOT NULL,
"B_CREATE_DATE" DATE DEFAULT SYSDATE NOT NULL,
"B_UPDATE_DATE" DATE NULL,
"READ_COUNT" NUMBER DEFAULT 0 NOT NULL,
"BOARD_DEL_FL" CHAR(1) DEFAULT 'N' NOT NULL,
"MEMBER_NO" NUMBER NOT NULL,
"BOARD_CODE" NUMBER NOT NULL
);
COMMENT ON COLUMN "BOARD"."BOARD_NO" IS '게시글 번호(SEQ_BOARD_NO)';
COMMENT ON COLUMN "BOARD"."BOARD_TITLE" IS '게시글 제목';
COMMENT ON COLUMN "BOARD"."BOARD_CONTENT" IS '게시글 내용';
COMMENT ON COLUMN "BOARD"."B_CREATE_DATE" IS '게시글 작성일';
COMMENT ON COLUMN "BOARD"."B_UPDATE_DATE" IS '마지막 수정일(수정 시 UPDATE)';
COMMENT ON COLUMN "BOARD"."READ_COUNT" IS '조회수';
COMMENT ON COLUMN "BOARD"."BOARD_DEL_FL" IS '삭제 여부(N : 삭제X , Y : 삭제O)';
COMMENT ON COLUMN "BOARD"."MEMBER_NO" IS '작성자 회원 번호';
COMMENT ON COLUMN "BOARD"."BOARD_CODE" IS '게시판 코드 번호';
...
<nav>
<ul>
<%-- <li><a href="#">공지사항</a></li>
<li><a href="#">자유 게시판</a></li>
<li><a href="#">질문 게시판</a></li>
<li><a href="#">FAQ</a></li>
<li><a href="#">1:1문의</a></li> --%>
<%-- interceptor를 이용해서 조회된 boardTypeList를
application scope에서 얻어와 화면에 출력
--%>
<c:forEach items="${boardTypeList}" var="boardType">
<li><a href="#">${boardType.BOARD_NAME}</a></li>
</c:forEach>
</ul>
</nav>
package edu.kh.project.common.interceptor;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import edu.kh.project.board.model.service.BoardService;
// Interceptor : 요청/응답을 가로채는 객체
// Client <-> Filter <-> Dispatcher Servlet <-> Interceptor <-> Controller
public class BoardTypeInterceptor implements HandlerInterceptor {
@Autowired
private BoardService service;
// 전처리
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// application scope 내장 객체 얻어오기
ServletContext application = request.getServletContext();
// application scope에 BOARD_TYPE이 조회되어 세팅이 되지 않았다면
// -> 서버 시작 후 누구도 요청한 적이 없을 경우
if(application.getAttribute("boardTypeList") == null) {
// 조회 서비스 호출
System.out.println("BOARD_TYPE 조회 서비스 호출");
List<Map<String, Object>> boardTypeList = service.selectBoardTypeList();
System.out.println(boardTypeList);
// application scope에 세팅
application.setAttribute("boardTypeList", boardTypeList);
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
package edu.kh.project.board.model.service;
import java.util.List;
import java.util.Map;
public interface BoardService {
/** 게시판 종류 목록 조회
* @return boardTypeList
*/
List<Map<String, Object>> selectBoardTypeList();
}
package edu.kh.project.board.model.service;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import edu.kh.project.board.model.dao.BoardDAO;
@Service
public class BoardServiceImpl implements BoardService{
@Autowired
private BoardDAO dao;
// 게시판 종류 목록 조회
@Override
public List<Map<String, Object>> selectBoardTypeList() {
return dao.selectBoardTypeList();
}
}
package edu.kh.project.board.model.dao;
import java.util.List;
import java.util.Map;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class BoardDAO {
@Autowired
private SqlSessionTemplate sqlSession;
/** 게시판 종류 목록 조회
* @return boardTypeList
*/
public List<Map<String, Object>> selectBoardTypeList() {
return sqlSession.selectList("boardMapper.selectBoardTypeList");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="boardMapper">
<!--
resultType이 "map"인 경우
K : 컬럼 명(BOARD_CODE, BOARD_NAME)
V : 컬럼 값( 1 , 공지사항 )
-->
<!-- 게시판 종류 목록 조회 -->
<select id="selectBoardTypeList" resultType="map">
SELECT * FROM BOARD_TYPE ORDER BY 1
</select>
</mapper>
메인 페이지가 출력되는 동시에 header의 nav에 BOARD_TYPE 테이블에 삽입된 게시판 이름이 순서대로 출력되는 모습을 볼 수 있다.