2 분 소요

Building REST API with Spring Boot (5)

/ HTTP 에러코드 / @ControllerAdvice / @ExceptionHandler /

에러코드 정리

HTTP ERROR CODE DESCRIPTION
200 에러없이 성공적으로 페이지를 불러오거나 데이터를 전송
400 Bad Request로써, 요청 실패-문법상 오류가 있어서 서버가 요청 사항을 이해하지 못함
404 Not Found, 문서를 찾을 수 없음->클라이언트가 요청한 문서를 찾지 못한 경우에 발생함 (URL을 잘 살펴보기)
405 Method not allowed, 메소드 허용 안됨-> Request 라인에 명시된 메소드를 수행하기 위한 해당 자원의 이용이 허용되지 않았을 경우 발생함.    (페이지는 존재하나, 그걸 못보게 막거나 리소스를 허용안함)
415 지원되지 않는 형식으로 클라이언트가 요청을 해서 서버가 요청에 대한 승인을 거부한 오류를 의미한다.(ContentType,Content Encoding 데이터를 확인할 필요가 있다.)
500 서버 내부 오류는 웹 서버가 요청사항을 수행할 수 없을 경우에 발생함
505 HTTP Version Not Supported
  • 참고 : https://articles09.tistory.com/5

Implementing Exception Handlin

  • 현재 user가 12까지 있지 않은데 이런 경우 문서에서 찾을 수 없는 경우라 500이 아닌 404 오류가 나와야 한다.

UserDaoService.java

public User findOne(int id) {  
	Predicate<? super User> predicate = user -> user.getId().equals(id);  
	return users.stream().filter(predicate).findFirst().get();  
}
  • get() 부분을 orElse(null) 로 변경해주면 된다.
  • 하지만 이것도 일종의 성공이라 200 이 나온다.

before UserResource.java

// GET /users  
@GetMapping("/users/{id}")  
public User retrieveUser(@PathVariable int id) {  
	return service.findOne(id);  
}

after UserResource.java

// GET /users  
@GetMapping("/users/{id}")  
public User retrieveUser(@PathVariable int id) {  
	User user = service.findOne(id);  
  
	if(user==null)  
			throw new UserNotFoundException("id : " + id);  
		  
		return user;  
}
  • 이전에 리턴으로 id 값만 줬던걸 orElse를 통해 null 값이 나오면 id 값을 보여준다.
  • UserNotFoundException 을 통해 메세지 전달.

UserNotFoundException.java

package com.in28minutes.rest.webservices.restfulwebservices.user;  
  
import org.springframework.http.HttpStatus;  
import org.springframework.web.bind.annotation.ResponseStatus;  
  
@ResponseStatus(code = HttpStatus.NOT_FOUND)  
public class UserNotFoundException extends RuntimeException {  
	public UserNotFoundException(String message) {  
		super(message);  
	}  
}
  • id 도 12로 잘 나오고 404 도 정상적으로 출력

Implementing Generic Exception Handling for all Resources

Custom structre for exception response

ErrorDetails.java

import java.time.LocalDateTime;  
public class ErrorDetails {  
	private LocalDateTime timestamp;  
	private String message;  
	private String details;  
public ErrorDetails(LocalDateTime timestamp, String message, String details) {  
	super();  
	this.timestamp = timestamp;  
	this.message = message;  
	this.details = details;  
}  
public LocalDateTime getTimestamp() {  
	return timestamp;  
}  
public String getMessage() {  
	return message;  
}  
public String getDetails() {  
	return details;  
}  
  
}

CustomizedResponseEntityExceptionHandler.java

@ControllerAdvice  
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler{  
@ExceptionHandler(Exception.class)  
public final ResponseEntity<ErrorDetails> handleAllExceptions(Exception ex, WebRequest request) throws Exception {  
	ErrorDetails errorDetails = new ErrorDetails(LocalDateTime.now(),  
	ex.getMessage(), request.getDescription(false));  
	  
	return new ResponseEntity<ErrorDetails>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);  
}  
@ExceptionHandler(UserNotFoundException.class)  
public final ResponseEntity<ErrorDetails> handleUserNotFoundException(Exception ex, WebRequest request) throws Exception {  
	ErrorDetails errorDetails = new ErrorDetails(LocalDateTime.now(),  
	ex.getMessage(), request.getDescription(false));  
	return new ResponseEntity<ErrorDetails>(errorDetails, HttpStatus.NOT_FOUND);  
	  
}  
}
  • ResponseEntityExceptionHandler
    • This is the standard class which handles all spring MVC raised exceptions and it returns formatted error details
  • @ControllerAdvice
    • Specialization of @Component for classes that declare @ExceptionHandler@InitBinder, or @ModelAttribute methods to be shared across multiple @Controller classes.
  • 오버라이딩을 통해 ResponseEntityExceptionHandler 을 extends를 통해 갖고 옴
  • @ExceptionHandler(Exception.class) 는 모든 예외를 갖고 옴
  • 유저 아이디가 없을 경우 실행되게 UserNotFoundException를 주입
- 404 오류 번호, 아이디 값이 null일 때 메세지 및  ErrorDetails 클래스에서 지정해두었던 정보들 확인

댓글남기기