오전 수업을 게시글을 작성 후 업로드 하는 부분을 구현했다
loginSession이 null이 아닐 경우 . 게시글 작성 버튼이 활성화 되는 코드를 작성했었다 하지만 연결된 버튼의 주소가 Servlet Project 당시와 좀 달라져 board.js의 즉시 실행 함수를 변경해줄 필요성이 생겼다.
// 서블릿 프로젝트 당시
프로젝트명/board/detail?no=249&cp=6
// Spring MVC 방식
프로젝트명/board/detail/1/496?cp=1
달라진점
이전 페이지에서 boardCode를 PathValue로 전달하게 되는데
PathValue는 자동적으로 Request Scope로 선언하게 된다
이 값을 이용해 해당 JSP 에서 전역변수로 만들어버려 사용하면 편하다.
<script>
const boardCode = "${boardCode}";
//게시판 종류 번호를 전역변수로 생성해서 js파일에서도 쉽게 사용한다.
</script>
필요한 값
//게시글 작성 (삽입 / 수정) @PostMapping("/write/{boardCode}") public String boardWrite(BoardDetail detail ,@RequestParam(value="images" ,required = false)List<MultipartFile> imageList ,@PathVariable("boardCode") int boardCode ,String mode ,@ModelAttribute("loginMember")Member loginMember ,HttpServletRequest req ,RedirectAttributes ra)throws Exception{
매개변수가 7개다...
이 때 전달되는 이미지'들'은 MultpartFile으로 자동적으로 변환되어 List객체에 저장된다.
step 1
로그인한 회원의 번호를 detail(게시글 상세정보VO)에 세팅해준다
detail.setMemberNo(loginMember.getMemberNo());
step 2
이미지를 저장할 경로 얻어오기( 2 가지 )
웹상에서 접근 가능한 경로인 webPath ( WEB-INF 기준? )String webPath = "/resources/images/board/";
실제로 서버에 저장될 folderPath (실제 저장될 서버 경로)
//webPath값을 지정하면 해당경로까지의 realPath를 추출하는 코드 String folderPath = req.getSession().getServletContext().getRealPath(webPath);
step 3
비지니스 로직 수행
INSERT에 필요한 VO(게시글 내용) , 이미지 목록 , 이미지를 저장할 경로값 두개를 가지고 로직 수행 후
삽입된 게시글 번호를 반환한다.
게시글 작성의 경우 Service 부분에서 상당히 많은 수행이 이뤄진다.
if (boardNo > 0) {
List<BoardImage> boardImageList = new ArrayList<BoardImage>();
List<String> reNameList = new ArrayList<String>();
for (int i = 0; i < imageList.size(); i++) {
// i 번째 이미지는 업로드된 이미지가 있을 경우 없으면 0이기 때문
if (imageList.get(i).getSize() > 0) {
// 변경된 파일명 저장
String rename = Util.fileRename(imageList.get(i).getOriginalFilename());
reNameList.add(rename);
// BoardImage 객체를 생성하여 값 세팅 후 boardImageList에 추가
BoardImage img = new BoardImage();
img.setBoardNo(boardNo); // 게시글 번호
img.setImageLevel(i); // 이미지 순서
img.setImageOriginal(imageList.get(i).getOriginalFilename()); // 원본 파일명
img.setImageReName(webPath + rename); // 웹 경로 + 방금 만든 이름
boardImageList.add(img);
} // if문 끝
} // for문 끝
if (!boardImageList.isEmpty()) {
//boardImageList == 실제 삽입된 이미지 목록
이미지 분류 작업.
if (!boardImageList.isEmpty()) {
int result = dao.insertBoardImageList(boardImageList);
if (boardImageList.size() == result) {
for (int i = 0; i < boardImageList.size(); i++) {
int index = boardImageList.get(i).getImageLevel();
imageList.get(index).transferTo(new File(folderPath + reNameList.get(i)));
}
}else{
throw new InsertFailException();
}
}
차근차근 읽어보면 단순한 로직이다
1 : 실제 삽입된 이미지만 DB에 저장되어야 한다
2 : 삽입 성공된 개수와 실제이미지 목록이 저장된 List의 길이가 동일하다면 정상적으로 삽입이 완료다는 의미이다
3: 실제 이미지들이 List의 길이 만큼 반복하면서 서버에 저장한다
단 ,반복을 수행하면서 단 한번의 에러라도 발생시 직접 정의한
파일 입력 실패 예외로 예외를 던진다.