20211215 게시판 페이징 및 글쓰기

DUUUPPAAN·2021년 12월 15일
0

Spring_Framework

목록 보기
8/19

·돌아온 대면 수업

-월요일은 코로나 확진자로 인해 갑작스럽게 코로나 검사와 귀가를 하게 되었고, 어제는 전 인원이 비대면으로 수업을 진행했다. 그리고 드디어 수요일인 오늘 대면수업을 하게 되었다. 집에서 하는 것도 나쁘지 않았지만, 역시 대면수업이 집중력 발휘는 훨씬 좋다는 점을 부정할 수 없다. 역시 사람은 환경이 정말 중요한 것 같다.

·미뤄왔던 페이징과 글쓰기 & 파일첨부

-우선 어제 완성하지 못한 파일첨부에 대한 부분을 먼저 진행했다.

@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
   public int boardInsert(HiBoard hiBoard) throws Exception 
   {
	   //Propagation.REQUIRED
	   //만약에 기존에 트랜잭션이 있었을 경우, 기존 트랜잭션을 유지, 없을 경우 새로운 트랜잭션 생성.
	   
	   //얘를 사용하는 곳에 예외처리를 넘김.
	   int count = 0;
	   
	   //얘는 예외처리를 여기서 안함. 왜? 트랜젝션으로 묶어야 하기 때문에.
	   count = hiBoardDao.boardInsert(hiBoard);
	   
	   //게시물이 정상적으로 등록되면, 첨부파일이 있다면 첨부파일 등록
	   if(count > 0 && hiBoard.getHiBoardFile() != null) 
	   {
		   //count가 0보다 크다는 것은 입력 성공, 
		   //하이보드파일은 얘를 호출한 컨트롤러에서 정의가 되어 있기 때문에 가져올 수 있음. 파라미터로 받았으니껜.
		   HiBoardFile hiBoardFile = hiBoard.getHiBoardFile();
		   //하이보드파일 객체를 생성해서 컨트롤러에서 선언한 하이보드 파일의 주소를 바라보게 함.
		   //왜 이렇게 하냐면 같은 곳을 바라봐야 바뀐 값을 적용했을 때, 여기선 바뀌고 저기선 안바뀌는 불상사를 방지할 수 있으니까.
		   
		   hiBoardFile.setHiBbsSeq(hiBoard.getHiBbsSeq());
		   hiBoardFile.setFileSeq((short)1);
		   //원래는 파일 첨부파일의 갯수에 따라서 숫자가 바뀌게 해야 하지만 지금은 하드코딩.
		   //만약에 첨부파일이 2개가 되는 경우에, 여기서 1을 하드코딩한다면 문제가 발생함.
		   //hiBbsSeq와 fileSeq 두 개의 값으로 컬럼의 고유값을 유지하는데, 게시물번호도 같고 첨부파일번호도 같은 컬럼이 두 개가 되는 상황이기 때문에
		   //나중에 로직을 통해서 해당 부분의 하드코딩을 바꿔줄 예정
		   
		   hiBoardDao.boardFileInsert(hiBoardFile);
		   //hiBoardDao.boardFileInsert(hiBoard.getHiBoardFile());
		   //얘를 써도 됨. 왜냐면 같은 주소를 바라보고 있기 때문에.
		   
		   
	   }
	   
	   return count;
   }

-서비스쪽에서 트랜잭션 어노테이션을 사용해서 게시글과 파일첨부를 동시에 처리되도록 해줬다. 물론, 파일첨부는 파일이 있을 때만 진행할 수 있도록 조건문으로 처리했다. if(count > 0 && hiBoard.getHiBoardFile() != null) 이 부분이 바로 그 부분이다. 사실 원래는 fileSeq의 값을 1로 하드코딩하지 않고, 여러개의 파일첨부가 가능하게 테이블을 만들었지만, 처음하는 파일첨부이니 해당 부분을 그냥 1개만 올린다는 가정으로 하드코딩했다.

-어제 게시글에 대한 .xml은 작성했지만 파일첨부에 대한 부분은 작성하지 않았다. 그래서 SQL디벨로퍼에서 쿼리문을 작성하고 xml파일에 파일첨부 부분의 쿼리를 넣어줬다.

<!-- 첨부파일 등록 시작 -->
<insert id="boardFileInsert" parameterType="com.icia.web.model.HiBoardFile">
INSERT INTO TBL_HIBOARD_FILE (
    HIBBS_SEQ,
    FILE_SEQ,
    FILE_ORG_NAME,
    FILE_NAME,
    FILE_EXT,
    FILE_SIZE,
    REG_DATE
) VALUES (
    #{hiBbsSeq},
    #{fileSeq},
    #{fileOrgName},
    #{fileName},
    #{fileExt},
    #{fileSize},
    SYSDATE
)
</insert>
<!-- 첨부파일 등록 종료-->

-물론 당연히 위의 아이디값과 같은 이름의 추상메소드를 dao.java에 정의해줘야 한다.

	public int boardFileInsert(HiBoardFile hiBoardFile);

서비스 부분은 위에서 작성했기 때문에 컨트롤러 부분을 작성해준다.

	//글쓰기 처리, 게시물 등록
	@RequestMapping(value="/board/writeProc", method=RequestMethod.POST)
	@ResponseBody
	public Response<Object> writeProc(MultipartHttpServletRequest request, HttpServletResponse response)
	{
		Response<Object> ajaxResponse = new Response<Object>();
		
		String cookieUserId = CookieUtil.getHexValue(request, AUTH_COOKIE_NAME);
		String hiBbsTitle = HttpUtil.get(request, "hiBbsTitle", "");
		String hiBbsContent = HttpUtil.get(request, "hiBbsContent", "");
		
		//첨부파일에 대한 것을 받을 것.
		//write.jsp에서 보낸 파일이 아래의 아이디임
		//즉, hiBbsFile이 첨부파일의 인풋 아이디임
		FileData fileData = HttpUtil.getFile(request, "hiBbsFile", UPLOAD_SAVE_DIR);
		//뒤에는 파일 경로에 대한 부분
		
		//브라우저에서 값이 있냐없냐를 넘겨주지만
		//경로명을 알면 바로 들어오는 경우가 있음
		//그래서 해당 부분에 대한 예외 처리
		if(!StringUtil.isEmpty(hiBbsTitle) && !StringUtil.isEmpty(hiBbsContent)) 
		{
			//둘 다 값이 있으면
			//HiBoard 객체에 각각의 값들을 넣어서 적용.
			HiBoard hiBoard = new HiBoard();
			hiBoard.setUserId(cookieUserId);
			hiBoard.setHiBbsTitle(hiBbsTitle);
			hiBoard.setHiBbsContent(hiBbsContent);
			
			//첨부파일에 대한 조건
			//이미 클라이언트에서 fileData에 값을 넣어놨음
			//넘어온 값이 null이 아니고, 파일 사이즈가 존재하는 경우에만 실행
			if(fileData != null && fileData.getFileSize()>0) 
			{
				HiBoardFile hiBoardFile = new HiBoardFile();
				
				hiBoardFile.setFileName(fileData.getFileName());
				hiBoardFile.setFileOrgName(fileData.getFileOrgName());
				hiBoardFile.setFileName(fileData.getFileName());
				hiBoardFile.setFileSize(fileData.getFileSize());

				//서비스는 하나를 콜할 것임. 해당 서비스에서 hiboard테이블에 인서트 시키고
				//그제서야 하이보드파일을 인서트 시키도록 할 것임.
				
				//현재 값을 넣은 객체의 주소값을 
				//하이보드 내에 있는 하이보드파일 객체와 같은 곳을 바라보게 해줌.
				//왜냐면 hiBoardFile은 지역변수이기 때문에 해당 if 부분을 벗어나면 사라짐
				//그래서 주소값을 일치시켜주는 것임, 그래야 밖에서 사용할 수 있음
				hiBoard.setHiBoardFile(hiBoardFile);
			}
			
			//게시물 또는 게시물 파일 첨부 적용에 대한 코드 작성할 부분 표시
			
			//여기에 예외처리를 넘겼음.
			//이 부분은 트랜젝션으로 처리할 것이라서, 이건 이클립스가 오라클에게 트랜젝션이라고 알려주는 것.
			try 
			{
				if(hiBoardService.boardInsert(hiBoard)> 0) 
				{
					//정상 처리, 처리건수가 0이 아니여서
					ajaxResponse.setResponse(0, "Success");
				}
				else 
				{
					ajaxResponse.setResponse(500, "Internal Server Error");
				}
			}
			catch(Exception e) 
			{
				logger.error("[HiBoardController] /board/writeProc Exception", e);
				ajaxResponse.setResponse(500, "Internal Server Error");
			}
		}
		else 
		{
			//값이 없음
			ajaxResponse.setResponse(400, "Bad Request: No parameter");
		}
		
		return ajaxResponse;
	}

-어제 코드에 이어서 작성했기 때문에 중간 부분만 적으면 이해가 쉽지 않을 것 같아 우선 전체 코드를 복사 붙여넣어줬다. 그러나 사실 오늘 진행한 부분은 저 중에서

			//첨부파일에 대한 조건
			//이미 클라이언트에서 fileData에 값을 넣어놨음
			//넘어온 값이 null이 아니고, 파일 사이즈가 존재하는 경우에만 실행
			if(fileData != null && fileData.getFileSize()>0) 
			{
				HiBoardFile hiBoardFile = new HiBoardFile();
				
				hiBoardFile.setFileName(fileData.getFileName());
				hiBoardFile.setFileOrgName(fileData.getFileOrgName());
				hiBoardFile.setFileName(fileData.getFileName());
				hiBoardFile.setFileSize(fileData.getFileSize());

				//서비스는 하나를 콜할 것임. 해당 서비스에서 hiboard테이블에 인서트 시키고
				//그제서야 하이보드파일을 인서트 시키도록 할 것임.
				
				//현재 값을 넣은 객체의 주소값을 
				//하이보드 내에 있는 하이보드파일 객체와 같은 곳을 바라보게 해줌.
				//왜냐면 hiBoardFile은 지역변수이기 때문에 해당 if 부분을 벗어나면 사라짐
				//그래서 주소값을 일치시켜주는 것임, 그래야 밖에서 사용할 수 있음
				hiBoard.setHiBoardFile(hiBoardFile);
			}

이 부분이다. 파일데이터가 널값이 아니고 파일사이즈도 0이상이라는 것은, 파일이 존재한다는 뜻이고, 그 때, 입력할 각각의 값들, 파일 이름이나 원래 이름, 사이즈 등에 대한 정보를 넣어주고 하이보드가 갖고 있는 하이보드파일 객체에 해당 값을 넣어준다. 여기서 굳이 이런 구조(하이보드가 하이보드 파일 객체를 내부적으로 갖고 있는 구조)를 사용한 이유는 1. 종속적인 구조이기 때문이고, 2. 지역변수를 더 넓은 범위에서 사용하기 위함이다.

-이제 페이징을 위한 공통모듈을 사용해서 페이징 처리하는 부분을 살펴보겠다.

//메소드 방식이 없으면 디폴트로 GET방식이 옴.
	@RequestMapping(value="/board/list")
	public String list(ModelMap model, HttpServletRequest request, HttpServletResponse response) 
	{
		//자기가 자기를 부를 수 있으니까 확인하기
		//조회 항목(1:작성자, 2:제목, 3:내용)
		String searchType = HttpUtil.get(request, "searchType", "");
		//조회값
		String searchValue = HttpUtil.get(request, "searchValue", "");
		//현재 페이지
		long curPage = HttpUtil.get(request, "curPage",(long)1);
		
		long totalCount = 0;
		List<HiBoard> list = null;
		
		//페이징 객체
		Paging paging = null;
		
		//조회 객체
		//넘길 파라미터 값이 많으니까, 객체로 넘기는 것임.
		HiBoard search = new HiBoard();
		
		if(!StringUtil.isEmpty(searchType) && !StringUtil.isEmpty(searchValue)) 
		{
			//받아온 값이 있음.
			search.setSearchType(searchType);
			search.setSearchValue(searchValue);
		}
		else 
		{
			searchType = "";
			searchValue = "";
		}
		
		//두개의 값만 넘기면 전체 건수를 알 수 있음.
		//먼저 토탈 카운트를 하는 이유는 인덱스부터 빠르게 찾아서 값이 있냐를 보고 진행하겠다는 뜻임.
		//+로 페이징 처리를 위해서 토탈 카운트를 하는 것도 있음.
		totalCount = hiBoardService.boardListCount(search);
		
		logger.debug("[totalCount] = "+totalCount);
		
		if(totalCount > 0 ) 
		{
			//검색 결과가 있음
			//페이징 처리 추가해야 함.
			paging = new Paging("/board/list", totalCount, LIST_COUNT, PAGE_COUNT, curPage, "curPage");
			paging.addParam("searchType", searchType);
			paging.addParam("searchValue", searchValue);
			paging.addParam("curPage", curPage);
			
			//시작 row와 종료 row를 paging 모듈에서 자동 계산해줌.
			search.setStartRow(paging.getStartRow());
			search.setEndRow(paging.getEndRow());
			
			list = hiBoardService.boardList(search);
		}
		
		//앞에 ""는 list.jsp에서 쓸 변수임. 내 메소드 내에 있는 변수가 뒤의 파라미터임.
		model.addAttribute("list", list);
		model.addAttribute("searchType", searchType);
		model.addAttribute("searchValue", searchValue);
		model.addAttribute("curPage", curPage);
		model.addAttribute("paging", paging);
		
		
		return "/board/list";
	}

-기존에 작성한 게시물을 가져오는 부분이다. 여기서 페이징 객체를 만들어서 해당 생성자의 각각의 값들을 넣어주면 자동으로 여러 값들을 계산해준다. 해당 값들을 search 객체 않에 다시 넣어준다. 또한 .jsp파일에 페이징 객체를 사용할 부분이 있기 때문에 페이징 객체도 ModelMap의 객체에 addAttribute해준다.

-list.jsp에서 기존에 하드코딩되어 있던, 이전블럭| 1 |다음블럭부분을 수정해줬다.

   <nav>
      <ul class="pagination justify-content-center">
		<c:if test="${!empty paging}">
			
			<c:if test="${paging.prevBlockPage gt 0}">
	        <!-- 이전 블럭이 있다는 뜻임, 이전 블럭 페이지가 0보다 크면. -->
	         	<li class="page-item"><a class="page-link" href="javascript:void(0)" onclick="fn_list(${paging.prevBlockPage})">이전블럭</a></li>
			</c:if>
	   		
	   		<c:forEach var="i" begin="${paging.startPage}" end="${paging.endPage}">

	   			<c:choose>
	   				<c:when test="${i ne curPage}">
	         			<li class="page-item"><a class="page-link" href="javascript:void(0)" onclick="fn_list(${i})">${i}</a></li>
					</c:when>
					<c:otherwise>
						<li class="page-item active"><a class="page-link" href="javascript:void(0)" style="cursor: default;">${i}</a></li>
					</c:otherwise>
				</c:choose>
			</c:forEach>
			
	        <c:if test="${paging.nextBlockPage gt 0}">
	         	<li class="page-item"><a class="page-link" href="javascript:void(0)" onclick="fn_list(${paging.nextBlockPage})">다음블럭</a></li>
			</c:if>
		</c:if>
      </ul>
   </nav>

-이전 블럭과 다음 블럭은 이전이나 다음으로 갈 수 있는 경우 처리되도록 했고, 중간의 숫자는 반복문을 통해서 보여주고 싶은 숫자(컨트롤러쪽에 5로 정의해놨다.)만큼 반복해서 생성되도록 했다. 또한 현재페이지는 버튼이 기능하지 않도록 처리했다.

·게시판 상세페이지를 위한 쿼리문

-게시판 상세페이지는 hiBbsSeq를 가지고 해당하는 게시글을 불러오고 해당하는 게시물의 첨부파일이 있으면 첨부파일까지 불러오고, 조회수를 +1하는 쿼리문이 총 3가지가 필요하다.
-그래서 쿼리문부터 작성했다.

--게시번호를 갖고 들어왔을 때 게시번호에 해당하는 게시판의 정보를 가져옴.
SELECT
    A.HIBBS_SEQ AS HIBBS_SEQ,
    A.USER_ID AS USER_ID,
    NVL(B.USER_NAME, '') AS USER_NAME,
    NVL(B.USER_EMAIL, '') AS USER_EMAIL,
    NVL(A.HIBBS_GROUP, 0) AS HIBBS_GROUP,
    NVL(A.HIBBS_ORDER, 0) AS HIBBS_ORDER,
    NVL(A.HIBBS_INDENT, 0) AS HIBBS_INDENT,
    NVL(A.HIBBS_TITLE, '') AS HIBBS_TITLE,
    NVL(A.HIBBS_CONTENT, '') AS HIBBS_CONTENT,
    NVL(A.HIBBS_READ_CNT, 0) AS HIBBS_READ_CNT,
    NVL(TO_CHAR(A.REG_DATE, 'YYYY.MM.DD HH24:MI:SS'), '') AS REG_DATE,
    NVL(A.HIBBS_PARENT, 0) AS HIBBS_PARENT
FROM
    TBL_HIBOARD A, TBL_USER B
WHERE
    HIBBS_SEQ = 5
  AND
    A.USER_ID = B.USER_ID
    ;
    
    
--게시물 조회시 +1되는거
UPDATE TBL_HIBOARD
   SET HIBBS_READ_CNT = HIBBS_READ_CNT + 1
 WHERE HIBBS_SEQ =5;
 
 ROLLBACK;
 


--첨부파일 조회 쿼리문 작성
SELECT
    HIBBS_SEQ,
    FILE_SEQ,
    NVL(FILE_ORG_NAME, '') AS FILE_ORG_NAME,
    NVL(FILE_NAME, '') AS FILE_NAME,
    NVL(FILE_EXT, '') AS FILE_EXT,
    NVL(FILE_SIZE, 0) AS FILE_SIZE,
    NVL(TO_CHAR(REG_DATE, 'YYYY.MM.DD HH24:MI:SS'), '') AS REG_DATE
FROM
    TBL_HIBOARD_FILE
WHERE
    HIBBS_SEQ = 7
  AND
    FILE_SEQ = 1
;

-크게 어렵지 않은 쿼리문이다. nvl처리는 자바에서도 해주지만, 그래도 db에서 또 한번 무조건 해주라고 하셨다.

-.xml파일에 해당 쿼리문에 대한 부분을 작성해줘야 한다. 다만, resultMap을 하이보드파일 테이블을 위해 하나 더 만들어야 하고, 어제 추가한 대댓글의 부모를 표시한 hiBbsParent도 맵핑시켜줘야 한다.

 <result column="HIBBS_PARENT" property="hiBbsParent" />
</resultMap>
<!-- 게시물에 대한 resultMap 종료-->

<!-- 첨부파일 resultMap 시작 -->
<resultMap id="hiBoardFileResultMap" type="com.icia.web.model.HiBoardFile">
    <id column="HIBBS_SEQ" property="hiBbsSeq" />
    <id column="FILE_SEQ" property="fileSeq" />
    <result column="FILE_ORG_NAME" property="fileOrgName" />
    <result column="FILE_NAME" property="fileName" />
    <result column="FILE_EXT" property="fileExt" />
    <result column="FILE_SIZE" property="fileSize" />
    <result column="REG_DATE" property="regDate" />
</resultMap>
<!-- 첨부파일 resultMap 종료 -->

-이제 진짜 쿼리문을 작성했다. 앞서 언급했다시피 매개변수로는 hiBbsSeq만 받는다. 물론 리턴타입은 HiBoard 객체가 될 것이다. 왜냐면, 시퀀스 번호로 해당 게시글의 여러 정보를 얻어와야 하기 때문이다.

<!-- 게시물 조회 시작-->
<select id="boardSelect" parameterType="long" resultMap="hiBoardResultMap">
SELECT
    A.HIBBS_SEQ AS HIBBS_SEQ,
    A.USER_ID AS USER_ID,
    NVL(B.USER_NAME, '') AS USER_NAME,
    NVL(B.USER_EMAIL, '') AS USER_EMAIL,
    NVL(A.HIBBS_GROUP, 0) AS HIBBS_GROUP,
    NVL(A.HIBBS_ORDER, 0) AS HIBBS_ORDER,
    NVL(A.HIBBS_INDENT, 0) AS HIBBS_INDENT,
    NVL(A.HIBBS_TITLE, '') AS HIBBS_TITLE,
    NVL(A.HIBBS_CONTENT, '') AS HIBBS_CONTENT,
    NVL(A.HIBBS_READ_CNT, 0) AS HIBBS_READ_CNT,
    NVL(TO_CHAR(A.REG_DATE, 'YYYY.MM.DD HH24:MI:SS'), '') AS REG_DATE,
    NVL(A.HIBBS_PARENT, 0) AS HIBBS_PARENT
FROM
    TBL_HIBOARD A, TBL_USER B
WHERE
    HIBBS_SEQ = #{value}
  AND
    A.USER_ID = B.USER_ID
</select>
<!-- 게시물 조회 종료 -->


<!-- 게시물 조회수 증가 시작 -->
<update id="boardReadCntPlus" parameterType="long">
UPDATE TBL_HIBOARD
   SET HIBBS_READ_CNT = HIBBS_READ_CNT + 1
 WHERE HIBBS_SEQ = #{value}
</update>
<!-- 게시물 조회수 증가 종료 -->


<!-- 첨부 파일 조회 시작 -->
<select id="boardFileSelect" parameterType="long" resultMap="hiBoardFileResultMap">
SELECT
    HIBBS_SEQ,
    FILE_SEQ,
    NVL(FILE_ORG_NAME, '') AS FILE_ORG_NAME,
    NVL(FILE_NAME, '') AS FILE_NAME,
    NVL(FILE_EXT, '') AS FILE_EXT,
    NVL(FILE_SIZE, 0) AS FILE_SIZE,
    NVL(TO_CHAR(REG_DATE, 'YYYY.MM.DD HH24:MI:SS'), '') AS REG_DATE
FROM
    TBL_HIBOARD_FILE
WHERE
    HIBBS_SEQ = #{value}
  AND
    FILE_SEQ = 1
</select>
<!-- 첨부 파일 조회 종료 -->

-물론 추상메소드도 정의해준다

	//게시물 조회
	public HiBoard boardSelect(long hiBbsSeq);
	
    //게시물 조회수 증가
	public int boardReadCntPlus(long hiBbsSeq);
	
	//게시물 첨부파일 조회
	public HiBoardFile boardFileSelect(long hiBbsSeq);

-이제 서비스쪽에서 정의해준다. 따로 트랜잭션을 줄 필요가 없으니 try catch문을 사용한다.

//게시물 조회, 파일 포함
   public HiBoard boardView(long hiBbsSeq) 
   {
	   //조회하고, 파일 있으면 조회하고, 조회수 늘리고
	   HiBoard hiBoard = null;
	   
	   try 
	   {
		   hiBoard = hiBoardDao.boardSelect(hiBbsSeq);
		   
		   if(hiBoard != null) 
		   {
			   //조회수 증가, 근데 처리할 게 없으니까 따로 어디다 담을 필요가 없음
			   hiBoardDao.boardReadCntPlus(hiBbsSeq);
			   
			   HiBoardFile hiBoardFile = hiBoardDao.boardFileSelect(hiBbsSeq);
			   //HiBoardFile hiBoardFile = hiBoardDao.boardFileSelect(hiBoard.getHiBbsSeq()); 이렇게 써도 됨
			   if(hiBoardFile !=null) 
			   {
				   //시작 주소 값을 일치시킴. 왜냐면 하이보드파일 객체가 지역변수라서 값을 잃게하지 않기 위해.
				   //또 리턴 타입이 HiBoard이기 때문에 안에 넣어줌
				   hiBoard.setHiBoardFile(hiBoardFile);
			   }
		   }		   
	   }
	   catch(Exception e) 
	   {
		   logger.error("[HiBoardService] boardView Exception", e);
	   }
	   
	   return hiBoard;
   }

-따로 특이할 것이 없다. 그냥 하이보드 객체 안에 하이보드파일 객체가 정의되어 있다는 것만 알면 되는 것 같다.

//게시물 조회
	@RequestMapping(value="/board/view")
	public String view(ModelMap model, HttpServletRequest request, HttpServletResponse response) 
	{
		String cookieUserId = CookieUtil.getHexValue(request, AUTH_COOKIE_NAME);
		
		//정보를 가져와야 하니까 가져와야 함.
		long hiBbsSeq = HttpUtil.get(request, "hiBbsSeq", (long)0);
		
		String searchType = HttpUtil.get(request, "searchType", "");
		String searchValue = HttpUtil.get(request, "searchValue", "");
		long curPage = HttpUtil.get(request, "curPage", (long)1);
		
		//본인글 여부
		String boardMe = "N";
		HiBoard hiBoard = null;
		
		//0보다 클 때 정상적으로 값이 넘어온 것임.
		if(hiBbsSeq > 0) 
		{
			//하이보드 객체에 서비스에서 한 것을 넣어줌
			hiBoard = hiBoardService.boardView(hiBbsSeq);
			
			if(hiBoard !=null && StringUtil.equals(hiBoard.getUserId(), cookieUserId)) 
			{
				//검색한 값이 있고, 아이디 작성자가 쿠키 유저인가 확인
				//수정 삭제 버튼을 보여줄지 말지에 대한 판별.
				boardMe = "Y";
			}
		}
		
		model.addAttribute("hiBbsSeq", hiBbsSeq);
		model.addAttribute("searchType", searchType);
		model.addAttribute("searchValue", searchValue);
		model.addAttribute("curPage", curPage);
		//jsp에 값을 찍어줄 용도인 hiBoard객체를 넘겨주고
		model.addAttribute("hiBoard", hiBoard);
		//수정 삭제 버튼이 나타날지 안나타날지를 판별하는 용도인 boardMe도 넘김
		model.addAttribute("boardMe", boardMe);
		
		return "/board/view";
	}

view.jsp를 호출하는 부분을 컨트롤러에 정의해줬다. 여기서 주의깊게 볼 부분은 바로 boardMe인데 이 boardMe는 .jsp에서 쿠키유저와 작성자가 다르면 수정과 삭제 버튼을 안보여주도록 할 용도라고 생각하면 된다.

-view.jsp 사실 뷰 부분은 그냥 주시기만 하고 따로 값을 넣은 것이 없이 하드코딩되어 있었는데 복습시간에 나 혼자 값들을 한번 넣어봤다. 생각보다 어렵지 않게 성공해서 정말 기뻤다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/include/taglib.jsp" %>
<%
   // 개행문자 값을 저장한다.
   pageContext.setAttribute("newLine", "\n");
%>
<!DOCTYPE html>
<html>
<head>
<%@ include file="/WEB-INF/views/include/head.jsp" %>

</head>
<body>

<%@ include file="/WEB-INF/views/include/navigation.jsp" %>
<div class="container">
   <h2>게시물 보기</h2>
   <div class="row" style="margin-right:0; margin-left:0;">
      <table class="table">
         <thead>
            <tr class="table-active">
               <th scope="col" style="width:60%">
                  제목: ${hiBoard.hiBbsTitle}<br/>
                  작성자: ${hiBoard.userName}&nbsp;&nbsp;&nbsp;
                  <a href="mailto:" style="color:#828282;">이메일: ${hiBoard.userEmail}</a>

                  &nbsp;&nbsp;&nbsp;<a href="/board/download?hiBbsSeq=번호" style="color:#000;">[첨부파일]${hiBoard.hiBoardFile.fileOrgName}</a>
                     
               </th>
               <th scope="col" style="width:40%" class="text-right">
                  조회: ${hiBoard.hiBbsReadCnt}<br/>
                  날짜: ${hiBoard.regDate}
               </th>
            </tr>
         </thead>
         <tbody>
            <tr>
               <td colspan="2"><pre>${hiBoard.hiBbsContent}</pre></td>
            </tr>
         </tbody>
         <tfoot>
         <tr>
               <td colspan="2"></td>
           </tr>
         </tfoot>
      </table>
   </div>
   
   <button type="button" id="btnList" class="btn btn-secondary">리스트</button>
   <button type="button" id="btnReply" class="btn btn-secondary">답변</button>
   <c:if test="${boardMe eq 'Y'}">
	   <button type="button" id="btnUpdate" class="btn btn-secondary">수정</button>
	   <button type="button" id="btnDelete" class="btn btn-secondary">삭제</button>
   </c:if>
   <br/>
   <br/>
</div>

<form name="bbsForm" id="bbsForm" method="post">
   <input type="hidden" name="hiBbsSeq" value="" />
   <input type="hidden" name="searchType" value="" />
   <input type="hidden" name="searchValue" value="" />
   <input type="hidden" name="curPage" value="" />
</form>

</body>
</html>

-물론 아직 히든 타입에 값을 넣어주는 것을 안했지만, 내일 수업에 같이 할 것이기 때문에 굳이 하지는 않겠다.

·내일은 우리팀 대면 수업

-내일은 우리팀원들 전부 학원에 출석해서 대면수업을 받는 날이다. 원래 진즉에 팀플 중간 검사를 해주셨어야 하지만, 교수님은 1팀만 많이 신경써주시고 다른 팀에는 시간을 못써주셨다. 아무래도 코로나 때문에 뒷전이 된 것 같은데 뭔가 체계가 안잡혀져서 정말 어려운 것 같다. 처음에만 조금 잡아주신다고 했는데, 뭔가 잊혀진 기분이다. ㅜㅜ

-그래도 오늘 줌으로 유의미한 회의를 진행했고 어느정도 프로젝트 페이지의 메뉴바 구성이 끝났다. 조금 빠르게 내일은 각 페이지에 필요한 DB테이블을 어느정도 그려봤으면 한다. 내일도 파이팅! 참고로 요즘 아침에 더 빨리 학원을 가기 위해서 기상시간을 30분 앞당겼다. 그래서 좀 더 피곤한 느낌이지만, 학원에 다니기로 한 이상 계속 일찍 가려고 한다. 나자신 파이팅!!!

profile
비전공자란 이름으로 새로운 길을 가려 하는 신입

0개의 댓글