[Spring_demo프로젝트] 3. Board(글쓰기, 파일첨부, 글보기)

jngyoon·2023년 10월 18일
0

혼공일기

목록 보기
21/24

#231005 수업 내용 복습

게시판 글쓰기

list.html 중 글쓰기(write) 부분

<!-- 글쓰기 버튼 배치하는 테이블 -->
		<table>
			<tr align="right" valign="middle">
				<td>
                  	<!-- 글쓰기 버튼을 누르면 글쓰기 페이지(write.html)로 이동  -->
					<a class="write" th:href="${'/board/write'+pageMaker.cri.listLink}">글쓰기</a> 
				</td>
			</tr>
		</table>
getListLink() : 페이지 이동시 필요한 pagenum, amount, keyword, type 파라미터를 
				쿼리스트림으로 돌려주는 메소드
public String getListLink() {
		// /board/write?userid=apple 라는 uri를 만들고 싶다면
		// fromPath("/board/write").queryParam("userid","apple")
		//fromPath : ? 앞에 붙는 uri 문자열
		UriComponentsBuilder builder = UriComponentsBuilder.fromPath("") //uri 생성
				.queryParam("pagenum", pagenum)	//queryParam : 파라미터 추가
				.queryParam("amount", amount)
				.queryParam("keyword",keyword)
				.queryParam("type", type);
		return builder.toUriString();	//toUriString : 빌더가 가지고 있는 설정대로 문자열 만들기
	}

BoardController.java 중 write 메소드(GetMapping) 생성

@GetMapping("write")	//a태그는 get 방식
	public void write(@ModelAttribute("cri") Criteria cri,Model model) {
		System.out.println(cri);
	}
	//void로 선언했기 때문에 '/board/wirte.html'을 찾음

/board/write.html(글쓰기 페이지) 생성

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Write</title>
<style>
	<!-- 스타일 생략 -->
</style>
<link rel="stylesheet" th:href="@{/board/css/layout.css}">
</head>
<body>
	<th:block th:replace="~{layout/header::header(${session.loginUser})}"></th:block>
	<div id="wrap">
		<form id="boardForm" method="post" name="boardForm" th:action="@{/board/write}" enctype="multipart/form-data">
          	<!-- 날아온 네개의 파라미터를 받아 놓음 -->
			<input type="hidden" th:value="${cri.pagenum}" name="pagenum">
			<input type="hidden" th:value="${cri.amount}" name="amount">
			<input type="hidden" th:value="${cri.type}" name="type">
			<input type="hidden" th:value="${cri.keyword}" name="keyword">
          	<!-- 글 작성 테이블 -->
			<table style="border-collapse: collapse;" border="1">
				<tr style="height:30px;">
					<th style="text-align:center; width:150px;">제목</th>
					<td>
						<input type="text" name="boardtitle" size="50" maxlength="50" placeholder="제목을 입력하세요">
					</td>
				</tr>
				<tr style="height:30px;">
					<th style="text-align:center; width:150px;">작성자</th>
					<td>
                      	<!-- 로그인유저 작성자에 박아 놓기 -->
						<input type="text" name="userid" size="50" maxlength="50" th:value="${session.loginUser}" readonly>
					</td>
				</tr>
				<tr style="height:300px;">
					<th style="text-align:center; width:150px;">내 용</th>
					<td>
						<textarea name="boardcontents" style="width:700px;height:290px;resize:none;"></textarea>
					</td>
				</tr>
				<tr class="r0 at">
					<th>파일 첨부1</th>
					<td class="file0_cont">
						<div style="float:left;">
							<input type="file" name="files" id="file0" style="display:none">
							<span id="file0name">선택된 파일 없음</span>
						</div>
						<div style="float:right; margin-right: 100px;">
							<a href="javascript:upload('file0')">파일 선택</a>
							<a href="javascript:cancelFile('file0')">첨부 삭제</a>
						</div>
					</td>
				</tr>
			</table>
		</form>
      	<!-- 등록, 목록 버튼 테이블 -->
		<table class="btn_area">
			<tr align="right" valign="middle">
				<td>
					<a href="javascript:sendit()">등록</a> <!-- javascript의 sendit 함수 호출 -->
					<a th:href="${'/board/list'+cri.listLink}">목록</a> <!-- cri.listLink를 붙여 목록으로 돌아가기 -->
				</td>
			</tr>
		</table>
	</div>
	<th:block th:replace="~{layout/footer::footer}"></th:block>
</body>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
	let i = 0;
	function upload(name){
		$("#"+name).click();
	}
	//$(선택자).change(함수) : 해당 선택자의 요소에 변화가 일어난다면 넘겨주는 함수 호출
	$("[type='file']").change(function(e){
		//e : 파일이 업로드된 상황 자체를 담고있는 객체
		//e.target : 파일이 업로드가 된 input[type=file] 객체(태그객체)
		//e.target.files : 파일태그에 업로드를 한 파일 객체들의 배열
		const file = e.target.files[0];
		const fileTag = e.target;
		
		if(file == undefined){
			//파일이 업로드 되었다가 없어진 경우
			cancelFile(fileTag.id);
		}
		else{
			//파일이 없었다가 업로드 한 경우
			//#file0name
			$("#"+fileTag.id+"name").text(file.name);
			//업로드 된 파일의 확장자명
			let ext = file.name.split(".").pop();
			if(ext == 'jpeg' || ext == 'jpg' || ext == 'png' || ext == 'gif' || ext == 'webp'){
				$("."+fileTag.id+"_cont .thumbnail").remove();
				const reader = new FileReader();
				
				reader.onload = function(ie){
					const img = document.createElement("img");
					img.setAttribute("src",ie.target.result)
					img.setAttribute("class","thumbnail");
					document.querySelector("."+fileTag.id+"_cont").appendChild(img);
				}
				reader.readAsDataURL(file);
			}
			else{
				const temp = $("."+fileTag.id+"_cont .thumbnail");
				if(temp != null){
					temp.remove();
				}
			}
			//가장 마지막 파일 선택 버튼을 눌렀을 때
			if(fileTag.id.split("e")[1] == i){
				const cloneElement = $(".r"+i).clone(true);
				i++;
				cloneElement.appendTo("#boardForm tbody")
				const lastElement = $("#boardForm tbody").children().last();
				
				lastElement.attr("class","r"+i+" at");
				lastElement.children("th").text("파일 첨부"+(i+1));
				lastElement.children("td").attr("class","file"+i+"_cont");
				
				lastElement.find("input[type='file']").attr("name","files");
				lastElement.find("input[type='file']").attr("id","file"+i);
				lastElement.find("input[type='file']").val("");
				
				lastElement.find("span").attr("id","file"+i+"name");
				lastElement.find("span").text("선택된 파일 없음");
				
				lastElement.find("a")[0].href = "javascript:upload('file"+i+"')";
				lastElement.find("a")[1].href = "javascript:cancelFile('file"+i+"')"
			}
			
		}
	})

	function cancelFile(name){
		//가장 마지막 첨부 삭제 버튼을 누른 경우
		if(name.split("e")[1] == i){ return; }
		//현재 업로드된 파일이 여러개일 때
		if(i != 0){
			//tr지우기
			let temp = Number(name.split("e")[1]);
			//해당 행 지우기
			$(".r"+temp).remove();
			//지워진 다음 행 부터 숫자 바꿔주기
			for(let j=temp+1;j<=i;j++){
				const el = $("#boardForm tbody").find(".r"+j);
				el.attr("class","r"+(j-1)+" at");
				
				el.children('th').text("파일 첨부"+j);
				
				el.children('td').attr("class","file"+(j-1)+"_cont");
				
				const fileTag = el.find("input[type='file']");
				fileTag.attr("name","file"+(j-1));
				fileTag.attr("id","file"+(j-1));
				
				el.find("span").attr("id","file"+(j-1)+"name");
				
				el.find("a")[0].href = "javascript:upload('file"+(j-1)+"')"
				el.find("a")[1].href = "javascript:cancelFile('file"+(j-1)+"')"
				
			}
			i--;
		}
	}
	
	function sendit(){
		const boardForm = document.boardForm;
		
		const boardtitle = boardForm.boardtitle;
		if(boardtitle.value == ""){
			alert("제목을 입력하세요!");
			boardtitle.focus();
			return false;
		}
		
		const boardcontents = boardForm.boardcontents;
		if(boardcontents.value == ""){
			alert("내용을 입력하세요!");
			boardcontents.focus();
			return false;
		}
		
		boardForm.submit();
	}
</script>
</html>

BoardController.java 중 write 메소드(PostMapping) 생성

@PostMapping("write")
	public String write(BoardDTO board, MultipartFile[] files, Criteria cri) throws Exception{
		Long boardnum = 0l;	//long 타입의 0(0+l)
		if(service.regist(board, files)) {
			boardnum = service.getLastNum(board.getUserid());
			return "redirect:/board/get"+cri.getListLink()+"&boardnum="+boardnum;
		} //성공시 게시글 보는 페이지로 이동(get.html)
		else {
			return "redirect:/board/list"+cri.getListLink();
		} //실패시 게시글 목록 페이지로 이동
	}

BoardServiceImpl.java (service 구현)

package com.kh.demo.service;

//import 생략

@Service
public class BoardServiceImpl implements BoardService{
	@Autowired
	private BoardMapper bmapper;
	@Autowired
	private ReplyMapper rmapper;
	@Autowired
	private FileMapper fmapper;
	@Value("${file.dir}")
	private String saveFolder;
	
    //게시글 등록
	@Override
	public boolean regist(BoardDTO board, MultipartFile[] files) throws Exception {
		int row = bmapper.insertBoard(board);
		if(row != 1) {			//등록실패
			return false;
		}
		if(files == null || files.length == 0) {		//파일첨부 안 한 경우 => 바로 등록
			return true;
		}
        //파일첨부 한 경우
		else {
			//방금 등록한 게시글 번호
			Long boardnum = bmapper.getLastNum(board.getUserid());
			boolean flag = false;
			for(int i=0;i<files.length-1;i++) {
				MultipartFile file = files[i];
				//apple.png
				String orgname = file.getOriginalFilename(); //업로드시 파일 이름
				//5
				int lastIdx = orgname.lastIndexOf(".");
				//.png
				String extension = orgname.substring(lastIdx); //확장자 잘라내기
				
				LocalDateTime now = LocalDateTime.now();
				String time = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));	//현재시간 포매팅

				//랜덤파일명 만들기(20231005103911237랜덤문자열.png)
				String systemname = time+UUID.randomUUID().toString()+extension;
				System.out.println(systemname);

				//실제 저장될 파일의 경로
				String path = saveFolder+systemname;
				
				FileDTO fdto = new FileDTO();
				fdto.setBoardnum(boardnum);
				fdto.setSystemname(systemname);
				fdto.setOrgname(orgname);
				
				//실제 파일 업로드
				file.transferTo(new File(path)); 
                //transferTo : 지정한 패스대로 파일을 실제 경로에 써주는 메소드
				
                //DB에 저장
				flag = fmapper.insertFile(fdto) == 1;
				
				if(!flag) {
					//업로드 했던 파일 삭제, 게시글 데이터 삭제(생략)
					return flag;
				}
			}
		}
		return true;
	}
	//게시글 등록 이외 생략
	
}

FileMapper.java 인터페이스 생성

package com.kh.demo.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.kh.demo.domain.dto.FileDTO;

@Mapper
public interface FileMapper {
	int insertFile(FileDTO file);
	
	List<FileDTO> getFiles(Long boardnum); //파일 목록보여주는거
	
	int deleteBySystemname(String systemname);
	
	int deleteByBoardnum(Long boardnum);
}

BoardMapper.xml 중 게시글 등록 부분

<insert id="insertBoard">
	insert into t_board (boardtitle,boardcontents,userid)
	values(#{boardtitle},#{boardcontents},#{userid})
</insert>
<select id="getLastNum">
	select max(boardnum) from t_board where userid=#{userid}
</select>

FileMapper.xml 생성

<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kh.demo.mapper.FileMapper">
	<insert id="insertFile">
		insert into t_file values(#{systemname},#{orgname},#{boardnum})
	</insert>
</mapper>

게시판 글 보기

/board/get.html 생성

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Get</title>
<style>
	<!-- 스타일 생략 -->
</style>
<link rel="stylesheet" th:href="@{/board/css/layout.css}">
</head>
<body>
	<th:block th:replace="~{layout/header::header(${session.loginUser})}"></th:block>
	<div id="wrap">
		<form>
          	<!-- 게시글 테이블 -->
			<table style="border-collapse: collapse;" border="1" class="board_area">
				<tr style="height:30px;">
					<th style="text-align:center; width:150px;">제목</th>
					<td>
						<input type="text" name="boardtitle" size="50" maxlength="50" th:value="${board.boardtitle}" readonly>
					</td>
				</tr>
				<tr style="height:30px;">
					<th style="text-align:center; width:150px;">작성자</th>
					<td>
						<input type="text" name="userid" size="50" maxlength="50" th:value="${board.userid}" readonly>
					</td>
				</tr>
				<tr>
					<th>조회수</th>
					<td>[[${board.readcount}]]</td>
				</tr>
				<tr style="height:300px;">
					<th style="text-align:center; width:150px;">내 용</th>
					<td>
						<textarea name="boardcontents" style="width:700px;height:290px;resize:none;" readonly>[[${board.boardcontents}]]</textarea>
					</td>
				</tr>
              	<!-- 파일 갯수에 따라 반복문 -->
				<th:block th:if="${files != null and files.size() > 0}" th:each="file : ${files}">
                  	<!-- th:with = 타임리프 내에서 사용가능한 어떤 변수가 설정된 구간-->
					<th:block th:with="sar=${file.orgname.split('[.]')}"> 
                    <!-- .은 정규식이어서 대괄호 []로 감싸야 문자 . 으로 사용 가능 -->
						<tr>
							<th>첨부파일[[${fileStat.index+1}]]</th>
							<td>
								<a th:href="@{/board/file (systemname=${file.systemname},orgname=${file.orgname})}">[[${file.orgname}]]</a>
							</td>
						</tr>
                      	<!-- ext : 확장자 변수 -->
						<th:block th:with="ext=${sar[sar.length-1]}">
							<tr th:if="${ext == 'jpg' or ext == 'jpeg' or ext == 'png' or ext == 'gif' or ext == 'webp'}">
								<td></td>
								<td>
                                  	<!-- 썸네일 -->
									<img style="width:100%;" th:src="@{/board/thumbnail (systemname=${file.systemname})}">
								</td>
							</tr>
						</th:block>
					</th:block>
				</th:block>
				<th:block th:unless="${files != null and files.size() > 0}">
					<tr>
						<td colspan="2" style="text-align: center; font-size: 20px;">첨부 파일이 없습니다.</td>
					</tr>
				</th:block>
			</table>
		</form>
      	<!-- 수정, 삭제 버튼 테이블 -->
		<table class="btn_area">
			<tr align="right" valign="middle">
				<td>
					<th:block th:if="${board.userid == session.loginUser}">
						<form name="boardForm" method="post" th:action="@{/board/remove}">
							<input name="boardnum" th:value="${board.boardnum}" type="hidden">
							<input name="pagenum" th:value="${cri.pagenum}" type="hidden">
							<input name="amount" th:value="${cri.amount}" type="hidden">
							<input name="type" th:value="${cri.type}" type="hidden">
							<input name="keyword" th:value="${cri.keyword}" type="hidden">
							<a href="javascript:modify()">수정</a>
							<a href="javascript:document.boardForm.submit()">삭제</a>
						</form>
					</th:block>
					<a th:href="${'/board/list'+cri.listLink}">목록</a>
				</td>
			</tr>
		</table>
    	<!-- 댓글 div -->
		<div class="reply_line">
			<a href="#" class="regist">댓글 등록</a>
			<div class="replyForm row">
				<div style="width:20%">
					<h4>작성자</h4>
					<input type="text" name="userid" th:value="${session.loginUser}" readonly style="text-align: center;">
				</div>
				<div style="width:65%">
					<h4>내 용</h4>
					<textarea name="replycontents" placeholder="Contents" style="resize:none;"></textarea>
				</div>
				<div style="width:15%">
					<a href="#" class="button finish" style="margin-bottom:1rem;">등록</a>
					<a href="#" class="button cancel">취소</a>
				</div>
			</div>
			<ul class="replies"></ul>
			<div class="page"></div>
		</div>
	</div>
	<th:block th:replace="~{layout/footer::footer}"></th:block>
</body>
<script th:src="@{/board/js/reply.js}"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script th:inline="javascript">
	const loginUser = /*[[${session.loginUser}]]*/'';
	const boardnum = /*[[${board.boardnum}]]*/'';
	const replies = $(".replies")
	const page = $(".page")
	let pagenum = 0;
	
	
	$(document).ready(function(){
		$(".replyForm").hide();
		pagenum = 1;
		
	})
	$(".regist").on("click",function(e){
		e.preventDefault();
		$(".replyForm").show();
		$(this).hide();
	})
	$(".finish").on("click",function(e){
		e.preventDefault();
		let replycontents = $("[name='replycontents']").val();
		
		replyService.add(
			{"boardnum":boardnum,"userid":loginUser, "replycontents":replycontents},
			function(result){
				alert("등록!");
				
			}
		)
		
		
	})
	
	function showList(pagenum){
		replyService.getList(
			{boardnum:boardnum, pagenum:pagenum||1},
			function(replyCnt, list){
				let str = "";
				if(list == null || list.length == 0){
					str+= '<li class="noreply" style="clear:both;">등록된 댓글이 없습니다.</li>';
					replies.html(str);
					return;
				}
				for(let i=0;i<list.length;i++){
					//<li style="clear:both;" class="li3">
					str += '<li style="clear:both;" class="li'+list[i].replynum+'">';
					str += '<div style="display:inline; float:left; width:80%;">';
					//<strong class="userid3">apple</strong>
					str += '<strong class="userid'+list[i].replynum+'">'+list[i].userid+'</strong>';
					//<p class="reply3">댓글내용</p>
					str += '<p class="reply'+list[i].replynum+'">'+list[i].replycontents+'</p>';
					str += '</div><div style="text-align:right;">';
					str += '<strong>'+replyService.displayTime(list[i])+'</strong>'
					if(list[i].userid){
						
					}
				}
			}
		)
	}
	
	function showReplyPage(replyCnt, pagenum){
		let endPage = Math.ceil(pagenum/5)*5;
		let startPage = endPage - 4;
		
		let prev = startPage != 1;
		endPage = (endPage-1)*5 >= replyCnt ? Math.ceil(replyCnt/5) : endPage;
		let next = endPage*5 < replyCnt ? true : false;
		
		let str = "";
		if(prev){
			//<a class="changePage" href="5"><code>&lt;</code></a>
			str += '<a class="changePage" href="'+(startPage-1)+'"><code>&lt;</code></a>';
		}
		for(let i=startPage;i<endPage;i++){
			if(i == pagenum){
				//<code class="nowPage">7</code>
				str += '<code class="nowPage">'+i+'</code>';
			}
			else{
				//<a class="changePage" href="9"><code>9</code></a>
				str += '<a class="changePage" href="'+i+'"><code>'+i+'</code></a>';
			}
		}
		if(next){
			str += '<a class="changePage" href="'+(endPage-1)+'"><code>&gt;</code></a>';
		}
		
		page.html(str);
		
		$(".changePage").on("click")
	}
	
	function modify(){
		const boardForm = document.boardForm;
		boardForm.setAttribute("action",/*[[@{/board/modify}]]*/'');
		boardForm.setAttribute("method","get");
		boardForm.submit();
	}
</script>
</html>

list.html 중 글보기(get) 부분

<!-- 게시글 리스트 띄우는 테이블 -->
		<table class="list">
			<tr align="right" valign="middle">
				<td colspan="6">글 개수 : [[${pageMaker.total}]]</td>
			</tr>
			<tr align="center" valign="middle">
				<th width="8%">번호</th>
				<th></th>
				<th>제목</th>
				<th width="15%">작성자</th>
				<th width="17%">날짜</th>
				<th width="10%">조회수</th>
			</tr>
			<tr th:if="${list != null and list.size()>0}" th:each="board : ${list}">
				<td>[[${board.boardnum}]]</td>
				<td>
					<sup class="hot" th:if="${recent_reply[boardStat.index] == 'O'}">Hot</sup>
					<sup class="new" th:if="${newly_board[boardStat.index] == 'O'}">New</sup>
				</td>
				<td>
                  	<!-- 게시글은 글 제목이 있는 a태그 부분을 클릭하면 보여짐 -->
					<a class="get" th:href="${board.boardnum}"> 
						[[${board.boardtitle}]]
						<span class="reply_cnt" th:text="'['+${reply_cnt_list[boardStat.index]}+']'"></span>
					</a>
				</td>
				<td>[[${board.userid}]]</td>
				<td>
					[[${board.regdate}]]
					<th:block th:if="${board.regdate != board.updatedate}">
					(수정됨)
					</th:block>
				</td>
				<td>[[${board.readcount}]]</td>
			</tr>
			<th:block th:if="${list == null or list.size() == 0}">
				<tr>
					<td colspan="6" style="text-align: center; font-size: 20px;">등록된
						게시글이 없습니다.</td>
				</tr>
			</th:block>
		</table>

	<!-- 이하 생략 -->
<!-- get부분 javascript -->
<script th:inline="javascript">
  
	$(".get").on("click",function(e){
		e.preventDefault();
		let boardnum = $(this).attr("href");
		let url=/*[[@{/board/get}]]*/'';
		pageForm.append("<input type='hidden' name='boardnum' value='"+boardnum+"'>")
		pageForm.attr("action",url);
		pageForm.attr("method","get");
		pageForm.submit();
	})
  
</script>

BoardController.java 중 get 메소드(GetMapping) 생성

@GetMapping(value = {"get","modify"})
	public String get(Criteria cri, Long boardnum, HttpServletRequest req, HttpServletResponse resp, Model model) {
		model.addAttribute("cri",cri);	//Criteria 추가
		HttpSession session = req.getSession();	//session 받아오기
		BoardDTO board = service.getDetail(boardnum);	//클릭한 boardnum에 해당하는 상세정보 board 객체에 담기
		model.addAttribute("board",board);	//board에 board 객체 추가
		model.addAttribute("files",service.getFileList(boardnum));	//files 추가
		String loginUser = (String)session.getAttribute("loginUser");	//현재 로그인유저 담기
		String requestURI = req.getRequestURI();
		if(requestURI.contains("/get")) {
			//게시글의 작성자가 로그인된 유저가 아닐 때 => 게시글 조회수 1 증가(cookie가 없을때만)
			if(!board.getUserid().equals(loginUser)) {
				//쿠키 검사
				Cookie[] cookies = req.getCookies();
				Cookie read_board = null;
				if(cookies != null) {
					for(Cookie cookie : cookies) {
						//ex) 1번 게시글을 조회하고자 클릭했을 때에는 "read_board1" 쿠키를 찾음
						//cookie의 이름이 read_board+boardnum이라면
                        if(cookie.getName().equals("read_board"+boardnum)) {
							read_board = cookie;
							break; //cookie가 있으면 조회수 안올릴거니까 break
						}
					}
				}
				//read_board가 null이라는 뜻은 위에서 쿠키를 찾았을 때 존재하지 않았다는 뜻
				//첫 조회거나 조회한지 1시간이 지난 후(cookie가 없는 경우)
				if(read_board == null) {
					//조회수 증가
					service.updateReadCount(boardnum);
					//read_board1 이름의 쿠키(유효기간 : 3600초)를 생성해서 클라이언트 컴퓨터에 저장
					Cookie cookie = new Cookie("read_board"+boardnum, "r");
					cookie.setMaxAge(3600);
					resp.addCookie(cookie);
				}
			}
		}
		return requestURI;
	}

@GetMapping("thumbnail")
	public ResponseEntity<Resource> thumbnail(String systemname) throws Exception{	
		return service.getThumbnailResource(systemname);
	}
//ResponseEntity<Resource> : 응답으로 특정한 데이터를 보낼건데 그 데이터는Resource 타입이고, Resource라는 타입은 어떤 파일을 자원화시킨 타입 => 특정 파일을 자원화시켜 바디에 담아서 응답으로 보내는 메소드

BoardServiceImpl.java 중 관련 서비스 구현

@Override
	public void updateReadCount(Long boardnum) {
		bmapper.updateReadCount(boardnum);
	}
    
@Override
	public BoardDTO getDetail(Long boardnum) {
		return bmapper.findByNum(boardnum);
	}  
    
@Override
	public List<FileDTO> getFileList(Long boardnum) {
		return fmapper.getFiles(boardnum);
	}   
    
@Override
	public ResponseEntity<Resource> getThumbnailResource(String systemname) throws Exception{
		//경로에 관련된 객체(자원으로 가지고 와야 하는 파일에 대한 경로)
		Path path = Paths.get(saveFolder+systemname);
		//경로에 있는 파일의 MIME타입을 조사해서 그대로 담기
		String contentType = Files.probeContentType(path);
		//응답 헤더 생성
		HttpHeaders headers = new HttpHeaders();
		headers.add(HttpHeaders.CONTENT_TYPE, contentType);
		
		//해당 경로(path)에 있는 파일에서부터 뻗어나오는 InputStream(Files.newInputStream)을 통해 자원화(InputStreamResource)
		Resource resource = new InputStreamResource(Files.newInputStream(path));
		return new ResponseEntity<>(resource,headers,HttpStatus.OK);
	}

BoardMapper.xml에 관련 쿼리문 작성

<update id="updateReadCount">
	update t_board set readcount = readcount+1 where boardnum = #{boardnum}
</update>
<select id="findByNum">
	select * from t_board where boardnum=#{boardnum}
</select>

FileMapper.xml에 관련 쿼리문 작성

<select id="getFiles">
	select * from t_file where boardnum=#{boardnum}
</select>

0개의 댓글