01. update.jsp 준비
02. BoardController.java
- URL 요청에 대해 받을 수 있게 GET 메소드에 대한 @GetMapping 메소드 작성
▼완성코드
// ▼ 게시글 수정
@GetMapping("/update")
public ModelAndView update(
@SessionAttribute("loginMember") Member loginMember,
ModelAndView model, @RequestParam("no") int no) {
Board board = service.findBoardByNo(no);
if(loginMember.getNo() == board.getWriterNo()) {
// ▼ model : 컨트롤러에서 처리한 결과를 jsp에게 전달하는 객체
// 서비스를 통해 조회해온 board 객체를 jsp에게 포워딩한다.
model.addObject("board", board);
model.setViewName("board/update");
} else {
model.addObject("msg", "잘못된 접근입니다.");
model.addObject("location", "/board/list");
model.setViewName("common/msg");
}
return model;
}
- 로그인체크인터셉터를 탈 수 있도록 해보자
03. Servlet-context.xml
<mapping path="/board/update"/>
- 로그인 체크 적용되도록 위처럼 작성
04. BoardController.java
- 지금 상태에서는 작성된 글 관련 정보(제목, 작성자 첨부파일, 내용 등)가 불러와지지 않은 상태이기 때문에 이 부분을 수정해보자.
- HOW? 게시글에 대한 PK 값인 no값을 이용해서 조회한다. -> 컨트롤러에서 데이터를 조회해서 Model 객체에 담아서 .jsp 에 포워딩 시키면 된다.
- 데이터베이스에 실제 있는(값이 저장되고 있는) 컬럼이랑 현재 계정의 NO 값이 동일하면 본인이 작성한 글이다.
- 또한, URL에서 바로 pk값을 파라미터로 넘겨버려서 특정 글 번호를 입력해버리면, 본인이 작성한 게시물이 아니여도 글 수정 페이지로 들어갈 수 있기 때문에 걸러주는 로직이 필요하다.
- 로그인 멤버는 Session 영역에서 가져올 수 있다. @SessionAttribute 파라미터에서 이용해보자.
(이 실습에서는 쿼리문들에서 WRITER_NO에 대한 매핑이 빠져있기 때문에, 해당하는 쿼리문에 컬럼들을 추가했다. 에러가 발생했을 때는 toString으로 값도 찍어보고 쿼리문도 뒤져보자.)
- 글을 수정하고 '수정하기(<input type="submit" value="수정">)' 버튼을 누르면 /board/update로 POST 요청을 보내게 될 것이다. 아직 POST 처리 요청에 대한 컨트롤러 메소드가 없어서 405 에러가 발생한다.
- POST 요청 받을 수 있는 핸들러를 컨트롤러에 만들자.
@PostMapping("/update")
public ModelAndView update(ModelAndView model,
@ModelAttribute Board board, @RequestParam("upfile") MultipartFile upfile,
@SessionAttribute("loginMember") Member loginMember){
int result;
if(loginMember.getId().equals(board.getWriterId))){
result = servie.save(board);
if(result > 0){
model.addObject("msg", "게시글 수정 성공");
model.addObject("location", "/board/view?no=" + board.getNo());
} else {
model.addObject("msg", "게시글 수정 실패");
model.addObject("location", "/board/update?no=" + board.getNo());
}
} else {
model.addObject("msg", "잘못된 접근입니다.");
model.addObject("location", "/board/list");
}
model.setViewName("common/msg");
return model;
}
- 사용자가 전달하는 데이터를 몽땅 받아오고 싶기때문에 즉, 객체로 받기 위해서 @ModelAttribute 이용
- @ModelAttribute로 원하는 타입의 객체 Board board 를 지정한다. 그러면 기본 생성자로 Board 객체를 만든다. Board 객체의 필드명과 사용자가 보내주는 파라미터의 name 속성이랑 동일한 것들이 있으면 자동으로 값을 set 해준다.
05. BoardServiceImpl.java
- save() 메소드에서 update가 수행될 수 있도록 로직 완성해보자.
@Override
@Transactional
public int save(Board board) {
int result = 0;
if(board.getNo() != 0) {
// update
result = mapper.updateBoard(board);
} else {
// insert
result = mapper.insertBoard(board);
}
return result;
}
- board-mapper.xml에 id가 updateBoard인 쿼리문 준비
06. BoardMapper.java
int updateBoard(Board board);
- 추상 메소드 작성
++) 업로드된 파일이 있는 경우 처리할 로직을 추가하자.
- 먼저 사용자가 파일을 업로드 했는지? 확인
- renamedFileName이 null이 아니면 originalFilename과 renamedFileName을 얻어와서 새로 board에 set 해보자.
- 그런데 실제 물리적인 위치에 원래 원본 파일이 남아있기 때문에, (실무에서는 바로 지우지 않고 임시 폴더에 옮겼다가 일정 기간 지나고 일괄 삭제 하거나 한다.) 이걸 지우는 로직을 추가해보자.
@PostMapping("/update")
public ModelAndView update(ModelAndView model,
@ModelAttribute Board board, @RequestParam("upfile") MultipartFile upfile,
@SessionAttribute("loginMember") Member loginMember){
int result;
if(loginMember.getId().equals(board.getWriterId))){
if(upfile != null && !upfile.isEmpty()){
String renamedFileName = null;
String location = null;
try{
location = resourceLoader.getResource("resources/upload/board").getFile().getPath();
if(board.getRenamedFileName() != null) {
FileProcess.delete(location + "/" + board.getRenamedFileName());
}
renamedFileName = FileProcess.save(upfile, location);
if(renamedFileName != null){
board.setOriginalFileName(upfile.getOriginalFileName());
board.setRenamedFileName(renamedFileName);
}
} catch (IOException e){
e.printStackTrace();
}
}
result = servie.save(board);
if(result > 0){
model.addObject("msg", "게시글 수정 성공");
model.addObject("location", "/board/view?no=" + board.getNo());
} else {
model.addObject("msg", "게시글 수정 실패");
model.addObject("location", "/board/update?no=" + board.getNo());
}
} else {
model.addObject("msg", "잘못된 접근입니다.");
model.addObject("location", "/board/list");
}
model.setViewName("common/msg");
return model;
}
07. FilePorcess.java
public static void delete(String location) {
File file = new File(location);
if(file.exists()) {
file.delete();
}
}
- 범용으로 사용할 수 있도록 FilePorcess에 delete() 메소드 작성
- 전달받은 location 정보로 새로운 파일 객체 만들고 File 객체의 delete() 메소드로 지운다.
'Programming > Framework' 카테고리의 다른 글
DAY 163. Spring MVC 첨부파일 다운로드 (0) | 2022.01.30 |
---|---|
DAY 162. Spring MVC 게시글 상세조회 (0) | 2022.01.29 |
DAY 161. Spring MVC 게시판 게시글 작성 (0) | 2022.01.28 |
DAY 160. Spring MVC 게시판 페이징 (0) | 2022.01.26 |
DAY 159. Spring 회원 탈퇴 (0) | 2022.01.25 |