Skip to content

Commit

Permalink
[feat:#9] 이메일 등록, 검증
Browse files Browse the repository at this point in the history
이메일 등록 후 중복, 타입 일치하지 않은 경우 모두 확인 완료
  • Loading branch information
hyejungg committed Sep 20, 2021
1 parent d3fea81 commit 66adc06
Show file tree
Hide file tree
Showing 13 changed files with 433 additions and 0 deletions.
25 changes: 25 additions & 0 deletions ticket/src/main/java/comento/backend/ticket/config/ErrorCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package comento.backend.ticket.config;

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
public enum ErrorCode {
/**
* @see : 예외케이스 정의
*/

INVALID_VALUE(400, HttpStatus.BAD_REQUEST, "BAD REQUEST", "잘못된 요청입니다. 다시 요청해주세요."),
NO_USER(401, HttpStatus.UNAUTHORIZED,"UNAUTHORIZED", "등록되지 않은 사용자입니다"),
NO_DATA(404, HttpStatus.NOT_FOUND, "NOT FOUND ERROR", "요청할 수 없는 리소스입니다."),
VALID_USER(409, HttpStatus.CONFLICT, "CONFLICT", "이미 존재하는 사용자입니다."),
VALID_SEAT(409, HttpStatus.CONFLICT, "CONFLICT", "이미 예약된 좌석입니다."),
SERVER_ERROR(500, HttpStatus.INTERNAL_SERVER_ERROR, "INTERVAL_SERVER ERROR", "서버 에러입니다.");

private final Integer status;
private final HttpStatus httpStatus;
private final String message;
private final String reason;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package comento.backend.ticket.config;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.springframework.http.HttpStatus;

@Data
@AllArgsConstructor
@Builder
public class ErrorResponse<T> {
private Integer status;
private String message;
private String reason;
private HttpStatus httpStatus;

//공통된 Error Message를 전송할 때 사용
public static ErrorResponse res(final Integer status, final String message, final String reason, final HttpStatus httpStatus){
return ErrorResponse.builder()
.status(status)
.message(message)
.reason(reason)
.httpStatus(httpStatus)
.build();
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package comento.backend.ticket.config;

import comento.backend.ticket.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

@RestControllerAdvice //@Conroller 전역에서 발생 가능한 예외를 잡아 처리
@Slf4j
public class GlobalExceptionHandler {
private static ErrorCode errorCode;

/**
* 특정 Exception을 지정하여 별도로 처리
*/

@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public static ErrorResponse missMatchExceptionHandler(MethodArgumentTypeMismatchException e){
errorCode = ErrorCode.INVALID_VALUE;
log.error(errorCode.getStatus() + errorCode.getMessage(), e);
return ErrorResponse.res(errorCode.getStatus(), errorCode.getMessage(), errorCode.getReason(), errorCode.getHttpStatus());
}

@ExceptionHandler(IllegalStateException.class)
public static ErrorResponse illegalExceptionHandler(IllegalStateException ie){
errorCode = ErrorCode.SERVER_ERROR;
log.error(errorCode.getStatus()+ " " + errorCode.getMessage(), ie);
return ErrorResponse.res(errorCode.getStatus(), errorCode.getMessage(), errorCode.getReason(), errorCode.getHttpStatus());
}

@ExceptionHandler(RuntimeException.class)
public static ErrorResponse exceptionHandler(RuntimeException e){
switch(e.getMessage()){
case "400" :
errorCode = ErrorCode.INVALID_VALUE;
log.error(errorCode.getStatus()+ " " + errorCode.getMessage(), e);
return ErrorResponse.res(errorCode.getStatus(), errorCode.getMessage(), errorCode.getReason(), errorCode.getHttpStatus());
case "401" :
errorCode = ErrorCode.NO_USER;
log.error(errorCode.getStatus() + " " + errorCode.getMessage(), e);
return ErrorResponse.res(errorCode.getStatus(), errorCode.getMessage(), errorCode.getReason(), errorCode.getHttpStatus());
case "404" :
errorCode = ErrorCode.NO_DATA;
log.error(errorCode.getStatus()+ " " + errorCode.getMessage(), e);
return ErrorResponse.res(errorCode.getStatus(), errorCode.getMessage(), errorCode.getReason(), errorCode.getHttpStatus());
case "409" :
if (e.getClass().getSimpleName().equals("UserService")) { //호출된 곳이 UserService
errorCode = ErrorCode.VALID_USER;
log.error(errorCode.getStatus()+ " " + errorCode.getMessage(), e);
return ErrorResponse.res(errorCode.getStatus(), errorCode.getMessage(), errorCode.getReason(), errorCode.getHttpStatus());
}else{ //좌석 예약 시
errorCode = ErrorCode.VALID_SEAT;
log.error(errorCode.getStatus()+ " " + errorCode.getMessage(), e);
return ErrorResponse.res(errorCode.getStatus(), errorCode.getMessage(), errorCode.getReason(), errorCode.getHttpStatus());
}
default :
errorCode = ErrorCode.SERVER_ERROR;
log.error(errorCode.getStatus() + errorCode.getMessage(), e);
return ErrorResponse.res(errorCode.getStatus(), errorCode.getMessage(), errorCode.getReason(), errorCode.getHttpStatus());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package comento.backend.ticket.config;

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
public enum SuccessCode {

OK(200, HttpStatus.OK, "OK"),
CREATED(201, HttpStatus.CREATED, "CREATED");

private final Integer status;
private final HttpStatus httpStatus;
private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package comento.backend.ticket.config;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.springframework.http.HttpStatus;

@Data
@AllArgsConstructor
@Builder
public class SuccessResponse<T> {
private Integer status;
private String message;
private Object data;
private HttpStatus httpStatus;

//공통된 Success Message를 전송할 때 사용
public static SuccessResponse res(final Integer status, final String message, final Object data, final HttpStatus httpStatus){
return SuccessResponse.builder()
.status(status)
.message(message)
.data(data)
.httpStatus(httpStatus)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package comento.backend.ticket.controller;

import comento.backend.ticket.config.SuccessCode;
import comento.backend.ticket.config.SuccessResponse;
import comento.backend.ticket.domain.User;
import comento.backend.ticket.dto.UserDto;
import comento.backend.ticket.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class UserController {
private SuccessCode successCode;
private final UserService userService;
private static final String CREATED_MSG = "등록 성공";

@Autowired
public UserController(UserService userService) {
this.userService = userService;
}

//이메일 등록
@PostMapping("/signup")
public SuccessResponse addEmail(@Validated @RequestBody String email){
UserDto userDto = new UserDto(email);
System.out.println(userDto.toString());
User receive = userService.saveUser(userDto);

if(receive != null){
successCode = SuccessCode.CREATED;
return SuccessResponse.res(
successCode.getStatus(), successCode.getMessage(), CREATED_MSG , successCode.getHttpStatus());
}else{
throw new RuntimeException("404");
}
}


}
37 changes: 37 additions & 0 deletions ticket/src/main/java/comento/backend/ticket/domain/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package comento.backend.ticket.domain;

import lombok.Builder;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.springframework.data.annotation.CreatedDate;

import javax.persistence.*;
import java.util.Date;

@Entity
@Data
@Table(name="User")
public class User{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="user_id")
private Long id;

@Column(nullable = true)
private String email;

@Column()
@CreationTimestamp //Entity가 생성되어 저장될 때 시간이 자동 저장
@Temporal(TemporalType.TIMESTAMP)
private Date create_at;

public User(){}

@Builder
public User(long id, String email, Date create_at) {
this.id = id;
this.email = email;
this.create_at = create_at;
}
}
21 changes: 21 additions & 0 deletions ticket/src/main/java/comento/backend/ticket/dto/UserDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package comento.backend.ticket.dto;

import comento.backend.ticket.domain.User;
import lombok.Data;
import lombok.Getter;

@Getter
@Data
public class UserDto {
private String email;

public UserDto(String email) {
this.email = email;
}

public User toEntity(){
return User.builder()
.email(email)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package comento.backend.ticket.repository;

import comento.backend.ticket.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

Optional<User> findByEmail(String email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package comento.backend.ticket.service;

import comento.backend.ticket.domain.User;
import comento.backend.ticket.dto.UserDto;
import comento.backend.ticket.repository.UserRepository;
import org.springframework.stereotype.Service;

import java.util.regex.Pattern;


@Service
public class UserService {
private final UserRepository userRepository;

public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}

//이메일 등록
public User saveUser(UserDto userDto){
User user = userDto.toEntity();
if(verifyEmail(user.getEmail()))
if(checkEmailDuplicate(user.getEmail()))
throw new RuntimeException("409");
else
return userRepository.save(user);
else
throw new RuntimeException("400");
}

//이메일 검증 (이메일 형식인지 확인)
private boolean verifyEmail(String email) {
String email2 = email;
String regex = "^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$";
return Pattern.matches(regex, email2);
}

//이메일 중복 확인
private boolean checkEmailDuplicate(String email){
return userRepository.findByEmail(email).isPresent() ? true : false;
}
}
29 changes: 29 additions & 0 deletions ticket/src/main/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />

<!-- appender : log의 형태 설정, log 메세지가 출력될 대상(console/file)결정 -->
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/ticket-reservation-server.log</file>
<rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 일자별 로그파일 생성 -->
<fileNamePattern>logs/ticket-reservation-server-%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 최대 보관주기. 30일 이상된 파일은 자동으로 제거 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>

<!-- INFO 이상 level 출력 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>

<logger name="org.springframework" level="warn">
<appender-ref ref = "ROLLING_FILE"/>
</logger>
</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package comento.backend.ticket.repository;

import comento.backend.ticket.domain.User;
import comento.backend.ticket.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

//given
//when
//then

@SpringBootTest
@Transactional
public class UserRepositryTest {
private final UserRepository userRepository;

@Autowired
public UserRepositryTest(UserRepository userRepository) {
this.userRepository = userRepository;
}

@Test
public void 사용자_등록(){
//given
User user = new User();
user.setEmail("[email protected]");

//when
User result = userRepository.save(user);

//then
if(result != null)
System.out.println(result.getId());
else
System.out.println("실패");
}
}
Loading

0 comments on commit 66adc06

Please sign in to comment.