Loading...

프로젝트/에브리타임 / / 2022. 4. 19. 16:37

[프로젝트] 인터셉터로 에러 처리 시 파일 리턴하기

반응형

 

인터셉터를 이용해 /s가 붙은 주소의 요청을 받으면 인증 체크를 손쉽게 했었다.

 

// CustomApiException
package site.metacoding.everytimeclone.handler.ex;

public class CustomApiException extends RuntimeException {
    public CustomApiException(String message) {
        super(message);
    }
}
// CustomException
package site.metacoding.everytimeclone.handler.ex;

public class CustomException extends RuntimeException {
    public CustomException(String message) {
        super(message);
    }
}
// GlobalExceptionHandler
package site.metacoding.everytimeclone.handler;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import site.metacoding.everytimeclone.handler.ex.CustomApiException;
import site.metacoding.everytimeclone.handler.ex.CustomException;
import site.metacoding.everytimeclone.util.Script;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(CustomApiException.class)
    public ResponseEntity<?> apiException(Exception e) { // fetch 요청시 발동
        return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(CustomException.class)
    public String htmlException(Exception e) { // 일반적인 요청 Get(a태그), Post(form태그) 요청
        return Script.back(e.getMessage());
    }
}

 

/s가 붙은 주소 요청이 들어왔을 때 SessionInterceptor에서 RuntimeException 오류를 터뜨렸었는데

세션이 존재하지 않는 유저가 들어오면 로그인 페이지를 리턴해주고 싶다.

 

GlobalExceptionHandler에서 페이지 리턴을 처리할 핸들러를 하나 더 만들어주면 된다.

 

// CustomPageException
package site.metacoding.everytimeclone.handler.ex;

public class CustomPageException extends RuntimeException {
    public CustomPageException(String message) {
        super(message);
    }
}

 

CustomPageException을 처리하는 핸들러를 만드려고 보니

이 Global 핸들러는 @RestControllerAdvice라서 페이지를 리턴해줄 수 없다.

 

@ControllerAdvice로 변경해준 뒤 CustomException 핸들러에만

데이터를 리턴해줄 수 있게 @ResponseBody를 붙여주자.

 

ResponseEntity를 리턴하는 CustomApiException은

ResponseEntity가 @ResponseBody를 붙이지 않아도 알아서 데이터를 리턴해주기 때문에 그냥 놔둬도 된다.

 

package site.metacoding.everytimeclone.handler;

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.bind.annotation.ResponseBody;

import site.metacoding.everytimeclone.handler.ex.CustomApiException;
import site.metacoding.everytimeclone.handler.ex.CustomException;
import site.metacoding.everytimeclone.handler.ex.CustomPageException;
import site.metacoding.everytimeclone.util.Script;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(CustomApiException.class)
    public ResponseEntity<?> apiException(Exception e) { // fetch 요청시 발동
        return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(CustomException.class)
    public @ResponseBody String htmlException(Exception e) { // 일반적인 요청 Get(a태그), Post(form태그) 요청
        return Script.back(e.getMessage());
    }

    @ExceptionHandler(CustomPageException.class)
    public String htmlPageException(Exception e) { // 세션이 없을 때 htmlPageException 터뜨리기
        return "redirect:/user/login-form";
    }
}

 

이제 세션 인터셉터에서 CustomPageException을 터뜨려주면

인증이 필요한 페이지에 로그인을 하지 않은 유저가 들어왔을 때

로그인 페이지를 리턴해줄 것이다.

 

package site.metacoding.everytimeclone.config.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;

import site.metacoding.everytimeclone.domain.user.User;
import site.metacoding.everytimeclone.handler.ex.CustomPageException;

public class SessionInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        HttpSession session = request.getSession();
        User principal = (User) session.getAttribute("principal");

        if (principal == null) {
            throw new CustomPageException("인증에 실패하였습니다.");
        } else {
            return true;
        }
    }
}

 

반응형