SPRING/WEBSERVICE

[Restuful 학습] - Exception 핸들링을 통한 HTTP STATUS Code 관리법 (ControllerAdvice 사용)

JUMP개발자 2020. 8. 4. 00:07

 

package com.example.demo.exception;

@RestController
@ControllerAdvice
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler{

	
	@ExceptionHandler(Exception.class)
	public final ResponseEntity<Object> handleAllExcetipon(Exception ex, WebRequest request) {
		System.out.println("Exception...");
		ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
		return new ResponseEntity(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
	}
	
	@ExceptionHandler(UserNotFoundException.class)
	public final ResponseEntity<Object> handleUserNotFoundException(Exception ex, WebRequest request) {
		ExceptionResponse exceptionResponse =
				new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
		
		return new ResponseEntity(exceptionResponse, HttpStatus.NOT_FOUND);
	}

	@Override
	protected ResponseEntity<Object> handleMethodArgumentNotValid(
			MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
		ExceptionResponse exceptionResponse =
				new ExceptionResponse(new Date(), "Valid Exception", ex.getBindingResult().toString());

		return new ResponseEntity(exceptionResponse, HttpStatus.BAD_REQUEST);
	}

}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExceptionResponse {

	private Date timestamp;
	private String message;
	private String details;
	
}
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

// HTTP Status code
// 2xx -> OK
// 4xx -> Client
// 5xx -> Server


@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {

	public UserNotFoundException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

}​
package com.example.demo.user;

import java.net.URI;
import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.validation.Valid;

@RestController
public class UserController {

	private UserDaoService service;
	
	public UserController(UserDaoService service) {
		this.service = service;
	}

	// GET /users/1 or /users/10 -> String 
	@GetMapping("/users/{id}")
	public User retrieveUser(@PathVariable int id) {
		User user =service.findOne(id);
		if (user == null) {
			throw new UserNotFoundException(String.format("ID[%s] not found", id));
		}
		
		return user;
	}
	
}

 

위 소스에서는 UserNotFoundException을 정의하고, user가 null일 때 해당 Exception 을 리턴하는 형식으로 예외처리를 하고 있다. 

ResponseEntityExceptionHandler를 상속받은  CustomizedResponseEntityExceptionHandler에서 해당 Exception 객체를 리턴하는방식이다.

 

@ExceptionHandler

@ExceptionHandler같은 경우는 Controller 단에서 발생하는 예외를 잡아서 처리해주는 기능을 한다.

위와 같이 @ExceptionHandler(UserNotFoundException.class)로 정의했을 때는 UserNotFOundException이 발생하면 해당 메서드가 호출 된다.

 

@ControllerAdvice

@ControllerAdvice는 @Controller, @RestController에서 발생하는 예외를 핸들링 할 수 있게 해주는 역할을 한다.