국비교육(22-23)

93일차(1)/Spring Boot(16) : Custom Exception 활용 예제

서리/Seori 2023. 2. 20. 18:54

93일차(1)/Spring Boot(16) : Custom Exception 활용 예제


- 개인이 업로드한 음악를 재생가능한 음악 재생 리스트를 만들고 있다.
- 업로드된 mp3파일을 재생 가능하도록 설정해둠

 

 

- 음악 각각의 링크를 누르면 javascript가 실행되면서 해당 DB 데이터의 primary key를 전달하도록 설정했다.
- js에서 이 번호를 이용해서 서버에서 페이지 전환 없이 정보를 받아온다.

 

 

- @ResponseBody로 json 문자열을 가져온다.

 


- json데이터를 이 js의 data에서 사용한다. data에 들어오는 것은 object이다.
- data 안의 title, saveFileName을 사용해서 사용자의 요청에 응답할 준비를 하는 것!

 


- 이렇게 object로 변환된 값이 data 안으로 들어온다.

 


- 로그인된 아이디를 넣어주기 (이전엔 임시 데이터를 사용했다)

 


- mapper에서 id=writer인 목록만 출력하도록 했다. 본인이 업로드한 목록만 받아오도록!

 



AOP 예제

- 번호, request 정보 받아와서 사용

 


- 맨앞의 * : 리턴타입은 아무거나 다 된다는 의미!(빨간화살표)
- 이 패키지, 이 클래스 안의 check로 시작하는 모든 aspect 에 적용

- 메소드 수행 이전, 이후에 개입해서 원하는 동작을 할 수 있다.

- joinPoint 의 핵심 메소드 2개
1) getArgs() : object 배열을 가져온다.
- 메소드에 전달된 인자들 목록을 얻어내기
2) proceed() : 호출된 메소드를 쭉 진행한다.

 


- 메소드에 이런 번호와 참조값이 전달된다고 하면
args 변수 안에는 { 3, id40 } 이런 값이 들어간다고 보면 된다.
- 메소드의 매개변수에 전달된 값을 object 배열에 담아서 읽어낼 수 있다.

 


- 담긴 값을 읽어내서 id와 writer가 다르면 예외를 발생시키겠다는 뜻
- 예외를 발생시킨다(빨강) / 그대로 호출하고, 리턴된 데이터(obj)를 그대로 다시 리턴해준다.

 

 

- checkDetail() 에서 리턴하는 데이터가 obj이다.(MusicDto 타입)

 

 

- checkDelete() 에 적용하면 obj안에는 String이 들어간다.

- aspect를 사용하면 적용된 메소드에서 리턴하는 값도 조사할 수 있다.

 



** 업로드한 사람이 아닌데 파일을 재생하려고 하거나 삭제하려고 하는 경우

 


- equals() 메소드로 비교하고 RuntimeException을 발생시키기


- num으로 detail, delete 페이지를 요청했는데 writer와 id가 다를 경우에는 이렇게 exception이 출력된다.
- 의도적으로 이런 예외를 발생시킬 수 있다.

 


 

(이전에 만든 custom exception)

- 위 상황에서 발생시킬 custom exception을 만들어볼 것이다.
- 특정 exeption이 발생하면 실행순서를 이쪽으로 뛰게 만들 수 있다.


ForbiddenException 생성

package com.sy.boot07.exception;

public class ForbiddenException extends RuntimeException {
	//생성자
	public ForbiddenException(String msg) {
		super(msg);
	}
}


- RuntimeException 을 상속해서 만들고, 생성자를 만들어주기


ExceptionController에 새 exception 추가

package com.sy.boot07.exception;

import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/*
 * Spring MVC가 동작중에 특정 type의 예외가 발생하면 해당 예외를 여기서 처리할 수 있다.
 */

@ControllerAdvice
public class ExceptionController {
	
	@ExceptionHandler(ForbiddenException.class)
	public ResponseEntity<String> forbidden(ForbiddenException fe) {
		//403 에러를 발생시키기 위한 ResponseEntity 객체를 생성해서
		ResponseEntity<String> re=new ResponseEntity<>(HttpStatus.FORBIDDEN);
		//리턴하면 에러가 응답된다.
		return re;
	}
	
	//spring Framework가 동작하는 중에 NotDeleteException type의
	//예외가 발생하면 호출되는 메소드
	@ExceptionHandler(NotDeleteException.class)
	public ModelAndView notDelete(NotDeleteException nde) {//메소드의 인자로 예외객체가 전달된다.
		ModelAndView mView=new ModelAndView();
		//exception이라는 키값으로 예외 객체를 담고
		mView.addObject("exception", nde);
		//view page(/WEB-INF/views/error/info.jsp) 로 forward 이동해서 예외정보 응답하기
		mView.setViewName("error/info");
		return mView;
	}
	
	@ExceptionHandler(DeliveryException.class)
	public ModelAndView delivery(DeliveryException de) {
		ModelAndView mView=new ModelAndView();
		mView.addObject("exception", de);
		mView.addObject("info", "내년부터는 제주도도 배송가능하도록 노력하겠습니다.");
		mView.setViewName("error/delivery");
		return mView;
	}
		
	//DB관련 작업을 하다가 발생하는 모든 예외를 처리하는 컨트롤러
	@ExceptionHandler(DataAccessException.class)
	public ModelAndView dataAccess(DataAccessException dae) {
		ModelAndView mView=new ModelAndView();
		mView.addObject("exception", dae);
		mView.setViewName("error/info");
		return mView;
	}
	
}

 


- ResponseEntity<> 에다가 HttpStatus.FORBIDDEN 에러를 발생시킨다.

- 이런 custom exception을 만들어두면 예외 상황 발생시 이쪽으로 실행순서가 들어온다.
- 변수 re 에 담아서 리턴했는데, 바로 new 해서 리턴해줄 수도 있다.


MusicAspect에서


- 발생시킬 예외를 ForbiddenException 으로 수정해줌


- 403에러 발생! FORBIDDEN 은 403에러이다.
- ForbiddenException에서 의도적으로 발생시킨 에러

- 이렇게 aspect는 특정 패턴을 만들어놓고 진행 순서 사이에 자동으로 적용되도록 하는 것이다.