Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

개(발)린이

Spring(게시글 작성)-Controller 본문

Spring

Spring(게시글 작성)-Controller

불도정 2023. 5. 12. 15:03

이번 시간엔 게시글을 작성하고 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