
<!-- 로그인한 회원과 게시글 작성한 회원의 번호가 같은 경우 -->
<th:block th:if="${board.memberNo == session.loginMember?.memberNo}">
<button id="updateBtn">수정</button>
<button id="deleteBtn">삭제(GET)</button>
<button id="deleteBtn2">삭제(POST)</button>
</th:block>
→ /board/1/2001
location.pathname.replace(’board’, ‘editBoard’);
→ /editBoard/1/2001/update?cp=1
⇒ 쿼리스트링 가져오기
location.pathname.replace("board", "editBoard") +
"/update" +
location.search
/**
* 게시글 수정 화면 전환
*
* @param boardCode
* @param boardNo
* @param loginMember : 로그인한 회원이 작성한 글이 맞는지
* @param ra : 글 작성 실패했을 때, redirect시 메세지 전달하기 위함
* @return
*/
@GetMapping("{boardCode:[0-9]+}/{boardNo:[0-9]+}/update")
public String boardUpdate(@PathVariable("boardCode") int boardCode, @PathVariable("boardNo") int boardNo,
@SessionAttribute("loginMember") Member loginMember, Model model, RedirectAttributes ra) {
// 수정 화면에 출력할 기존의 제목/내용/이미지 조회
// -> 게시글 상세 조회 서비스
Map<String, Integer> map = new HashMap<>();
map.put("boardCode", boardCode);
map.put("boardNo", boardNo);
// BoardService.selectOne(map) 호출 결과값 반환 받기
Board board = boardService.selectOne(map);
// memberNo는 안필요한지?
// selectOne에서 boardLike에 대한 조건을 처리하는데,
// 필요하지 않은 데이터임 -> 굳이 필요없는 데이터는 안넣어도 됌
String message = null;
String path = null;
if (board == null) {
message = "해당 게시글이 존재하지 않습니다";
// get방식이기 떄문에, 사용자가 일부로 url을 조작할 수 있기 때문에,
// 조건문 처리를 필수적으로 해줘야 한다.
path = "redirect:/";
ra.addFlashAttribute("message", message);
} else if(board.getMemberNo() != loginMember.getMemberNo()) {
// board는 가져왔는데, 로그인한 사람과, 게시글을 작성한 회원의 번호가 같지 않을떄의 상황을 처리
message = "자신이 작성한 글만 수정할 수 있습니다";
// 해당 글 상세조회 리다이렉트 (/board/1/2000)
path = String.format("redirect:/board/%d/%d", boardCode, boardNo);
ra.addFlashAttribute("message", message);
}
else {
path = "board/boardUpdate"; // forward templates/board/boardUpdate.html
model.addAttribute("board", board);
}
return path;
}
로그인한 회원 ≠ 게시글 작성한 회원

로그인한 회원 = 게시글 작성한 회원

/**
* 게시글 수정
*
* @param inputBoard : 커맨드 객체(제목, 내용)
* @param images : 제출된 type="file"인 모든 요소
* @param deleteOrderList : 삭제된 이미지 순서가 기록된 문자열 (ex. "1,2,3")
* @return
*/
@PostMapping("{boardCode:[0-9]+}/{boardNo:[0-9]+}/update")
public String boardUpdate(@PathVariable("boardCode") int boardCode, @PathVariable("boardNo") int boardNo,
Board inputBoard, @RequestParam("images") List<MultipartFile> images,
@RequestParam(value = "deleteOrderList", required = false) String deleteOrderList,
@RequestParam(value = "cp", required = false, defaultValue = "1") int cp,
@SessionAttribute("loginMember") Member loginMember, RedirectAttributes ra) throws Exception {
// 1. 커맨드 객체(inputBoard)에 boardCoe, boardNo, memberNo를 세팅
inputBoard.setBoardCode(boardCode);
inputBoard.setBoardNo(boardNo);
inputBoard.setMemberNo(loginMember.getMemberNo());
// inputBoard -> 제목, 내용, boardCode, boardNo, 회원번호 세팅됨
// 2. 게시글 수정 서비스 호출 후 결과 반환 받기
int result = service.boardUpdate(inputBoard, images, deleteOrderList);
// 3. 서비스 결과에 따라 응답 제어
String message = null;
String path = null;
if (result > 0) {
message = "게시글이 수정되었습니다";
path = String.format("/board/%d/%d?cp=%d", boardCode, boardNo, cp);
// /board/1/2000?cp=3
} else {
message = "수정 실패";
path = "update";
// 1/2000/update -> 즉, GetMapping으로 받겠다는 것 => 다시한번 시도해보라는 것
// GET (수정 화면 전환)
}
ra.addFlashAttribute("message", message);
return "redirect:" + path;
}
// 게시글 수정 서비스
@Override
public int boardUpdate(Board inputBoard, List<MultipartFile> images, String deleteOrderList) throws Exception{
// 1. 게시글 부분(제목/내용) 수정
// 제목/내용 -> BOARD 테이블, BOARD_IMG 테이블
// 테이블이 다르기 때문에 따로따로 진행해야함
int result = mapper.boardUpdate(inputBoard);
// 수정 실패 시 바로 리턴
if (result == 0)
return 0;
// 2. 기존 0 -> 삭제된 이미지(deleteOrderList)가 있는 경우
if (deleteOrderList != null && !deleteOrderList.equals("")) {
Map<String, Object> map = new HashMap<>();
map.put("deleteOrderList", deleteOrderList);
map.put("boardNo", inputBoard.getBoardNo());
// BOARD_IMG에 존재하는 행을 삭제하는 SQL 호출
result = mapper.deleteImage(map);
String[] delete = deleteOrderList.split(",");
if (result == 0) {
// 삭제 실패한 경우
throw new RuntimeException();
} else if (delete.length != result) {
// 업로드된 갯수와 삭제하려던 갯수가 다른 경우
throw new RuntimeException();
}
// 3. 선택한 파일이 존재할 경우
// (클라이언트가 실제로 업로드한 이미지가 있는 경우)
List<BoardImg> uploadList = new ArrayList<>();
for (int i = 0; i < images.size(); i++) {
if (!images.get(i).isEmpty()) {
String originalName = images.get(i).getOriginalFilename();
String rename = Utility.fileRename(originalName);
BoardImg img = BoardImg.builder().imgOriginalName(originalName).imgRename(rename).imgPath(webPath)
.boardNo(inputBoard.getBoardNo()).imgOrder(i).uploadFile(images.get(i)).build();
uploadList.add(img);
// 4. 업로드 하려는 이미지 정보(img) 이용해서
// 수정을 할지, 삽입을 할지 결정을 해야함
// 게시판에서 기존에 있는 사진에 다른 사진을 넣던지(수정), 아예 업로드 안됐던 곳에 사진을 업로드(삽입)
// 1) 기존에 이미지가 있었다면 -> 새 이미지로 변경 -> 수정
result = mapper.updateImage(img);
// 즉, BOARD_IMG에서 수정이 됐다면 1, 없다면 0
if(result == 0) {
// 수정 실패 == 기존에 해당하는 순서(IMG_ORDER)에 이미지가 없었음
// -> 삽입 수행
// 2) 기존에 존재하지 않으므로, 새 이미지 추가
result = mapper.insertImg(img);
}
}
// 수정 또는 삽입이 실패한 경우
if(result == 0) {
throw new RuntimeException(); // 롤백
}
}
if(uploadList.isEmpty()) {
// 선택한 파일이 없을 경우
// 즉, 클라이언트가 업로드한 이미지가 없을 경우
// 1) 제목, 내용만 수정한 경우
// 2) 이미지를 삭제한 경우
return result;
}
// 수정, 새 이미지 파일을 서버에 저장
for(BoardImg img : uploadList) {
img.getUploadFile().transferTo(new File(folderPath + img.getImgRename()));
}
}
return result;
}
// 삭제할 때 BOARD_DEL_FL, 즉 진짜 삭제하지말고 UPDATE하라는 것
// /editBoard/2/1997/delete?cp=1
@RequestMapping("{boardCode:[0-9]+}/{boardNo:[0-9]+}/delete")
public String boardDelete(Board board, @SessionAttribute("loginMember") Member loginMember,
@RequestParam(value = "cp", required = false, defaultValue = "1") int cp, RedirectAttributes ra)
throws Exception {
int result = service.boardDelete(board, loginMember);
String message = null;
String path = null;
if (result > 0) {
// 삭제 성공
message = "삭제에 성공했습니다!";
path = "/board/" + String.format("%d?cp=%d", board.getBoardCode(), cp);
} else {
// 삭제 실패
message = "삭제에 실패했습니다...";
path = "/board/" + String.format("%d/%d?cp%d", board.getBoardCode(), board.getBoardNo(), cp);
}
ra.addFlashAttribute("message", message);
return "redirect:" + path;
}
/**
* 게시물 삭제
*/
@Override
public int boardDelete(Board board, Member loginMember) throws Exception{
Map<String, Integer> map = new HashMap<>();
map.put("memberNo", loginMember.getMemberNo());
map.put("boardNo", board.getBoardNo());
return mapper.boardDelete(map);
}