ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA & Security (예외처리)
    spring boot 2023. 5. 10. 12:28
    학습 목표

    1. @RestControllerAdvice 기능 만들어 보기
    2. 예외 처리 클래스 만들어 보기 (1단계)
    3. 예외 처리 클래스 만들어 보기 (2단계)

     

    build.gradle에 선언해주었는지 확인

    implementation 'org.springframework.boot:spring-boot-starter-validation'

     

    NotBlank 추가

     

    package com.tenco.blog.model;
    
    import java.sql.Timestamp;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.validation.constraints.NotBlank;
    
    import org.hibernate.annotations.ColumnDefault;
    import org.hibernate.annotations.CreationTimestamp;
    
    import lombok.Data;
    
    @Entity
    @Data // 주의! (Object Mapper) 파싱 처리할때 setter 반드시 있어야 한다. 
    public class User {
    	
    	@Id
    	@GeneratedValue(strategy = GenerationType.IDENTITY)
    	private int id;
    	@Column(nullable = false, length = 30)
    	private String username; 
    	
    	@NotBlank // null, "" - 빈문자열, 잡겠다 
    	@Column(nullable = false, length = 100)
    	private String password; 
    	
    	@NotBlank 
    	@Column(nullable = false, length = 50)
    	private String email; 
    	
    	@ColumnDefault("'user'") // 문자열 타입 이라고 명시는 ''(홑따옴표) 
    	private String role; // user, admin, manager 
    	
    	@CreationTimestamp // 자동 시간 입력 == now() 
    	private Timestamp createdDate;
    	
    }

     

    1. @RestControllerAdvice 기능 만들어 보기

    package com.tenco.blog.handler;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.validation.ConstraintViolationException;
    
    import org.springframework.validation.FieldError;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    
    import com.tenco.blog.dto.ExceptionFieldMessage;
    
    @RestControllerAdvice // IoC 
    public class RestExcptionHandler {
    
    	@ExceptionHandler(value = Exception.class)
    	public void exception(Exception e) {
    		System.out.println("-----------");
    		System.out.println(e.getClass().getName());
    		System.out.println(e.getMessage());
    		System.out.println("-----------");
    	}
    	
    	@ExceptionHandler(value = IllegalArgumentException.class)
    	public String illegalArgumentException(IllegalArgumentException e) {
    		
    		return "<h1>" + e.getMessage() + "</h1>";
    	}
    	
    	@ExceptionHandler(value = ConstraintViolationException.class)
    	public String constraintViolationException(ConstraintViolationException e) {
    		System.out.println("ConstraintViolationException 예외 발생");
    		return e.toString();
    	}	
    }

     

    package com.tenco.blog.dto;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class ExceptionFieldMessage {
    	
    	private String field;
    	private String message;
    }

     

     

    전체 코드

    package com.tenco.blog.handler;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.validation.ConstraintViolationException;
    
    import org.springframework.validation.FieldError;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    
    import com.tenco.blog.dto.ExceptionFieldMessage;
    
    @RestControllerAdvice // IoC 
    public class RestExcptionHandler {
    
    	@ExceptionHandler(value = Exception.class)
    	public void exception(Exception e) {
    		System.out.println("-----------");
    		System.out.println(e.getClass().getName());
    		System.out.println(e.getMessage());
    		System.out.println("-----------");
    	}
    	
    	@ExceptionHandler(value = IllegalArgumentException.class)
    	public String illegalArgumentException(IllegalArgumentException e) {
    		return "<h1>" + e.getMessage() + "</h1>";
    	}
    	
    	@ExceptionHandler(value = ConstraintViolationException.class)
    	public String constraintViolationException(ConstraintViolationException e) {
    		System.out.println("ConstraintViolationException 예외 발생");
    		return e.toString();
    	}
    	
    	
    	@ExceptionHandler(value = MethodArgumentNotValidException.class)
    	public List<ExceptionFieldMessage> methodArgumentNotValidException(MethodArgumentNotValidException e) {
    		List<ExceptionFieldMessage> errorList = new ArrayList<>();
    		e.getBindingResult().getAllErrors().forEach(action -> {
    			FieldError fieldError = (FieldError)action;
    			String fieldName = fieldError.getField();
    			String message = fieldError.getDefaultMessage();
    			
    			ExceptionFieldMessage exceptionFieldMessage = 
    					ExceptionFieldMessage.builder()
    			.field(fieldName)
    			.message(message).build();
    			errorList.add(exceptionFieldMessage);
    		});
    		return errorList;
    	}
    }

     

     

    코드 수정

    package com.tenco.blog.dto;
    
    import java.util.List;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public class ApiErrorResponse {
    	
    	private int statusCode; 
    	private String code; 
    	private String message; 
    	private String resultCode;
    	private List<ExceptionFieldMessage> exceptionFieldMessages;
    }

     

     

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ApiErrorResponse methodArgumentNotValidException(MethodArgumentNotValidException e) {
    	
    	List<ExceptionFieldMessage> errorList = new ArrayList<>();
    	e.getBindingResult().getAllErrors().forEach(action -> {
    		FieldError fieldError = (FieldError)action;
    		String fieldName = fieldError.getField();
    		String message = fieldError.getDefaultMessage();
    		
    		ExceptionFieldMessage exceptionFieldMessage = 
    				ExceptionFieldMessage.builder()
    		.field(fieldName)
    		.message(message).build();
    		errorList.add(exceptionFieldMessage);
    	});
    	return ApiErrorResponse.builder()
    			.statusCode(HttpStatus.BAD_REQUEST.value())
    			.code("-1")
    			.resultCode("fail")
    			.message("잘못된 요청입니다")
    			.exceptionFieldMessages(errorList)
    			.build();
    }

     

Designed by Tistory.