대외활동/SSUPOWER : 학교 내부 길찾기 및 공강 스터디룸 예약 매칭 서비스

[SpringBoot] HTTP Response with ResponseEntity

oxdjww 2023. 5. 23. 02:52
728x90
반응형

https://oxdjww.tistory.com/entry/SpringBoot-Github-Merge

 

[SpringBoot] Github Merge

https://oxdjww.tistory.com/entry/SSUPOWER-%ED%95%99%EA%B5%90-%EB%82%B4%EB%B6%80-%EA%B8%B8%EC%B0%BE%EA%B8%B0-%EB%B0%8F-%EA%B3%B5%EA%B0%95-%EC%8A%A4%ED%84%B0%EB%94%94%EB%A3%B8-%EC%98%88%EC%95%BD-%EB%A7%A4%EC%B9%AD-%EC%84%9C%EB%B9%84%EC%8A%A4-Login-Jo [Spring

oxdjww.tistory.com

Login, Join을 master에 merge했다

 

부족했던 몇 가지 기능을 더 추가하고자 코드 리팩토링을 시작했다.

1. JoinForm 에 school 추가

2. Email형식 검증

 

기존에 HTTP 상태코드를 반환하지 않고 Long value를 반환하여 프론트와 우리만의 코드를 정했다

ex ) null 반환시 중복회원 존재, -1 반환시 Entity 내 null value 존재 등

 

하지만 Restful API에 가까워지기 위해서는 HTTP 상태코드와 message를 반환해야 함을 구글링을 통해 깨달았다.

우리 팀원들끼리만 아는 토큰을 주고 받는 것은 의미가 크게 없기 때문이다.

 

그러므로, ErrorResponse를 다음과같이 설계하였다.

package com.ssupowerback.exception;

import org.springframework.http.HttpStatus;

public class ErrorResponse {
    /**
     * HTTP ErrorCode & ErrorMessage를 Client에게 전송할 수 있도록 함
     */
    private int statusCode;
    private String message;

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    // ErrorResponse 객체를 생성하여 반환하는 유틸리티 메서드
    public static ErrorResponse of(HttpStatus status, String message) {
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setStatusCode(status.value());
        errorResponse.setMessage(message);
        return errorResponse;
    }
}

 

ResponseEntity를 활용하여 Client에게 보내줄 것이다

 

ResponseEntity란?
ResponseEntity는 Spring Framework에서 제공하는 클래스로, HTTP 응답을 나타내는 래퍼 클래스이다.
일반적으로 Spring 기반의 웹 애플리케이션에서 클라이언트에게 응답을 보낼 때 사용된다.
ResponseEntity는 응답의 HTTP 상태 코드, 헤더 및 본문 데이터를 포함할 수 있다.
이를 통해 클라이언트에게 다양한 형식의 응답을 반환할 수 있다.
일반적으로 ResponseEntity는 제네릭 타입을 사용하여 반환할 데이터의 유형을 지정할 수 있다.
(JSON, XML, HTML 등의 형식)

예를 들어, 다음은 문자열 데이터를 포함하는 HTTP 200 (OK) 응답을 생성하는 방법이다

@GetMapping("/hello")
public ResponseEntity<String> sayHello() {
    String message = "Hello, world!";
    return ResponseEntity.ok(message);
}

우리의 예제에서 ResponseEntity<?> 의 ?에는 HttpStatus와 message를 담는 ErrorResponse를 Client에게 보내줄 것이다

 

그리고 case에 맞게 구분할 것이다. 

 

1. Entity에 입력된 variable들 중 null이 있는가?

@ControllerAdvice
public class ExceptionAdvisor {
    /**
     * Null variable을 입력 받았을 시 Member의 @NotBlank와 MemberController의 파라미터 앞 @Valid에 의거하여
     * MethodArgumentNotValidException 예외를 여기서 처리해줌 (Controller 내부로 들어가지 않고)
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> methodValidException(MethodArgumentNotValidException e) {
        ErrorResponse errorResponse = ErrorResponse.of(HttpStatus.BAD_REQUEST, "회원 정보를 모두 입력해주세요.");
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
}

// MemberController
public ResponseEntity<?> join(@Valid @RequestBody Member member) {

 

@Valid @ControllerAdvice, @ExceptionHandler를 통한 예외처리

이렇게 구현하면 MethodArgumentNotValidException 예외를 처리해주며 Controller 내부에서 email 유효검사 등에 접근 전에 사전처리 해줄 수 있다.

    @PostMapping("/join")
    public ResponseEntity<?> join(@Valid @RequestBody Member member) {
            if (!isValidEmail(member.getEmail())) {
                ErrorResponse errorResponse = ErrorResponse.of(HttpStatus.BAD_REQUEST, "유효하지 않은 이메일 주소입니다.");
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
            }
            else if (validateDuplicateMember(member)) {
                ErrorResponse errorResponse = ErrorResponse.of(HttpStatus.CONFLICT, "이미 등록된 회원입니다.");
                return ResponseEntity.status(HttpStatus.CONFLICT).body(errorResponse);
            } else {
                /**
                 * 회원가입 성공
                 */
                Long memberId = memberService.save(member);
                return ResponseEntity.ok(memberId);
            }
    }

그리고 각 if-elseif-else 문의 분류는..

2. 이메일 주소가 유효한가?

3. 이미 등록된 회원(이메일) 인가?

4. 아니라면 회원가입 성공

 

postman test

단순하게 코드와 메시지형태 포맷으로 전송된다.

 

react test

Front에서 테스트 결과 ErrorCode는 Status, Response data에 오류메시지가 잘 담겨서 간다!

 

정말.. 오래걸렸다..

거의 5시간을 붙잡고 있었다..

 

처음부터 RESTFUL한 API를 알았으면 좀 덜 고생했을텐데..

이런 코드 하나하나 짜면서 배운다고 생각중이다..!

 

728x90
반응형