본문 바로가기

공부/Spring Boot를 이용한 RESTful Web Services 정리

[Spring Boot] HTTP Status Code 제어, Exception Handling

HTTP Status Code 제어 


HTTP Status Code를 서버에서 클라이언트 응답할 때, 가공해서 보낼 수 있다.

 

아래의 코드는 USER를 저장하기 위해 서버에 POST 요청 코드

 

-  서버에서 자동으로 USER id를 생성 

-  Client는 생성된  USER id를 알기 위해 서버한테 재요청 해야함
 - 서버에서 응답할 때 상태 코드와, 생성된 id 값을 클라이언트에게 전송해주면 클라이언트가 재전송할 필요가 없어 네트워크 트래픽이 감소됌

 

 

예제 코드)

    @PostMapping("/users")
    public ResponseEntity<User> createUser(@RequestBody User user){ 
         User savedUser = service.save(user);

          URI location = ServletUriComponentsBuilder.fromCurrentRequest() 
                .path("/{id}") //반환 값은 가변 변수 id
                .buildAndExpand(savedUser.getId()) //저장된 user값의 id값을 지정
                .toUri(); //URI로 반환

        return ResponseEntity.created(location).build();//서버로 부터 적절한 상태 코드를 보내주는 것이 좋은 api 임
    }

 

POST로 전송결과, 상태코드는 201로 생성에 성공했음을 알수 있고, Header의 Location Value로 서버가 상태 코드와, 생성된 id를 클라이언트에게 응답으로 보내줌을 확인할 수 있다.

 

결과

 

 

// 설계할 때 안좋은 케이스 하나가 클라이언트 모든 요청을 Post로 요청, 응답 코드를 200으로 처리하는 경우로,         예외 핸들링을 조합해서 사용해야 좋은 API 할 수 있다.

 

HTTP Status Code Exception Handling


 

 

서버에서는 존재하지 않은 id로 조회했을 때, 데이터를 조회할 수는 없으나 프로그램은 문제가 없어 200으로 응답한다.

 

 

 

존재하지 않은 id일 때 예외 처리하기,@ResponseStatus 상태 코드 제어

 

    @GetMapping("/users/{id}")
    public User retreiveAllUsers(@PathVariable int id) {
        User user = service.findOne(id);

        if(user == null){ //아이디가 존재하지 않을 때 예외를 발생시킨다.
            throw  new UserNotFoundException(String.format("ID[%s] not found",id));
        }
        return user;
    }

 

@ResponseStatus 어노테이션으로 상태코드를 제어할수있다. 없으면 500에러로 출력

 

package com.example.restfulwebservice.User;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND) //not found인 404번 오류로 반환
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message); // 부모 클래스에서 전달 받은 메시지 실행
    }
}

 

 

결과!

 

 

Spring AOP Exception Handling


 AOP는 여러 객체에 공통으로 적용할 수 있는 기능을 분리해서 재사용성을 높여주는 기법이다. 공통적으로 사용하는 예외처리를 한곳으로 모아 사용 할수 있도록 Exception Handler을 구현한다.

 

- 예외 발생 시간, 오류 메시지, 오류 상세정보를 담아오는 객체 클래스 구현

package com.example.restfulwebservice.exception;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;


@Data
@AllArgsConstructor
@NoArgsConstructor


public class ExceptionResponse {
    private Date timestamp; //오류 발생 시간
    private String message; // 오류 메시지
    private String details; // 오류 상세정보
}

 

-ExceptionHandler을 구현한다.

-컨트롤러가 실행하면 자동으로 핸들러가 실행되고 클래스 안에서 예외가 발생하면 hanlerAllExceptions메서드가 실행된다.

- 클래스 별로 예외 처리를 하고 싶으면, 해당 클래스로 @ExceptionHandler 해준다.

    

package com.example.restfulwebservice.exception;

import com.example.restfulwebservice.User.UserNotFoundException;
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.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.util.Date;

@RestController
@ControllerAdvice 

public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(Exception.class) //모든 예외 처리
    public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request){
        ExceptionResponse exceptionResponsee =
                new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));

        return new ResponseEntity(exceptionResponsee, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(UserNotFoundException.class) //해당 클래스에서 예외가 발생하면
    public final ResponseEntity<Object> handleUserNotFoundExceptions(Exception ex, WebRequest request){
        ExceptionResponse exceptionResponsee =
                new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));

        return new ResponseEntity(exceptionResponsee, HttpStatus.NOT_FOUND);
    }
}

 

-  @ControllerAdvice - 모든 컨트롤러가 실행될 때 자동 실행된다.

-  ResponseEntityExceptionHandler는 Spring MVC에서 기본으로 제공되는 ExceptionHandler로 ControllerAdvice로 빈으로 등록해 모든 컨트롤러가 실행될 때 자동 실행되도록 한다.

Reference


인프런 강의 -  Spring Boot를 이용한 RESTful Web Services 개발

 

 

300x250