5 Commits 0a1984b76f ... 8a2664ea00

Author SHA1 Message Date
  sangwonlee 8a2664ea00 기타 수정 3 years ago
  sangwonlee 05ac10db83 Merge branch 'dbs333' 3 years ago
  sangwonlee e2a3c3241c DTO에 @noArgsConstructor @AllArgsConstructor 제거 3 years ago
  sangwonlee c673474511 Merge branch 'master' of http://wcollector.idatabank.com:5230/dbs333/RealWorld into dbs333 3 years ago
  sangwonlee 50c14ea120 밸리데이션 공통 에러 처리 베이스 코드 3 years ago

+ 6 - 0
realworld/pom.xml

@@ -79,6 +79,12 @@
 		</dependency>
 		</dependency>
 		 -->
 		 -->
 
 
+		<!-- validation -->
+		 <dependency> 
+			<groupId>org.springframework.boot</groupId> 
+			<artifactId>spring-boot-starter-validation</artifactId> 
+		</dependency>
+
 
 
 		<dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<groupId>org.springframework.boot</groupId>

+ 4 - 3
realworld/src/main/java/com/dbs/realworld/controller/UserController.java

@@ -3,6 +3,7 @@ package com.dbs.realworld.controller;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 import javax.servlet.http.HttpSession;
+import javax.validation.Valid;
 
 
 import com.dbs.realworld.common.Views;
 import com.dbs.realworld.common.Views;
 import com.dbs.realworld.dto.FollowDTO;
 import com.dbs.realworld.dto.FollowDTO;
@@ -48,7 +49,7 @@ public class UserController {
 
 
     // 회원가입 요청
     // 회원가입 요청
     @PostMapping("/signup")
     @PostMapping("/signup")
-    public String processSignupForm(HttpServletRequest request, @ModelAttribute("userDTO") UserDTO userDTO, ModelMap model) {
+    public String processSignupForm(HttpServletRequest request, @Valid @ModelAttribute("userDTO") UserDTO userDTO, ModelMap model) {
         try {
         try {
             this.userService.register(userDTO);
             this.userService.register(userDTO);
         } catch (RuntimeException e) {
         } catch (RuntimeException e) {
@@ -112,7 +113,7 @@ public class UserController {
 
 
     // 사용자 팔로우
     // 사용자 팔로우
     @PostMapping("/follow")
     @PostMapping("/follow")
-    public ResponseEntity follow(HttpServletRequest request, @RequestBody FollowDTO followDTO) {
+    public ResponseEntity follow(HttpServletRequest request, @RequestBody @Valid FollowDTO followDTO) {
         final int userId = (int) request.getSession().getAttribute("ssId");
         final int userId = (int) request.getSession().getAttribute("ssId");
         if (userId != followDTO.getFromUser()) {
         if (userId != followDTO.getFromUser()) {
             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("권한이 없습니다");
             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("권한이 없습니다");
@@ -124,7 +125,7 @@ public class UserController {
 
 
     // 사용자 언팔로우
     // 사용자 언팔로우
     @DeleteMapping("/unfollow")
     @DeleteMapping("/unfollow")
-    public ResponseEntity unfollow(HttpServletRequest request, @RequestBody FollowDTO followDTO) {
+    public ResponseEntity unfollow(HttpServletRequest request, @RequestBody @Valid FollowDTO followDTO) {
         final int userId = (int) request.getSession().getAttribute("ssId");
         final int userId = (int) request.getSession().getAttribute("ssId");
         if (userId != followDTO.getFromUser()) {
         if (userId != followDTO.getFromUser()) {
             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("권한이 없습니다");
             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("권한이 없습니다");

+ 0 - 4
realworld/src/main/java/com/dbs/realworld/dto/ArticleDTO.java

@@ -1,16 +1,12 @@
 package com.dbs.realworld.dto;
 package com.dbs.realworld.dto;
 
 
-import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.Data;
-import lombok.NoArgsConstructor;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.List;
 
 
 
 
 @Data
 @Data
-@NoArgsConstructor
-@AllArgsConstructor
 public class ArticleDTO {
 public class ArticleDTO {
     private int id;
     private int id;
     private String title;
     private String title;

+ 9 - 0
realworld/src/main/java/com/dbs/realworld/dto/FollowDTO.java

@@ -2,11 +2,20 @@ package com.dbs.realworld.dto;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 
 
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.PositiveOrZero;
+
 import lombok.Data;
 import lombok.Data;
 
 
 @Data
 @Data
 public class FollowDTO {
 public class FollowDTO {
+    @NotNull
+    @PositiveOrZero(message = "올바른 사용자가 아닙니다.")
     private int fromUser;
     private int fromUser;
+
+    @NotNull
+    @PositiveOrZero(message = "올바른 사용자가 아닙니다.")
     private int toUser;
     private int toUser;
+
     private LocalDateTime created;
     private LocalDateTime created;
 }
 }

+ 7 - 2
realworld/src/main/java/com/dbs/realworld/dto/UserDTO.java

@@ -2,16 +2,21 @@ package com.dbs.realworld.dto;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 
 
+import javax.validation.constraints.Email;
+
 import lombok.*;
 import lombok.*;
 
 
 @Data
 @Data
-@NoArgsConstructor
-@AllArgsConstructor
 public class UserDTO {
 public class UserDTO {
     private int id;
     private int id;
+
     private String username;
     private String username;
+
+    @Email
     private String email;
     private String email;
+
     private String password;
     private String password;
+    
     private String shortBio;
     private String shortBio;
     private LocalDateTime created;
     private LocalDateTime created;
     private LocalDateTime updated;
     private LocalDateTime updated;

+ 22 - 0
realworld/src/main/java/com/dbs/realworld/exception/ErrorCode.java

@@ -0,0 +1,22 @@
+package com.dbs.realworld.exception;
+
+
+public class ErrorCode {
+
+    private String code;
+
+    private String description;
+
+    public ErrorCode(String code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}

+ 17 - 0
realworld/src/main/java/com/dbs/realworld/exception/ErrorCodeMap.java

@@ -0,0 +1,17 @@
+package com.dbs.realworld.exception;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ErrorCodeMap {
+    private static Map<String, ErrorCode> errorCodeMap = new HashMap<>() {{
+        put("NOT_NULL", new ErrorCode("ERROR_CODE_0001", "필수값이 누락되었습니다."));
+        put("MIN_VALUE", new ErrorCode("ERROR_CODE_0002", "최소값보다 커야 합니다."));
+        put("EMAIL", new ErrorCode("ERROR_CODE_0003", "이메일 형식만 입력 가능합니다."));
+        put("PositiveOrZero", new ErrorCode("ERROR_CODE_0004", "0 이상의 수만 가능합니다."));
+    }};
+
+    public static ErrorCode getByResultCode(String resultCode) {
+        return errorCodeMap.get(resultCode);
+    }
+}

+ 23 - 0
realworld/src/main/java/com/dbs/realworld/exception/ErrorResponse.java

@@ -0,0 +1,23 @@
+package com.dbs.realworld.exception;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter 
+@Setter
+public class ErrorResponse {
+    private String code = "";
+    private String description = "";
+    private String detail = "";
+
+    public ErrorResponse(String detail) {
+        this.detail = detail;
+    }
+
+    public ErrorResponse(ErrorCode errorCode, String detail) {
+        this(detail);
+        this.code = errorCode.getCode();
+        this.description = errorCode.getDescription();
+    }
+}

+ 43 - 0
realworld/src/main/java/com/dbs/realworld/exception/ExceptionController.java

@@ -0,0 +1,43 @@
+package com.dbs.realworld.exception;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @ControllerAdvice 전역적으로 예외를 핸들링
+ */
+@Slf4j
+@ControllerAdvice
+public class ExceptionController {
+    
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    public ResponseEntity<ErrorResponse> processMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
+        ErrorResponse errorResponse = createErrorResponse(e.getBindingResult());
+        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
+    }
+
+    private ErrorResponse createErrorResponse(BindingResult bindingResult) {
+        ErrorCode errorCode = null; // code, description
+        String detail = null;
+
+        if (bindingResult.hasErrors()) {
+            // DTO에 설정한 메시지 값
+            detail = bindingResult.getFieldError().getDefaultMessage();
+            // DTO에 설정한 유효성 어노테이션명) NotNull, Min, Email...
+            String bindResultCode = bindingResult.getFieldError().getCode();
+            errorCode = ErrorCodeMap.getByResultCode(bindResultCode);
+        } else {
+            log.warn("bindingResult error 발생 없이 MethodArgumentNotValidException 발생... 에러 재현 필요");
+        }
+
+        return (errorCode == null) ? new ErrorResponse(detail) : new ErrorResponse(errorCode, detail);
+    }
+}