게시물 상세보기(read.jsp) URL에서 없는 게시글 번호를 입력하면 게시글 번호가 없다는 에러가 발생합니다.

이럴  때 예외가 발생했을 때 처리를 해야합니다.

@ControllerAdvice를 이용한 예외처리를 해볼텐데요

스프링에서 제공하는 @Controller는 해당 메서드에서 발생한 예외를 모두 처리하는 역할을 수행해줍니다.

ExceptionAdvice.java를 생성하겠습니다.

package kr.co.web.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class ExceptionAdvice {
	private static final Logger logger = LoggerFactory
			.getLogger(ExceptionAdvice.class);
	
	@ExceptionHandler(Exception.class)
	public String common(Exception e) {
		logger.info(e.toString());
		
		return "error_common";
		
	}
}

 

ExceptionAdvice 클래스의 선언된 어노테이션을 보시면 @ControllerAdvice로 선언이 되어 있는데요

이 @ControllerAdvice 어노테이션은 클래스의 객체가 컨트롤러에서 발생하는 예외를 처리하는 클래스라고 명시합니다.

common() 이라는 메서드를 이용해서 Exception 타입으로 처리되는 모든 예외를 처리하도록 설정합니다.

만약 예외가 발생하면 ExceptionAdvice의 common 메서드가 실행되어서 return 값으로 error_common 페이지로 이동합니다.

이동하고 오류 내용을 해당 페이지에 출력하고 싶다면, 오류 내용을 Model에 담아 error_common로 값을 전달하는데요

@ControllerAdvice 클래스의 메서드는 Exception 객체의 타입만을 파라미터로 사용할 수 있고, 일반 Controller와 같이 Model을 파라미터로 사용하지 못하도록 되어 있습니다.

그래서 하나의 객체에 Model 데이터와 View의 처리를 동시에 사용할 수 있는 ModelAndView 객체를 사용할텐

ModelAndView 객체는 하나의 객체에 Model 데이터와 View의 처리를 동시에 할 수 있는 객체 입니다.

이제 ModelAndView 객체를 이용하기 위해 코드를 수정하겠습니다.

 

package kr.co.web.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class ExceptionAdvice {
	private static final Logger logger = LoggerFactory
			.getLogger(ExceptionAdvice.class);
	
	@ExceptionHandler(Exception.class)
	public ModelAndView errorModelAndView(Exception e) {
		logger.info(e.toString());
		
		ModelAndView modelAndView = new ModelAndView();
		
		modelAndView.setViewName("error_common");
		
		modelAndView.addObject("exception", e);
		
		return modelAndView;
		
	}
}

 

이렇게 수정 한뒤 없는 번호를 입력해보겠습니다

http://localhost:8081/board/read?board_number=2666

 

 

아까는 500 error로 해당 데이터가 없다고 출력됐지만 예외를 처리하는 클래스인 ExceptionAdvice를 만들었기 때문에

error_common.jsp를 찾는건데요 

error_common.jsp를 만들겠습니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
		<h1>오류 내용</h1>
		
		<ul>
			<!-- 예외발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력 -->
			<c:forEach items="${exception.getStackTrace()}" var="stack">
				<li>${stack.toString()}</li>
			</c:forEach>
		</ul>
</body>
</html>

 

 

 

 

정상적으로 에러 내용이 나옵니다!!

수정 기능

 

저번장에서 read.jsp에 삭제버튼과 수정버튼을 만들었습니다.

이제 수정 기능부터 구현하도록 하겠습니다.

 

BoardController에 update 메소드를 작성하겠습니다.

 

@RequestMapping(value = "/update", method = RequestMethod.GET)
public void updateGET(@RequestParam("board_number") Integer board_number, Model model) throws Exception {
	logger.info("updateGET!!!");
	BoardVO board = service.read(board_number);
	model.addAttribute("BoardVO", board);
}
	
@RequestMapping(value = "/update", method = RequestMethod.POST)
public String updatePOST(BoardVO board, RedirectAttributes ra) throws Exception {
	logger.info("updateGET!!!");
	service.update(board);
	ra.addFlashAttribute("result", "updateOK");
	return "redirect:/board/read?board_number="+board.getBoard_number();
}

 

 

read.jsp에서 수정버튼을 누르면 updateGET 메서드가 호출되어서 수정할 게시물의 데이터를 조회하여 수정 창을 보여줍니다.

그 다음 사용자가 수정 하려는 데이터를 입력하고 저장버튼을 누르면 updatePOST메서드가 실행되어서, 서비스 객체를 이용해서 DB 값을 수정 하고 난뒤 해당 게시물의 read.jsp를 redirect하는 방식입니다.

이제 update.jsp를 작성하겠습니다. 

board/view 폴더에 update.jsp를 생성하구요

read.jsp의 코드를 가져와서 몇 가지만 수정할건데요

read.jsp에서 제목, 내용, 작성자가 readonly로 되어있는데 작성자는 그대로 readonly로 두고,

제목과 내용은 readonly를 지워줍니다.

그리고 저희는 update할것이기 때문에 form태그로 해당 코드를 감싸줄겁니다.

다음과 같이 작성합니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>
</head>
<body>
	<form method="post">
		<div>글번호 : ${BoardVO.board_number}</div>
		<input type="hidden" name="board_number" value="${BoardVO.board_number}"/>
		<div>
			<div>
				<label for="title">제목</label>
				<input type="text" id="title" name="title" value="${BoardVO.title}"/>		
			</div>
			
			<div>
				<label for="contents">내용</label>
				<textarea name="contents" id="contents" rows="3">${BoardVO.contents}</textarea>		
			</div>
			
			<div>
				<label for="name">작성자</label>
				<input type="text" name="name" id="name" value="${BoardVO.name}" readonly="readonly"/>		
			</div>
		</div>
		
		<div>
			<button type="submit">등록</button>
			<button><a href="/board/read?board_number=${BoardVO.board_number}">취소</a></button>
		</div>
	</form>
</body>
</html>

 

 

아까 updatePOST에서 model 값을 보냈는데 그 값을 받아서 업데이트가 되었다고 경고창을 띄워 보겠습니다.

 

<!-- read.jsp -->

<script>
	var result = '${result}';
  	if(result === 'updateOK') {
		alert("수정되었습니다.");
	}
</script>

 

 

삭제 기능

 

수정 기능을 작성했으니 이제 삭제를 하는 메서드를 만들겠습니다.

BoardController에 delete메서드를 작성합니다.

 

@RequestMapping(value = "/delete", method = RequestMethod.GET)
public void deleteGET(@RequestParam("board_number") Integer board_number, Model model) throws Exception {
	logger.info("deleteGET");
	BoardVO board = service.read(board_number);
	model.addAttribute("BoardVO", board);
}
	
@RequestMapping(value = "delete", method = RequestMethod.POST)
public String deletePOST(@RequestParam("board_number") Integer board_number, RedirectAttributes ra) throws Exception {
	logger.info("deletePOST");
	service.delete(board_number);
    ra.addFlashAttribute("result", "deleteOK");
	return "redirect:/board/listAll";	
}

 

GET에서는 update 메서드와 마찬가지고 board_number를 파라미터로 받아서 글번호를 출력하고,

POST에서도 board_number를 파라미터로 받아서 글을 삭제 하겠습니다.

 

이제 delete.jsp의 뷰를 만들어 볼 것입니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>

</head>
<body>
	<div>글번호 : ${BoardVO.board_number}</div>
	<br/>
	정말로 삭제하시겠습니까?
	<br />
	
	<div>
		<form action="/board/delete?board_number=${BoardVO.board_number}" method="post">
			<a><button>예 삭제합니다</button></a>
		</form>
		
		<button><a href="/board/read?board_number=${BoardVO.board_number}">취소</a></button>	
	</div>
	
</body>
</html>

 

controller를 수정했으니 서버를 재가동 시키고 삭제를 해보겠습니다.

 

삭제하기 위해 read.jsp 접속하여 삭제 버튼클릭

 

 

삭제 버튼 클릭

 

 

삭제 완료

 

 

28번 게시글을 지우는 것을 확인했으니 마지막으로 잘 삭제가 되었다고 경고창을 띄우러 가겠습니다.

 

BoardController -> deletePOST 메서드의 리턴값이 listAll을 향하고 있으니 

listAll.jsp에 script를 작성해야겠죠?

 

아래와 같이 작성합니다.

 

<!-- listAll.jsp -->

<script>
	var register = "${register}";
	if(register === "registerOK") {
		alert("등록 되었습니다.");
	}
		
	var result = "${result}";
	if(result === "deleteOK") {
		alert("삭제 되었습니다.");
	}
</script>

 

 

경고창이 잘 뜨는지 확인해볼까요?

 

 

 

정상적으로 작동하는것을 확인했습니다.

 

지금까지 글작성, 수정, 삭제 기능을 구현했으니 다음 장에는 게시글 목록을 깔끔하게 보기 위하여

다음 장에는 페이징 기능을 구현하겠습니다!!

'JAVA > blog' 카테고리의 다른 글

페이징 처리(2)  (0) 2020.07.11
페이징 처리(1)  (0) 2020.07.11
해당 게시물 조회  (0) 2020.07.09
게시글 목록 구현  (0) 2020.07.09
controller redirect  (0) 2020.07.09

저번 장에서는 작성한 게시물들의 목록을 보여주는 게시물목록을 구현했습니다.

이번에는 각 게시물의  제목, 내용, 작성자가 누구인지 볼 수 있는 기능을 구현해보겠습니다.

BoardController에 read메서드를 만들고 해당 view를 만들어보겠습니다.

 

read 기능 추가

 

저번장에서 listAll.jsp에서 title에 ‘/board/read?board_number=글번호’ 링크를 걸었는데 title을 누르면 조회를 담당하는 BoardController 메소드 read를 호출되게 구현하겠습니다.

read 메서드는 글번호에 따라 데이터를 가져와야 함으로 board_number를 매개변수로 받아야 합니다.

이제 read메서드를 추가하겠습니다.

 

@RequestMapping(value = "/read", method = RequestMethod.GET)
public void read(@RequestParam("board_number") Integer board_number, Model model) throws Exception{
	 logger.info("read GET!!!");
	 BoardVO board  = service.read(board_number);
     	 model.addAttribute("BoardVO", board);
}

 

여기서 잠깐 설명을 하자면

read 메서드의 파라미터로 @RequestParam("board_number") Integer board_number 부분이 있는데요

이렇게 하는이유는 2가지로 설명하겠습니다.

1. 파라미터의 값과 이름을 함께 전달하는 방식으로 게시판등에서 페이지 및 검색 정보를 함께 전달하는 방식을 사용할 때

2.. listAll.jsp에서 /read?board_number=1와 같이 url이 전달될 때 board_number 파라미터를 받아오게되는데요

    @RequestParam 어노테이션의 괄호 안의 경우는 전달인자 이름(실제 값)입니다.

 

이와 같이 파라미터값을 가져올 때 사용합니다!

 

read VIEW 구현

 

view/board 폴더에 read.jsp를 생성하겠습니다.

추가로 다른 게시판등에서도 사용되는 수정, 삭제를 위해 버튼과 목록으로 돌아가는 버튼을 추가하겠습니다.

코드는 register.jsp에 있는 코드를 복사해서 붙여넣기 해서 <input> 태그의 value속성으로 데이터를 가져와서 뿌리겠습니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>
</head>
<body>
	
		<div>글번호 : ${BoardVO.board_number}</div>
	
		<div>
			<button type="button" onclick="location.href='listAll' ">목록</button>
			<button><a href="/board/update?board_number=${boardVO.board_number}">수정</a></button>
			<button><a href="/board/delete?board_number=${boardVO.board_number}">삭제</a></button>
			
		</div>
		
		<div>
			<div>
				<label for="title">제목</label>
				<input type="text" id="title" name="title" value="${BoardVO.title}" readonly="readonly"/>		
			</div>
			
			<div>
				<label for="contents">내용</label>
				<textarea name="contents" id="contents" rows="3" readonly="readonly">${BoardVO.contents}</textarea>		
			</div>
			
			<div>
				<label for="name">작성자</label>
				<input type="text" name="name" id="name" value="${BoardVO.name}" readonly="readonly"/>		
			</div>
		</div>
		
		<div>
			<button type="submit">등록</button>
		</div>
		
</body>
</html>

 

이제 listAll페이지에서 게시물 제목을 클릭해보겠습니다.

 

 

데이터가 정상적으로 잘나오는 것을 확인했습니다.

이제 생성한 수정, 삭제 버튼을 구현해야겠죠?

다음 장에서 구현하겠습니다!!!

'JAVA > blog' 카테고리의 다른 글

페이징 처리(1)  (0) 2020.07.11
게시글 삭제, 수정 기능 추가  (0) 2020.07.09
게시글 목록 구현  (0) 2020.07.09
controller redirect  (0) 2020.07.09
controller 구현  (0) 2020.07.08

+ Recent posts