[Framework] TIL 061 - 23.10.16

유진·2023년 10월 15일
0

07_Framework

게시판 SQL 생성

-- 게시판 종류
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;
SELECT * FROM "BOARD_TYPE";


-- [게시판 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 '게시판 코드 번호';
----------------------------------------------------------------------
CREATE TABLE "BOARD_IMG" (
	"IMG_NO"	NUMBER		NOT NULL,
	"IMG_PATH"	VARCHAR2(300)		NOT NULL,
	"IMG_RENAME"	VARCHAR2(30)		NOT NULL,
	"IMG_ORIGINAL"	VARCHAR2(300)		NOT NULL,
	"IMG_ORDER"	NUMBER		NOT NULL,
	"BOARD_NO"	NUMBER		NOT NULL
);
COMMENT ON COLUMN "BOARD_IMG"."IMG_NO" IS '이미지 번호(SEQ_IMG_NO)';
COMMENT ON COLUMN "BOARD_IMG"."IMG_PATH" IS '이미지 저장 폴더 경로';
COMMENT ON COLUMN "BOARD_IMG"."IMG_RENAME" IS '변경된 이미지 파일 이름';
COMMENT ON COLUMN "BOARD_IMG"."IMG_ORIGINAL" IS '원본 이미지 파일 이름';
COMMENT ON COLUMN "BOARD_IMG"."IMG_ORDER" IS '이미지 파일 순서 번호';
COMMENT ON COLUMN "BOARD_IMG"."BOARD_NO" IS '이미지가 첨부된 게시글 번호';
----------------------------------------------------------------------
CREATE TABLE "BOARD_LIKE" (
	"BOARD_NO"	NUMBER		NOT NULL,
	"MEMBER_NO"	NUMBER		NOT NULL
);
COMMENT ON COLUMN "BOARD_LIKE"."BOARD_NO" IS '게시글 번호';
COMMENT ON COLUMN "BOARD_LIKE"."MEMBER_NO" IS '좋아요 누른 회원 번호';
----------------------------------------------------------------------
CREATE TABLE "COMMENT" (
	"COMMENT_NO"	NUMBER		NOT NULL,
	"COMMENT_CONTENT"	VARCHAR2(4000)		NOT NULL,
	"C_CREATE_DATE"	DATE	DEFAULT SYSDATE	NOT NULL,
	"COMMENT_DEL_FL"	CHAR(1)	DEFAULT 'N'	NOT NULL,
	"BOARD_NO"	NUMBER		NOT NULL,
	"MEMBER_NO"	NUMBER		NOT NULL,
	"PARENT_NO"	NUMBER	
);
COMMENT ON COLUMN "COMMENT"."COMMENT_NO" IS '댓글 번호(SEQ_COMMENT_NO)';
COMMENT ON COLUMN "COMMENT"."COMMENT_CONTENT" IS '댓글 내용';
COMMENT ON COLUMN "COMMENT"."C_CREATE_DATE" IS '댓글 작성일';
COMMENT ON COLUMN "COMMENT"."COMMENT_DEL_FL" IS '댓글 삭제 여부(N : 삭제X, Y : 삭제O)';
COMMENT ON COLUMN "COMMENT"."BOARD_NO" IS '댓글이 작성된 게시글 번호';
COMMENT ON COLUMN "COMMENT"."MEMBER_NO" IS '댓글 작성자 회원 번호';
COMMENT ON COLUMN "COMMENT"."PARENT_NO" IS '부모 댓글 번호';
----------------------------------------------------------------------
ALTER TABLE "BOARD" ADD CONSTRAINT "PK_BOARD" PRIMARY KEY (
	"BOARD_NO"
);
ALTER TABLE "BOARD_IMG" ADD CONSTRAINT "PK_BOARD_IMG" PRIMARY KEY (
	"IMG_NO"
);
ALTER TABLE "BOARD_LIKE" ADD CONSTRAINT "PK_BOARD_LIKE" PRIMARY KEY (
	"BOARD_NO",
	"MEMBER_NO"
);
ALTER TABLE "COMMENT" ADD CONSTRAINT "PK_COMMENT" PRIMARY KEY (
	"COMMENT_NO"
);
ALTER TABLE "BOARD" ADD CONSTRAINT "FK_MEMBER_TO_BOARD_1" FOREIGN KEY (
	"MEMBER_NO"
)
REFERENCES "MEMBER" (
	"MEMBER_NO"
);
ALTER TABLE "BOARD" ADD CONSTRAINT "FK_BOARD_TYPE_TO_BOARD_1" FOREIGN KEY (
	"BOARD_CODE"
)
REFERENCES "BOARD_TYPE" (
	"BOARD_CODE"
);
ALTER TABLE "BOARD_IMG" ADD CONSTRAINT "FK_BOARD_TO_BOARD_IMG_1" FOREIGN KEY (
	"BOARD_NO"
)
REFERENCES "BOARD" (
	"BOARD_NO"
);
ALTER TABLE "BOARD_LIKE" ADD CONSTRAINT "FK_BOARD_TO_BOARD_LIKE_1" FOREIGN KEY (
	"BOARD_NO"
)
REFERENCES "BOARD" (
	"BOARD_NO"
);
ALTER TABLE "BOARD_LIKE" ADD CONSTRAINT "FK_MEMBER_TO_BOARD_LIKE_1" FOREIGN KEY (
	"MEMBER_NO"
)
REFERENCES "MEMBER" (
	"MEMBER_NO"
);
ALTER TABLE "COMMENT" ADD CONSTRAINT "FK_BOARD_TO_COMMENT_1" FOREIGN KEY (
	"BOARD_NO"
)
REFERENCES "BOARD" (
	"BOARD_NO"
);
ALTER TABLE "COMMENT" ADD CONSTRAINT "FK_MEMBER_TO_COMMENT_1" FOREIGN KEY (
	"MEMBER_NO"
)
REFERENCES "MEMBER" (
	"MEMBER_NO"
);
ALTER TABLE "COMMENT" ADD CONSTRAINT "FK_COMMENT_TO_COMMENT_1" FOREIGN KEY (
	"PARENT_NO"
)
REFERENCES "COMMENT" (
	"COMMENT_NO"
);
-- 시퀀스 생성
CREATE SEQUENCE SEQ_BOARD_NO NOCACHE; -- 게시글 번호
CREATE SEQUENCE SEQ_IMG_NO NOCACHE; -- 게시글 이미지 번호
CREATE SEQUENCE SEQ_COMMENT_NO NOCACHE; -- 댓글 번호
-- BOARD 테이블 샘플 데이터 삽입(PL/SQL)
BEGIN
FOR I IN 1..2000 LOOP
INSERT INTO BOARD
VALUES( SEQ_BOARD_NO.NEXTVAL,
SEQ_BOARD_NO.CURRVAL || '번째 게시글',
SEQ_BOARD_NO.CURRVAL || '번째 게시글 내용 입니다.',
DEFAULT, DEFAULT, DEFAULT, DEFAULT, 1,
CEIL(DBMS_RANDOM.VALUE(0,4))
);
END LOOP;
END;
COMMIT;


SELECT * FROM BOARD;

-- DROP TABLE BOARD CASCADE CONSTRAINT;

-- DROP SEQUENCE SEQ_BOARD_NO;

------------------------------------------------------
-- COMMENT 테이블 샘플 데이터 삽입(PL/SQL)
BEGIN
FOR I IN 1..1000 LOOP
	 INSERT INTO "COMMENT"
		VALUES(SEQ_COMMENT_NO.NEXTVAL,
				SEQ_COMMENT_NO.CURRVAL || '번째 댓글',
				DEFAULT, DEFAULT,
				 CEIL(DBMS_RANDOM.VALUE(0,2000)),
				 1, NULL);
END LOOP;
END;
COMMIT;

SELECT * FROM "COMMENT";


-- 게시글 샘플 이미지
INSERT INTO BOARD_IMG
VALUES(SEQ_IMG_NO.NEXTVAL, '/resources/images/board/',
		'20230508115013_00001.jpg', 'cat1.jpg', 0, 1996);
	
INSERT INTO BOARD_IMG
VALUES(SEQ_IMG_NO.NEXTVAL, '/resources/images/board/',
		'20230508115013_00002.jpg', 'cat2.jpg', 0, 1995);
	
INSERT INTO BOARD_IMG
VALUES(SEQ_IMG_NO.NEXTVAL, '/resources/images/board/',
		'20230508115013_00003.jpg', 'cat3.jpg', 0, 1994);
	
INSERT INTO BOARD_IMG
VALUES(SEQ_IMG_NO.NEXTVAL, '/resources/images/board/',
		'20230508115013_00004.jpg', 'cat4.jpg', 0, 1993);
	
INSERT INTO BOARD_IMG
VALUES(SEQ_IMG_NO.NEXTVAL, '/resources/images/board/',
		'20230508115013_00005.jpg', 'cat5.jpg', 0, 1989);
COMMIT;

SELECT * FROM BOARD_IMG;

BoardTypeInterceptor.java

  • Filter : 전반적으로 쓰일 보안/인증/인가 관련 작업, 문자열 인코딩
  • Interceptor : 요청에 대한 데이터 가공, 세부적으로 쓰일 보안/인증

Alt + Shift + S 후, >

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

// Filter : 전반적으로 쓰일 보안/인증/인가 관련 작업, 문자열 인코딩, 이미지 데이터 압축..
// Interceptor : 요청에 대한 '데이터 가공' -> Controller로 넘겨주기 위한 정보/데이터 가공,
//				 세부적으로 쓰일 보안/인증


// Handle = '처리' 의미
public class BoardTypeInterceptor implements HandlerInterceptor {
	
	/* preHandle : 전처리		      Dispathcer Servlet -> Contoller 사이
	 * postHandle : 후처리	      Controller -> Dispathcer Servlet 사이
	 * afterCompletion : 뷰 완성 후  View Resolver -> Dispathcer Servlet 사이
	 * */
	
	@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: " + 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 {
		// TODO Auto-generated method stub
		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}

	
}

servlet-context.xml

BoardService.java

package edu.kh.project.board.model.service;

import java.util.List;
import java.util.Map;

public interface BoardService {

	List<Map<String, Object>> selectBoardTypeList();

}

BoardServiceImpl.java

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();
	}
	
}

boardDAO.java

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
	 */
	public List<Map<String, Object>> selectBoardTypeList() {
		return sqlSession.selectList("boardMapper.selectBoardTypeList");
	}

}

board-mapper.xml

<?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	   ,   공지 사항  )
		
		[{BOARD_NAME= 공지사항, BOARD_CODE=1}, {BOARD_NAME= 자유게시판, BOARD_CODE=2}, ...]
	 -->

	<!-- 게시판 종류 목록 조회 -->
	<select id="selectBoardTypeList" resultType="map">
		SELECT * FROM "BOARD_TYPE" ORDER BY 1
	</select>


</mapper>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" >
<configuration>

	<!-- SqlSessionTemplate 관련 설정 -->
	<settings>
	
		<!-- insert, update 사용 값중 null 이 있을 경우 
			SQL 구문에 null 포함되어 있다는 오류 발생
			이 설정 후, 오류 발생 X, NULL 값을 컬럼에 대입
			단, NOT NULL 제약조건이 없는 컬럼에만 가능
		-->
		<setting name="jdbcTypeForNull" value="NULL"/>
	</settings>
	
	<!-- 별칭 작성 부분 -->
	<!-- VO/DTO 클래스의 패키지명+클래스명 작성하는게 불편하기 때문에 짧은 별칭을 부여 -->
	<typeAliases>
		<typeAlias type="edu.kh.project.member.model.dto.Member" alias="Member"/>
	
	</typeAliases>
	
	
	<!-- mapper파일(SQL 작성되는파일) 위치 등록 부분 -->
	<mappers>
		<mapper resource="/mappers/member-mapper.xml"/>
		<mapper resource="/mappers/ajax-mapper.xml"/>
		<mapper resource="/mappers/email-mapper.xml"/>
		<mapper resource="/mappers/myPage-mapper.xml"/>
		<mapper resource="/mappers/board-mapper.xml"/>
		<!-- 추후 board-mapper를 사용하고 싶다면 추가해야 함!
		<mapper resource="/mappers/board-mapper.xml"/>
		 -->
	</mappers>


</configuration>

header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    
<link rel="stylesheet" href="/resources/css/main-style.css">

	<header>

            <!-- 클릭 시 메인페이지로 이동하는 로고 -->
            <section>
                <a href="/">
                    <img src="/resources/images/logo.jpg" id="homeLogo">
                </a>
            </section>

            <!-- 검색창 부분 -->
            <section>
                <section class="search-area">
                    <!-- form 내부 input 태그 값을 서버 또는 페이지로 전달 -->
                    <form action="/search" method="GET" name="search-form">

                        <!-- fieldset : form 내부에서 input을 종류별로 묶는 용도로 자주 사용 -->
                        <fieldset>

                            <!-- search : 텍스트 타입과 기능적으로는 똑같으나,
                                브라우저에 의해 다르게 표현될 수 있음. -->
                            <!-- autocomplete : HTML 기본 자동완성 사용 X -->
                            <input type="search" id="query" name="query"
                                autocomplete="off" placeholder="회원을 닉네임으로 검색해주세요."
                            >

                            <button id="searchBtn" class="fa-solid fa-magnifying-glass"></button>
                        </fieldset>

                    </form>

                </section>
            </section>

            <section></section>
        </header>

        <!-- 보통은 header안에 작성하나 사이드에 nav가 있는 경우도 있기 때문에 따로 작성해본다! -->
        <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에서 얻어와 화면에 출력
                 --%>
                  
                 <%--
                 [
                 {BOARD_NAME=공지사항, BOARD_CODE=1},
                 {BOARD_NAME=자유 게시판, BOARD_CODE=2},
                 {BOARD_NAME=테스트 게시판, BOARD_CODE=3},
                 {BOARD_NAME=질문 게시판, BOARD_CODE=4},
                 {BOARD_NAME=점심 게시판, BOARD_CODE=5}
                 ]
                  --%>
                 <c:forEach var="boardType" items="${boardTypeList}">
                 	<li>
                 		<a href="/board/${boardType.BOARD_CODE}">${boardType.BOARD_NAME}</a>
                 	</li>
                 </c:forEach> 
            </ul>
        </nav>



header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    
<link rel="stylesheet" href="/resources/css/main-style.css">

	<header>

            <!-- 클릭 시 메인페이지로 이동하는 로고 -->
            <section>
                <a href="/">
                    <img src="/resources/images/logo.jpg" id="homeLogo">
                </a>
            </section>

            <!-- 검색창 부분 -->
            <section>
                <section class="search-area">
                    <!-- form 내부 input 태그 값을 서버 또는 페이지로 전달 -->
                    <form action="/search" method="GET" name="search-form">

                        <!-- fieldset : form 내부에서 input을 종류별로 묶는 용도로 자주 사용 -->
                        <fieldset>

                            <!-- search : 텍스트 타입과 기능적으로는 똑같으나,
                                브라우저에 의해 다르게 표현될 수 있음. -->
                            <!-- autocomplete : HTML 기본 자동완성 사용 X -->
                            <input type="search" id="query" name="query"
                                autocomplete="off" placeholder="회원을 닉네임으로 검색해주세요."
                            >

                            <button id="searchBtn" class="fa-solid fa-magnifying-glass"></button>
                        </fieldset>

                    </form>

                </section>
            </section>

            <section></section>
        </header>

        <!-- 보통은 header안에 작성하나 사이드에 nav가 있는 경우도 있기 때문에 따로 작성해본다! -->
        <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에서 얻어와 화면에 출력
                 --%>
                  
                 <%--
                 [
                 {BOARD_NAME=공지사항, BOARD_CODE=1},
                 {BOARD_NAME=자유 게시판, BOARD_CODE=2},
                 {BOARD_NAME=테스트 게시판, BOARD_CODE=3},
                 {BOARD_NAME=질문 게시판, BOARD_CODE=4},
                 {BOARD_NAME=점심 게시판, BOARD_CODE=5}
                 ]
                  --%>
                 <c:forEach var="boardType" items="${boardTypeList}">
                 	<li>
                 		<a href="/board/${boardType.BOARD_CODE}">${boardType.BOARD_NAME}</a>
                 	</li>
                 </c:forEach> 
            </ul>
        </nav>

BoardController.java

package edu.kh.project.board.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

@SessionAttributes({"loginMember"})
@RequestMapping("/board")
@Controller
public class BoardController {
	
	/*  목록 조회 : /board/1?cp=1 (cp: current page(현재페이지))
	 *  상세 조회 : /board/1/1500?cp=1
	 *  
	 *  ** 컨트롤러 따로 생성 **
	 *  삽입 : /board2/1/insert
	 *  수정 : /board2/1/1500/update
	 *  삭제 : /board2/1/1500/delete
	 * */
	
	
	@GetMapping("/{boardCode}") // @PathVariable : 주소를 값 자체로 쓸 수 있는 것
	public String selectBoardList( @PathVariable("boardCode") int boardCode ) {
		
		// boardCode 확인
		System.out.println("boardCode : " + boardCode);
		
		return "board/boardList";
	}

}

공지사항 클릭 시, 콘솔창
해당 페이지로 이동


-> 주소에 영어 입력 시, 더이상 페이지가 매핑되지 않음( 숫자만 입력 가능 )


BoardController.java

package edu.kh.project.board.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

@SessionAttributes({"loginMember"})
@RequestMapping("/board")
@Controller
public class BoardController {
	
	/*  목록 조회 : /board/1?cp=1 (cp: current page(현재페이지))
	 *  상세 조회 : /board/1/1500?cp=1
	 *  
	 *  ** 컨트롤러 따로 생성 **
	 *  삽입 : /board2/1/insert
	 *  수정 : /board2/1/1500/update
	 *  삭제 : /board2/1/1500/delete
	 * */
	
	/*
	 * ******** @PathVariable 사용 시 문제점과 해결법 ********
	 * 
	 * 문제점 : 요청 주소와 @PathVariable로 가져다 쓸 주소와 레벨이 같다면
	 * 		구분하지 않고 모두 매핑되는 문제가 발생
	 * 
	 * 해결방법 : @PathVariable 지정 시 정규 표현식 사용
	 * {키:정규표현식}
	 * */
	
	
	
	
	@GetMapping("/{boardCode:[0-9]+}") // boardCode는 1자리 이상 숫자
									   // @PathVariable : 주소를 값 자체로 쓸 수 있는 것
	public String selectBoardList( @PathVariable("boardCode") int boardCode ) {
		
		// boardCode 확인
		System.out.println("boardCode : " + boardCode);
		
		return "board/boardList";
	}

}

0개의 댓글