목차
-
static/css =>common.css
-
BoardMapper.xml
-
BoardServiceImpl
-
BoardController
-
ch12에 있던 pagingUtil.java 그대로 가져와서 같은 위치에 사용
-
그 후 BoardController 재수정
-
-
boardList.jsp
-
BoardMapper.java
-
BoardServiceImpl
-
BoardController.java
-
board=>boardView.jsp
-
tile-def => board.xml
-
memberController
-
BoardController
-
BoardMapper.java
-
BoardServiceImpl
-
BoardAjaxController 생성
-
-
BoardController
-
board.xml
-
boardModify.jsp
-
BoardMapper.xml
-
BoardServiceImpl
-
BoardController
static/css =>common.css
/* 공통 테이블
---------------------*/
table.basic-table{
width:100%;
border:1px solid #000;
border-collapse:collapse;
margin-top:5px;
}
table.basic-table td, table.basic-table th{
border:1px solid #000;
padding:5px;
}
table.striped-table{
width:100%;
border:1px solid #FFF;
border-collapse:collapse;
font-size:15px;
margin:7px 0;
}
table.striped-table td, table.striped-table th{
padding:.7em .5em; /* 0.7 0.5인데 생략가능 */
vertical-align:middle;
}
table.striped-table th{
font-weight:bold;
background:#E1E1E1;
}
table.striped-table td{
border-bottom:1px solid rgba(0,0,0.1);
}
table.striped-table tr:nth-child(odd){
background-color:rgb(250,250,247);
}
BoardMapper.xml
<!-- sql 태그와 include 태그를 이용해서 SQL문을 재사용 -->
<sql id="boardSearch"> <!-- 검색할 떄 -->
<where>
<if test="category != null and category != ''"> <!-- 카테고리가 있을 때 where절과 카테고리값 생성 -->
category = #{category}
</if>
<if test="keyword !=null and keyword !=''">
And
</if>
<if test="keyfield ==1">
title LIKE '%' || #{keyword} || '%'
</if>
<if test="keyfield ==2">
(id LIKE '%' || #{keyword} || '%' OR
nick_name LIKE '%' || #{keyword} || '%')
</if>
<if test="keyfield ==3">
content LIKE '%' || #{keyword} || '%'
</if>
<if test="keyfield ==4">
(title LIKE '%' || #{keyword} || '%' OR
content LIKE '%' || #{keyword} || '%')
</if>
</where>
</sql>
<sql id="boardOrder"> <!-- 정렬할 때 -->
<if test="order ==1">
ORDER BY board_num DESC
</if>
<if test="order ==2">
ORDER BY hit DESC
</if>
<if test="order ==3">
ORDER BY fav_cnt DESC NULLS LAST
</if>
<if test="order ==4">
ORDER BY re_cnt DESC NULLS LAST
</if>
</sql>
<!-- 게시판 글 총레코드 수/검색 레코드 수 -->
<select id="selectRowCount" parameterType="map" resultType="integer">
SELECT
COUNT(*)
FROM spboard JOIN spmember USING (mem_num)
<include refid="boardSearch"></include>
</select>
<!-- 게시판 전체 목록/검색 목록 -->
<select id="selectList" parameterType="map" resultType="boardVO">
SELECT
*
FROM (SELECT
a.*,
rownum rnum
FROM (SELECT
*
FROM spboard JOIN spmember USING(mem_num)
<include refid="boardSearch"></include>
<include refid="boardOrder"></include>
)a)
<![CDATA[
WHERE rnum >= #{start} AND rnum <= #{end}
]]>
</select>
BoardServiceImpl
@Override
public List<BoardVO> selectList(Map<String, Object> map) {
return boardMapper.selectList(map);
}
@Override
public Integer selectRowCount(Map<String, Object> map) {
return boardMapper.selectRowCount(map);
}
BoardController
Map<String,Object> map = new HashMap<String,Object>();
map.put("category",category);
map.put("keyfield",keyfield);
map.put("keyword",keyword);
//전체,검색 레코드 수
int count = boardService.selectRowCount(map);
ch12에 있던 pagingUtil.java 그대로 가져와서 같은 위치에 사용
그 후 BoardController 재수정
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.min.js"></script>
//페이지 처리
PagingUtil page =
new PagingUtil(keyfield,keyword, pageNum,
count,20,10,"list",
"&category="+category+"&order="+order);
List<BoardVO> list = null;
if(count >0) {
map.put("order",order);
map.put("start",page.getStartRow());
map.put("end",page.getEndRow());
list = boardService.selectList(map);
}
model.addAttribute("count",count);
model.addAttribute("list",list);
model.addAttribute("page",page.getPage());
boardList.jsp
<div>
<a href="list">전체</a> |
<a href="list?category=1">자바</a> |
<a href="list?category=2">데이터베이스</a> |
<a href="list?category=3">자바스크립트</a> |
<a href="list?category=4">기타</a>
</div>
<form action="list" id="search_form" method="get">
<input type="hidden" name="category" value="${param.category}">
<ul class="search">
<li>
<select name="keyfield" id="keyfield">
<option value="1"<c:if test="${param.keyfield==1}">selected</c:if>>제목</option>
<option value="2"<c:if test="${param.keyfield==2}">selected</c:if>>ID+별명</option>
<option value="3"<c:if test="${param.keyfield==3}">selected</c:if>>내용</option>
<option value="4"<c:if test="${param.keyfield==4}">selected</c:if>>제목+내용</option>
</select>
</li>
<li>
<input type="search" name="keyword" id="keyword" value="${param.keyword}">
</li>
<li>
<input type="submit" value="찾기">
</li>
</ul>
<div class="align-right">
<select id="order" name="order">
<option value="1"<c:if test="${param.order==1}">selected</c:if>>최신순</option>
<option value="2"<c:if test="${param.order==2}">selected</c:if>>조회수</option>
<option value="3"<c:if test="${param.order==3}">selected</c:if>>좋아요</option>
<option value="4"<c:if test="${param.order==4}">selected</c:if>>댓글수</option>
</select>
<script type="text/javascript">
$('#order').change(function(){
location.href='list?category=${param.category}&keyfield='
+$('#keyfield').val()
+'&keyword='+$('#keyword').val()
+'&order='+$('#oredr').val();
});
</script>
<c:if test="${!empty user}">
<input type="button" value="글쓰기" onclick="location.href='write'">
</c:if>
</div>
</form>
<c:if test="${count ==0}">
<div class="result-display">표시할 게시물이 없습니다.</div>
</c:if>
<c:if test="${count>0}">
<table class="striped-table">
<tr>
<th>번호</th>
<th width="400">제목</th>
<th>작성자</th>
<th>작성일</th>
<th>조회수</th>
<th>좋아요수</th>
</tr>
<c:forEach var="board" items="${list}">
<tr>
<td class="align-center">${board.board_num}</td>
<td class="align-left"><a href="detail?board_num=${board.board_num}">${board.title}(${board.re_cnt})</a></td>
<td class="align-center">
<c:if test="${empty board.nick_name}">${board.id}</c:if> <!-- 닉네임이 없으면 아이디를 보여준다 -->
<c:if test="${!empty board.nick_name}">${board.nick_name}</c:if>
</td>
<td class="align-center">${board.reg_date}</td>
<td class="align-center">${board.hit}</td>
<td class="align-center">${board.fav_cnt}</td>
</tr>
</c:forEach>
</table>
<div class="align-center">${page}</div>
</c:if>
</div>




BoardMapper.java
@Select("SELECT * FROM spboard JOIN spmember USING (mem_num) LEFT OUTER JOIN spmember_detail USING(mem_num) WHERE board_num=#{board_num}") //LEFT OUTER를 하는 이유는 탈퇴했을 때 에러나는 것을 방지하기 위해
public BoardVO selectBoard(Long board_num);
@Update("UPDATE spboard SET hit=hit+1 WHERE board_num=#{board_num}")
public void updateHit(Long board_num);
BoardServiceImpl
@Override
public BoardVO selectBoard(Long board_num) {
return boardMapper.selectBoard(board_num);
}
@Override
public void updateHit(Long board_num) {
boardMapper.updateHit(board_num);
}
BoardController.java
StringUtil.java
0.00MB
이 파일의 클래스를 사용하기위해 다운
/*=======================
* 게시판 글상세
*=======================*/
@GetMapping("/board/detail")
public ModelAndView process(long board_num) {
log.debug("<<게시판 글 상세 - board_num>> :"+board_num);
//해당 글의 조회수 증가
boardService.updateHit(board_num);
BoardVO board = boardService.selectBoard(board_num);
//제목에 태그를 허용하지 않음
board.setTitle(StringUtil.useNoHTML(board.getTitle()));
//내용에 태그를 허용하지 않으면서 줄바꿈 처리
board.setContent(StringUtil.useBrNoHTML(board.getContent()));
return new ModelAndView("boardView","board",board);
}
board=>boardView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!-- 게시판 글 상세 시작 -->
<div class="page-main">
<h2>${board.title}</h2>
<ul class="detail-info">
<li>
<img src="${pageContext.request.contextPath}/member/viewProfile?mem_num=${board.mem_num}" width="40" height="40" class="my-photo">
</li>
<li>
<c:if test="${empty board.nick_name}">${board.id}</c:if>
<c:if test="${!empty board.nick_name}">${board.nick_name}</c:if>
<br>
<c:if test="${empty board_modify_date}">
작성일: ${board.reg_date}
</c:if>
<c:if test="${!empty board_modify_date}">
최근 수정일: ${board.modify_date}
</c:if>
조회 : ${board.hit}
</li>
</ul>
<c:if test="${!empty board.filename}">
<ul>
<li>첨부 파일 : <a href="file?board_num=${board.board_num}">${board.filename}</a></li>
</ul>
</c:if>
<div class="detail-content">
${board.content}
</div>
<div>
<%-- 좋아요 --%>
<%-- 댓글수 --%>
</div>
<hr size="1" width="100%">
<div class="align-right">
<c:if test="${!empty user && user.mem_num == board.mem_num}">
<input type="button" value="수정" onclick="location.href='update?board_num=${board.board_num}'">
<input type="button" value="삭제" id="delete_btn">
<script>
const delete_btn = document.getElementById('delete_btn');
delete_btn.onclick=function(){
const choice = confirm('삭제하시겠습니까?');
if (choice){
location.replace('delete?board_num=${board.board_num}');
}
};
</script>
</c:if>
<input type="button" value="목록" onclick="location.href='list'">
</div>
<hr size="1" width="100%">
<!-- 댓글 UI 시작 -->
<!-- 댓글 목록 출력 -->
<!-- 댓글 UI 끝 -->
</div>
<!-- 게시판 글 상세 끝 -->
tile-def => board.xml
<definition name="boardView" extends="main">
<put-attribute name="title" value="글상세"/>
<put-attribute name="css" value="/WEB-INF/views/board/boardCSS.jsp"/>
<put-attribute name="body" value="/WEB-INF/views/board/boardView.jsp"/>
</definition>


memberController
프로필 설정
//프로필 사진 출력(회원번호 지정)
@GetMapping("/member/viewProfile")
public String getProfileByMem_num(long mem_num,
HttpServletRequest request,
Model model) {
MemberVO memberVO = memberService.selectMember(mem_num);
viewProfile(memberVO,request,model);
return "imageView";
}

BoardController
첨부파일 다운로드하기
DownloadView.java
0.00MB
kr.spring.view에 넣기
//파일 다운로드
@GetMapping("/board/file")
public String download(long board_num, HttpServletRequest request, Model model) {
BoardVO board = boardService.selectBoard(board_num);
byte[] downloadFile = FileUtil.getbytes(request.getServletContext()
.getRealPath("/upload")+"/"+board.getFilename());
model.addAttribute("downloadFile",downloadFile);
model.addAttribute("filename",board.getFilename());
return "downloadView";
}


BoardMapper.java
파일삭제 하기위해
@Update("UPDATE spboard SET filename='' WHERE board_num=#{board_num}")
public void deleteFile(Long board_num);
BoardServiceImpl
@Override
public void deleteFile(Long board_num) {
boardMapper.deleteFile(board_num);
}
BoardAjaxController 생성
package kr.spring.board.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.spring.board.service.BoardService;
import kr.spring.board.vo.BoardVO;
import kr.spring.member.vo.MemberVO;
import kr.spring.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class BoardAjaxController {
@Autowired
private BoardService boardService;
/*========================
* 부모글
*========================*/
//업로드 파일 삭제
@PostMapping("/board/deleteFile")
@ResponseBody
public Map<String,String> processFile(long board_num, HttpSession session, HttpServletRequest request){
Map<String,String> mapJson = new HashMap<String, String>();
MemberVO user = (MemberVO)session.getAttribute("user");
if(user==null) {
mapJson.put("result","logout");
}else {
BoardVO db_board = boardService.selectBoard(board_num);
//로그인한 회원번호와 작성자 회원번호 일치 여부 체크
if(user.getMem_num() != db_board.getMem_num()) {
//불일치
mapJson.put("result","wrongAccess");
}else {
//일치
boardService.deleteFile(board_num);
FileUtil.removeFile(request,db_board.getFilename());
mapJson.put("result","success");
}
}
return mapJson;
}
}
BoardController
/*=======================
* 게시판 글 수정
*=======================*/
//수정 폼 호출
@GetMapping("/board/update")
public String formUpdate(long board_num, Model model) {
BoardVO boardVO = boardService.selectBoard(board_num);
model.addAttribute("boardVO",boardVO);
return "boardModify";
}
board.xml
<definition name="boardModify" extends="main">
<put-attribute name="title" value="글수정"/>
<put-attribute name="css" value="/WEB-INF/views/board/boardCSS.jsp"/>
<put-attribute name="body" value="/WEB-INF/views/board/boardModify.jsp"/>
</definition>
boardModify.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.min.js"></script>
<!-- 게시판 글수정 시작 -->
<div class="page-main">
<h2>글쓰기</h2>
<form:form action="update" id="board_modify"
enctype="multipart/form-data"
modelAttribute="boardVO">
<form:hidden path="board_num"/>
<ul>
<li>
<form:label path="category">분류</form:label>
<form:select path="category"> <!-- 기존에 지정해둔 value값으로 자동으로 지정되어있음 -->
<form:option value="1">자바</form:option>
<form:option value="2">데이터베이스</form:option>
<form:option value="3">자바스크립드</form:option>
<form:option value="4">기타</form:option>
</form:select>
<form:errors path="category" cssClass="error-color"/>
</li>
<li>
<form:label path="title">제목</form:label>
<form:input path="title"/>
<form:errors path="title" cssClass="error-color"/>
</li>
<li>
<form:label path="content">내용</form:label>
<form:textarea path="content"/>
<form:errors path="content" cssClass="error-color"/>
</li>
<li>
<form:label path="upload">파일 업로드</form:label>
<input type="file" name="upload" id="upload">
<c:if test="${!empty boardVO.filename}">
<div id="file_detail">
(${boardVO.filename})파일이 등록되어 있습니다.
<input type="button" value="파일 삭제" id="file_del">
</div>
<script type="text/javascript">
$(function(){
$('#file_del').click(function(){
const choice = confirm('삭제하시겠습니까?');
if(choice){
$.ajax({
url:'deleteFile',
data:{board_num:${boardVO.board_num}},
type:'post',
dataType:'json',
success:function(param){
if(param.result=='logout'){
alert('로그인 후 사용하세요');
}else if(param.result == 'wrongAccess'){
alert('잘못된 접속입니다');
}else if(param.result == 'success'){
$('#file_detail').hide();
}else{
alert('파일 삭제 오류 발생');
}
},
error:function(){
alert('네트워크 오류 발생');
}
});
}
});
});
</script>
</c:if>
</li>
</ul>
<div class="align-center">
<form:button class="default-btn">전송</form:button>
<input type="button" value="목록"
class="default-btn"
onclick="location.href='list'">
</div>
</form:form>
</div>
<!-- 게시판 글수정 끝 -->


BoardMapper.xml
로 SQL 작성
-- 글 수정 부분
<!-- 게시판 글수정 -->
<update id="updateBoard" parameterType="boardVO">
UPDATE spboard SET
<if test="filename != null">
filename = #{filename},
</if>
title = #{title},
content = #{content},
ip = #{ip},
modify_date = SYSDATE
WHERE board_num = #{board_num}
</update>
BoardServiceImpl
@Override
public void updateBoard(BoardVO board) {
boardMapper.updateBoard(board);
}
BoardController
//수정 폼에서 전송된 데이터 처리
@PostMapping("/board/update")
public String submitUpdate(@Valid BoardVO boardVO, //Valid 다음에는 바로 BindingResult가 나와야된다. 사이에 다른 값을 넣으면 에러남
BindingResult result,
Model model,
HttpServletRequest request) throws IllegalStateException, IOException {
log.debug("<<게시판 글 수정>> : "+boardVO);
//유효성 체크 결과 오류가 있으면 폼 호출
if(result.hasErrors()) {
//title 또는 content가 입력되지 않아서 유효성 체크에 걸리면
//파일 정보를 잃어버리기 때문에 폼을 호출할 때 다시 파일 정보를 세팅해야 함.
BoardVO vo = boardService.selectBoard(boardVO.getBoard_num());
boardVO.setFilename(vo.getFilename());
return "boardModify";
}
//오류가 나지 않았을 때
//DB에 저장된 파일 정보 구하기
BoardVO db_board = boardService.selectBoard(boardVO.getBoard_num());
//파일명 세팅(FileUtil.createFile에서 파일이 없으면 null 처리함)
boardVO.setFilename(FileUtil.createFile(request,boardVO.getUpload()));
return "common/resultAlert";
}
'쌍용교육(JAVA) > SpringBoot' 카테고리의 다른 글
쌍용교육 -JSP수업 97일차 ch15SpringPage(8) (0) | 2024.07.04 |
---|---|
쌍용교육 -JSP수업 96일차 ch15SpringPage(7) (0) | 2024.07.03 |
쌍용교육 -JSP수업 93일차 ch15SpringPage(4) (0) | 2024.06.28 |
쌍용교육 -JSP수업 92일차 ch15SpringPage(3) (1) | 2024.06.27 |
쌍용교육 -JSP수업 91일차 ch15SpringPage(2) (0) | 2024.06.26 |
static/css =>common.css
/* 공통 테이블
---------------------*/
table.basic-table{
width:100%;
border:1px solid #000;
border-collapse:collapse;
margin-top:5px;
}
table.basic-table td, table.basic-table th{
border:1px solid #000;
padding:5px;
}
table.striped-table{
width:100%;
border:1px solid #FFF;
border-collapse:collapse;
font-size:15px;
margin:7px 0;
}
table.striped-table td, table.striped-table th{
padding:.7em .5em; /* 0.7 0.5인데 생략가능 */
vertical-align:middle;
}
table.striped-table th{
font-weight:bold;
background:#E1E1E1;
}
table.striped-table td{
border-bottom:1px solid rgba(0,0,0.1);
}
table.striped-table tr:nth-child(odd){
background-color:rgb(250,250,247);
}
BoardMapper.xml
<!-- sql 태그와 include 태그를 이용해서 SQL문을 재사용 -->
<sql id="boardSearch"> <!-- 검색할 떄 -->
<where>
<if test="category != null and category != ''"> <!-- 카테고리가 있을 때 where절과 카테고리값 생성 -->
category = #{category}
</if>
<if test="keyword !=null and keyword !=''">
And
</if>
<if test="keyfield ==1">
title LIKE '%' || #{keyword} || '%'
</if>
<if test="keyfield ==2">
(id LIKE '%' || #{keyword} || '%' OR
nick_name LIKE '%' || #{keyword} || '%')
</if>
<if test="keyfield ==3">
content LIKE '%' || #{keyword} || '%'
</if>
<if test="keyfield ==4">
(title LIKE '%' || #{keyword} || '%' OR
content LIKE '%' || #{keyword} || '%')
</if>
</where>
</sql>
<sql id="boardOrder"> <!-- 정렬할 때 -->
<if test="order ==1">
ORDER BY board_num DESC
</if>
<if test="order ==2">
ORDER BY hit DESC
</if>
<if test="order ==3">
ORDER BY fav_cnt DESC NULLS LAST
</if>
<if test="order ==4">
ORDER BY re_cnt DESC NULLS LAST
</if>
</sql>
<!-- 게시판 글 총레코드 수/검색 레코드 수 -->
<select id="selectRowCount" parameterType="map" resultType="integer">
SELECT
COUNT(*)
FROM spboard JOIN spmember USING (mem_num)
<include refid="boardSearch"></include>
</select>
<!-- 게시판 전체 목록/검색 목록 -->
<select id="selectList" parameterType="map" resultType="boardVO">
SELECT
*
FROM (SELECT
a.*,
rownum rnum
FROM (SELECT
*
FROM spboard JOIN spmember USING(mem_num)
<include refid="boardSearch"></include>
<include refid="boardOrder"></include>
)a)
<![CDATA[
WHERE rnum >= #{start} AND rnum <= #{end}
]]>
</select>
BoardServiceImpl
@Override
public List<BoardVO> selectList(Map<String, Object> map) {
return boardMapper.selectList(map);
}
@Override
public Integer selectRowCount(Map<String, Object> map) {
return boardMapper.selectRowCount(map);
}
BoardController
Map<String,Object> map = new HashMap<String,Object>();
map.put("category",category);
map.put("keyfield",keyfield);
map.put("keyword",keyword);
//전체,검색 레코드 수
int count = boardService.selectRowCount(map);
ch12에 있던 pagingUtil.java 그대로 가져와서 같은 위치에 사용
그 후 BoardController 재수정
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.min.js"></script>
//페이지 처리
PagingUtil page =
new PagingUtil(keyfield,keyword, pageNum,
count,20,10,"list",
"&category="+category+"&order="+order);
List<BoardVO> list = null;
if(count >0) {
map.put("order",order);
map.put("start",page.getStartRow());
map.put("end",page.getEndRow());
list = boardService.selectList(map);
}
model.addAttribute("count",count);
model.addAttribute("list",list);
model.addAttribute("page",page.getPage());
boardList.jsp
<div>
<a href="list">전체</a> |
<a href="list?category=1">자바</a> |
<a href="list?category=2">데이터베이스</a> |
<a href="list?category=3">자바스크립트</a> |
<a href="list?category=4">기타</a>
</div>
<form action="list" id="search_form" method="get">
<input type="hidden" name="category" value="${param.category}">
<ul class="search">
<li>
<select name="keyfield" id="keyfield">
<option value="1"<c:if test="${param.keyfield==1}">selected</c:if>>제목</option>
<option value="2"<c:if test="${param.keyfield==2}">selected</c:if>>ID+별명</option>
<option value="3"<c:if test="${param.keyfield==3}">selected</c:if>>내용</option>
<option value="4"<c:if test="${param.keyfield==4}">selected</c:if>>제목+내용</option>
</select>
</li>
<li>
<input type="search" name="keyword" id="keyword" value="${param.keyword}">
</li>
<li>
<input type="submit" value="찾기">
</li>
</ul>
<div class="align-right">
<select id="order" name="order">
<option value="1"<c:if test="${param.order==1}">selected</c:if>>최신순</option>
<option value="2"<c:if test="${param.order==2}">selected</c:if>>조회수</option>
<option value="3"<c:if test="${param.order==3}">selected</c:if>>좋아요</option>
<option value="4"<c:if test="${param.order==4}">selected</c:if>>댓글수</option>
</select>
<script type="text/javascript">
$('#order').change(function(){
location.href='list?category=${param.category}&keyfield='
+$('#keyfield').val()
+'&keyword='+$('#keyword').val()
+'&order='+$('#oredr').val();
});
</script>
<c:if test="${!empty user}">
<input type="button" value="글쓰기" onclick="location.href='write'">
</c:if>
</div>
</form>
<c:if test="${count ==0}">
<div class="result-display">표시할 게시물이 없습니다.</div>
</c:if>
<c:if test="${count>0}">
<table class="striped-table">
<tr>
<th>번호</th>
<th width="400">제목</th>
<th>작성자</th>
<th>작성일</th>
<th>조회수</th>
<th>좋아요수</th>
</tr>
<c:forEach var="board" items="${list}">
<tr>
<td class="align-center">${board.board_num}</td>
<td class="align-left"><a href="detail?board_num=${board.board_num}">${board.title}(${board.re_cnt})</a></td>
<td class="align-center">
<c:if test="${empty board.nick_name}">${board.id}</c:if> <!-- 닉네임이 없으면 아이디를 보여준다 -->
<c:if test="${!empty board.nick_name}">${board.nick_name}</c:if>
</td>
<td class="align-center">${board.reg_date}</td>
<td class="align-center">${board.hit}</td>
<td class="align-center">${board.fav_cnt}</td>
</tr>
</c:forEach>
</table>
<div class="align-center">${page}</div>
</c:if>
</div>




BoardMapper.java
@Select("SELECT * FROM spboard JOIN spmember USING (mem_num) LEFT OUTER JOIN spmember_detail USING(mem_num) WHERE board_num=#{board_num}") //LEFT OUTER를 하는 이유는 탈퇴했을 때 에러나는 것을 방지하기 위해
public BoardVO selectBoard(Long board_num);
@Update("UPDATE spboard SET hit=hit+1 WHERE board_num=#{board_num}")
public void updateHit(Long board_num);
BoardServiceImpl
@Override
public BoardVO selectBoard(Long board_num) {
return boardMapper.selectBoard(board_num);
}
@Override
public void updateHit(Long board_num) {
boardMapper.updateHit(board_num);
}
BoardController.java
StringUtil.java
0.00MB
이 파일의 클래스를 사용하기위해 다운
/*=======================
* 게시판 글상세
*=======================*/
@GetMapping("/board/detail")
public ModelAndView process(long board_num) {
log.debug("<<게시판 글 상세 - board_num>> :"+board_num);
//해당 글의 조회수 증가
boardService.updateHit(board_num);
BoardVO board = boardService.selectBoard(board_num);
//제목에 태그를 허용하지 않음
board.setTitle(StringUtil.useNoHTML(board.getTitle()));
//내용에 태그를 허용하지 않으면서 줄바꿈 처리
board.setContent(StringUtil.useBrNoHTML(board.getContent()));
return new ModelAndView("boardView","board",board);
}
board=>boardView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!-- 게시판 글 상세 시작 -->
<div class="page-main">
<h2>${board.title}</h2>
<ul class="detail-info">
<li>
<img src="${pageContext.request.contextPath}/member/viewProfile?mem_num=${board.mem_num}" width="40" height="40" class="my-photo">
</li>
<li>
<c:if test="${empty board.nick_name}">${board.id}</c:if>
<c:if test="${!empty board.nick_name}">${board.nick_name}</c:if>
<br>
<c:if test="${empty board_modify_date}">
작성일: ${board.reg_date}
</c:if>
<c:if test="${!empty board_modify_date}">
최근 수정일: ${board.modify_date}
</c:if>
조회 : ${board.hit}
</li>
</ul>
<c:if test="${!empty board.filename}">
<ul>
<li>첨부 파일 : <a href="file?board_num=${board.board_num}">${board.filename}</a></li>
</ul>
</c:if>
<div class="detail-content">
${board.content}
</div>
<div>
<%-- 좋아요 --%>
<%-- 댓글수 --%>
</div>
<hr size="1" width="100%">
<div class="align-right">
<c:if test="${!empty user && user.mem_num == board.mem_num}">
<input type="button" value="수정" onclick="location.href='update?board_num=${board.board_num}'">
<input type="button" value="삭제" id="delete_btn">
<script>
const delete_btn = document.getElementById('delete_btn');
delete_btn.onclick=function(){
const choice = confirm('삭제하시겠습니까?');
if (choice){
location.replace('delete?board_num=${board.board_num}');
}
};
</script>
</c:if>
<input type="button" value="목록" onclick="location.href='list'">
</div>
<hr size="1" width="100%">
<!-- 댓글 UI 시작 -->
<!-- 댓글 목록 출력 -->
<!-- 댓글 UI 끝 -->
</div>
<!-- 게시판 글 상세 끝 -->
tile-def => board.xml
<definition name="boardView" extends="main">
<put-attribute name="title" value="글상세"/>
<put-attribute name="css" value="/WEB-INF/views/board/boardCSS.jsp"/>
<put-attribute name="body" value="/WEB-INF/views/board/boardView.jsp"/>
</definition>


memberController
프로필 설정
//프로필 사진 출력(회원번호 지정)
@GetMapping("/member/viewProfile")
public String getProfileByMem_num(long mem_num,
HttpServletRequest request,
Model model) {
MemberVO memberVO = memberService.selectMember(mem_num);
viewProfile(memberVO,request,model);
return "imageView";
}

BoardController
첨부파일 다운로드하기
DownloadView.java
0.00MB
kr.spring.view에 넣기
//파일 다운로드
@GetMapping("/board/file")
public String download(long board_num, HttpServletRequest request, Model model) {
BoardVO board = boardService.selectBoard(board_num);
byte[] downloadFile = FileUtil.getbytes(request.getServletContext()
.getRealPath("/upload")+"/"+board.getFilename());
model.addAttribute("downloadFile",downloadFile);
model.addAttribute("filename",board.getFilename());
return "downloadView";
}


BoardMapper.java
파일삭제 하기위해
@Update("UPDATE spboard SET filename='' WHERE board_num=#{board_num}")
public void deleteFile(Long board_num);
BoardServiceImpl
@Override
public void deleteFile(Long board_num) {
boardMapper.deleteFile(board_num);
}
BoardAjaxController 생성
package kr.spring.board.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.spring.board.service.BoardService;
import kr.spring.board.vo.BoardVO;
import kr.spring.member.vo.MemberVO;
import kr.spring.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class BoardAjaxController {
@Autowired
private BoardService boardService;
/*========================
* 부모글
*========================*/
//업로드 파일 삭제
@PostMapping("/board/deleteFile")
@ResponseBody
public Map<String,String> processFile(long board_num, HttpSession session, HttpServletRequest request){
Map<String,String> mapJson = new HashMap<String, String>();
MemberVO user = (MemberVO)session.getAttribute("user");
if(user==null) {
mapJson.put("result","logout");
}else {
BoardVO db_board = boardService.selectBoard(board_num);
//로그인한 회원번호와 작성자 회원번호 일치 여부 체크
if(user.getMem_num() != db_board.getMem_num()) {
//불일치
mapJson.put("result","wrongAccess");
}else {
//일치
boardService.deleteFile(board_num);
FileUtil.removeFile(request,db_board.getFilename());
mapJson.put("result","success");
}
}
return mapJson;
}
}
BoardController
/*=======================
* 게시판 글 수정
*=======================*/
//수정 폼 호출
@GetMapping("/board/update")
public String formUpdate(long board_num, Model model) {
BoardVO boardVO = boardService.selectBoard(board_num);
model.addAttribute("boardVO",boardVO);
return "boardModify";
}
board.xml
<definition name="boardModify" extends="main">
<put-attribute name="title" value="글수정"/>
<put-attribute name="css" value="/WEB-INF/views/board/boardCSS.jsp"/>
<put-attribute name="body" value="/WEB-INF/views/board/boardModify.jsp"/>
</definition>
boardModify.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.min.js"></script>
<!-- 게시판 글수정 시작 -->
<div class="page-main">
<h2>글쓰기</h2>
<form:form action="update" id="board_modify"
enctype="multipart/form-data"
modelAttribute="boardVO">
<form:hidden path="board_num"/>
<ul>
<li>
<form:label path="category">분류</form:label>
<form:select path="category"> <!-- 기존에 지정해둔 value값으로 자동으로 지정되어있음 -->
<form:option value="1">자바</form:option>
<form:option value="2">데이터베이스</form:option>
<form:option value="3">자바스크립드</form:option>
<form:option value="4">기타</form:option>
</form:select>
<form:errors path="category" cssClass="error-color"/>
</li>
<li>
<form:label path="title">제목</form:label>
<form:input path="title"/>
<form:errors path="title" cssClass="error-color"/>
</li>
<li>
<form:label path="content">내용</form:label>
<form:textarea path="content"/>
<form:errors path="content" cssClass="error-color"/>
</li>
<li>
<form:label path="upload">파일 업로드</form:label>
<input type="file" name="upload" id="upload">
<c:if test="${!empty boardVO.filename}">
<div id="file_detail">
(${boardVO.filename})파일이 등록되어 있습니다.
<input type="button" value="파일 삭제" id="file_del">
</div>
<script type="text/javascript">
$(function(){
$('#file_del').click(function(){
const choice = confirm('삭제하시겠습니까?');
if(choice){
$.ajax({
url:'deleteFile',
data:{board_num:${boardVO.board_num}},
type:'post',
dataType:'json',
success:function(param){
if(param.result=='logout'){
alert('로그인 후 사용하세요');
}else if(param.result == 'wrongAccess'){
alert('잘못된 접속입니다');
}else if(param.result == 'success'){
$('#file_detail').hide();
}else{
alert('파일 삭제 오류 발생');
}
},
error:function(){
alert('네트워크 오류 발생');
}
});
}
});
});
</script>
</c:if>
</li>
</ul>
<div class="align-center">
<form:button class="default-btn">전송</form:button>
<input type="button" value="목록"
class="default-btn"
onclick="location.href='list'">
</div>
</form:form>
</div>
<!-- 게시판 글수정 끝 -->


BoardMapper.xml
로 SQL 작성
-- 글 수정 부분
<!-- 게시판 글수정 -->
<update id="updateBoard" parameterType="boardVO">
UPDATE spboard SET
<if test="filename != null">
filename = #{filename},
</if>
title = #{title},
content = #{content},
ip = #{ip},
modify_date = SYSDATE
WHERE board_num = #{board_num}
</update>
BoardServiceImpl
@Override
public void updateBoard(BoardVO board) {
boardMapper.updateBoard(board);
}
BoardController
//수정 폼에서 전송된 데이터 처리
@PostMapping("/board/update")
public String submitUpdate(@Valid BoardVO boardVO, //Valid 다음에는 바로 BindingResult가 나와야된다. 사이에 다른 값을 넣으면 에러남
BindingResult result,
Model model,
HttpServletRequest request) throws IllegalStateException, IOException {
log.debug("<<게시판 글 수정>> : "+boardVO);
//유효성 체크 결과 오류가 있으면 폼 호출
if(result.hasErrors()) {
//title 또는 content가 입력되지 않아서 유효성 체크에 걸리면
//파일 정보를 잃어버리기 때문에 폼을 호출할 때 다시 파일 정보를 세팅해야 함.
BoardVO vo = boardService.selectBoard(boardVO.getBoard_num());
boardVO.setFilename(vo.getFilename());
return "boardModify";
}
//오류가 나지 않았을 때
//DB에 저장된 파일 정보 구하기
BoardVO db_board = boardService.selectBoard(boardVO.getBoard_num());
//파일명 세팅(FileUtil.createFile에서 파일이 없으면 null 처리함)
boardVO.setFilename(FileUtil.createFile(request,boardVO.getUpload()));
return "common/resultAlert";
}
'쌍용교육(JAVA) > SpringBoot' 카테고리의 다른 글
쌍용교육 -JSP수업 97일차 ch15SpringPage(8) (0) | 2024.07.04 |
---|---|
쌍용교육 -JSP수업 96일차 ch15SpringPage(7) (0) | 2024.07.03 |
쌍용교육 -JSP수업 93일차 ch15SpringPage(4) (0) | 2024.06.28 |
쌍용교육 -JSP수업 92일차 ch15SpringPage(3) (1) | 2024.06.27 |
쌍용교육 -JSP수업 91일차 ch15SpringPage(2) (0) | 2024.06.26 |