개(발)린이
Spring(게시글 작성)-Controller 본문
이번 시간엔 게시글을 작성하고 DB에 저장하는 것 까지 구현 해본다.
먼저 jsp파일을보자
거두절미하고 버튼부분만 본다면
<div class="btn-area">
<c:if test="${!empty loginMember}">
<!-- /community/board/write -->
<button id="insertBtn" onclick="location.href='../write/${boardCode}?mode=insert&cp=${pagination.currentPage}'">글쓰기</button> <!-- ex) 현재 주소 : /comm/board/list/3 -->
</c:if> <!-- mode에 따라 한 메소드에 삽입/수정 이 이루어지게끔 --> <!-- 목표 주소 : /comm/board/write?mode=i/u -->
</div>
버튼을 눌러서 이동하고자 하는 jsp는 boardWriteForm 이다. 글쓰기 주소를 보면http://localhost:8080/comm/board/write/3?mode=insert&cp=1 이고
게시판 목록 주소는(현재주소)
http://localhost:8080/comm/board/list/3 이다
게시글 작성 페이지로 가기 위해선 한단계 위로 올라가서 board/... 이런식으로 가야한다
그래서 버튼에 onclick속성을 넣어서 ../write/${boardcode}(공지사항1, 자유게시판 2, 질문게시판3)?mode=insert(게시글 삽입모드 or 수정모드를 쿼리스트링을 이용하기위에 넣음)&cp=${pagination.currentPage} 이렇게 url설정을 하였다.
그리고 <c:if> 태그에는 로그인 했을때만 글쓰기 버튼을 보여주기 위해 넣었다.
다음으로 컨트롤러를 만들어보자
게시글을 작성하려면 작성 화면으로 이동해야하므로 이동하는 컨트롤러부터 만들어보자
@GetMapping("/write/{boardCode}")
public String writeBoard(@PathVariable("boardCode") int boardCode,
String mode,
@RequestParam(value="no", required =false, defaultValue = "0") int boardNo,
/* insert의 경우 파라미터에 no 가 없을 수 있음 그래서 required = false 넣어줌 */
Model model) {
if(mode.equals("update")) {
// 게시글 상세조회 서비스 호출(boardNo)
BoardDetail detail = service.selectBoardDetail(boardNo);
// -> 개행 문자가 <br> 로 되어있는 상태 -> textarea 출력 예정이기 때문에 \n 으로 변경
detail.setBoardContent(Util.newLineClear(detail.getBoardContent()));
model.addAttribute("detail", detail);
}
return "board/boardWriteForm";
}
GetMapping은 /write/{boardCode}로 설정해주었다.
그리고 if문을 사용해서 mode가 insert가 아닌 update일 경우에는 수정화면으로 전환 시키기 위해 사용하였는데
수정 버튼 코드를 보면
<button id="updateBtn" onclick="location.href='../../write/${boardCode}?mode=update&type=&cp=${cp}&no=${detail.boardNo}'">수정</button>
../../write/${boardCodde}에 모드는 update로 되어있다.
따라서 같은 주소를 가지고 있어서 쿼리스트링을 이용 mode를 비교해 화면을 선택해 띄워주는것이다.
그래서 만약 mode=update일 경우엔 BoardDetail(상세조회) 서비스를 호출한다.
개행 문자를 미리 만들어놓은 Util클래스에있는 newLineClear를 사용하여 <br>을 \n으로 바꿔준다
후에 Mode.addAttribute를 이용 스코프에 올려준다.
따라서 수정화면으로 가게되면 작성 페이지에 해당 번호의 게시글을 불러와서 띄워준다고 생각하면 된다.
마지막으로 board/boardWriteForm을 리턴하여 페이지 이동하면 된다.
페이지 이동에 성공했으면 게시글 작성을 본격적으로 해보자
boardWriteForm을 보면 Form태그를 보면
<form action="${boardCode}" enctype="multipart/form-data" method="POST" class="board-write"
onsubmit="return writeValidate()">
이렇게 되있다
따라서 컨트롤러에 @PostMapping("/write/{boardCode}")로 작성해준다
@PostMapping("/write/{boardCode}") // boardTitle, boardContent, boardNo(수정)
public String boardWrite( BoardDetail detail,
@RequestParam(value="images", required = false) List<MultipartFile> imageList, // 업로드파일(이미지)리스트
@PathVariable("boardCode") int boardCode,
String mode,
@ModelAttribute("loginMember") Member loginMember,
RedirectAttributes ra,
HttpServletRequest req, // 이미지 저장 경로용
@RequestParam(value="cp", required = false, defaultValue = "1") int cp,
@RequestParam(value="deleteList", required=false) String deleteList) throws IOException{
게시글에 이미지를 삽입하기위해 MutipartFile을 리스트로 작성해주었고 이미지 없이 작성했을때 예외가 나지 않도록 하기 위하여 required = false 로 설정해주었다.
PathVariable로 boardCode를 그리고 작성과 수정을 한 메소드에서 해결하기 위해 mode를 가져왔다.
그리고 로그인 유무를 확인하기 위해 loginMember를 가져오고 메세지arlet을 사용하기위해 RedirectAttributes, 이미지 저장 경로용 HttpServletRequest, 그리고 cp와 deleteList 또한 required = false로 설정해주었다.
그 후에
게시글 삽입인지 수정인지 확인하기위해
if문을 사용해 갈림길을 만들어 준다
로그인한 회원번호를 얻어와서 detail에 세팅해준다.
detail.setMemberNo( loginMember.getMemberNo() );
이미지 저장 경로 얻어오기 (webPath, folderPath)
String webPath = "/resources/images/board/";
String folderPath = req.getSession().getServletContext().getRealPath(webPath);
삽입인지 수정인지 확인
if(mode.equals("insert")) { // 삽입
// 게시글 부분 삽입 (제목, 내용, 회원번호, 게시판코드)
// -> 삽입된 게시글의 번호( boardNo) 반화 (why? 삽입이 끝나면 게시글 상세조회로 redirect)
// 게시글에 포함된 이미지 정보 삽입 (0 ~ 5개, 게시글 번호 필요)
// -> 실제 파일로 변환해서 서버에 저장( transFer() )
// 두 번의 insert 중 한 번 이라도 실패하면 전체 rollback(트랜잭션 처리)
int boardNo = service.insertBoard(detail, imageList, webPath, folderPath);
String path = null;
String message = null;
if(boardNo > 0) {
// /board/write/1
// /board/detail/1/520
path = "../detail/" + boardCode + "/" +boardNo;
message = "게시글 등록 완료";
} else {
path = req.getHeader("referer");
message ="게시글 작성 실패";
}
ra.addFlashAttribute("message", message);
return "redirect:" + path;
}
게시글 작성이 완료되면 /detail/boardCode/삽입되었을때 return한 boardNo 로 redirect되게끔 작성하였다.
만약에 else로 실행된다면 수정이 되게끔 코드를 작성하였다.
else { // 수정
// 게시글 수정 서비스 호출
// 게시글 번호를 알고잇기떄문에 수정 결과만 반환 받으면 된다.
int result = service.updateBoard(detail, imageList, webPath, folderPath, deleteList);
String path = null;
String message = null;
if(result > 0) {
// 현재 : /board/write/{boardCode}
// 목표 : /board/detail/{boardCode}/{boardNo}?cp=10
path = "../detail/" + boardCode + "/" + detail.getBoardNo() + "?cp=" + cp;
message = "게시글 수정 완료";
} else {
path = req.getHeader("referer");
message ="게시글 수정 실패";
}
ra.addFlashAttribute("message", message);
return "redirect:" + path;
}
}
삽입과 거의 같지만 수정 완료후 기존에 detail페이지로 redirect해주기 위해 cp를 추가하였다.
다음엔 service부터 시작한다.
'Spring' 카테고리의 다른 글
AOP(2) (0) | 2023.05.16 |
---|---|
AOP (0) | 2023.05.12 |
Spring(scheduling) (0) | 2023.05.11 |
Spring (게시글 조회수) (0) | 2023.05.07 |
Spring 게시판 3 (0) | 2023.05.02 |