취뽀몽

[Spring] 프로젝트 리팩토링 1 본문

spring

[Spring] 프로젝트 리팩토링 1

허몽구 2023. 3. 25. 00:30

구글 솔루션 챌린지에 제출한 프로젝트이다.

이 프로젝트는 바코드를 찍으면 해당 상품의 분리수거 방법을 알려주는 어플이다.

혼자 데이터베이스부터 배포까지 하다보니 시간이 부족했어서 코드의 부족함도 눈에 너무 보여서 리팩토링을 진행하게 되었다.

리팩토링 첫 번째 포스팅은 User 관련 코드이다.

 

1. Entity

import lombok.*;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name="User")
@AllArgsConstructor
@Builder
public class User extends BaseTimeEntity {

    @Id
    @Column(name="user_id", unique = true)
    private String id; // 아이디

    @Column(name = "user_pw", unique = true)
    private String password; // 비밀번호

    @Column(name = "user_checkpw")
    private String checkpassword; // 비밀번호 확인

    @Column(name = "user_nickname", unique = true, length = 20)
    private String nickname; // 닉네임

    private String date; // 분리수거 버리는 날 지정

}

 

2. UserDto

import com.barcode.solution_challenge_7_back.domain.User;
import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserDto {
    private String id; // 유저 아이디
    private String password; // 유저 비밀번호
    private String checkpassword; // 비밀번호 확인
    private String nickname; // 유저 닉네임
    private String date; // 쓰레기 버리는 날

    public User toEntity(){
        return User.builder()
                .id(id)
                .password(password)
                .checkpassword(checkpassword)
                .nickname(nickname)
                .date(date)
                .build();
    }
}

 

3. LoginRequest

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Getter
public final class LoginRequest { // 로그인 요정
    private String id;
    private String password;
}

 

4. UserDuplicatedException (중복 Exception)

public class UserDuplicatedException extends RuntimeException {
    public UserDuplicatedException(String message) {
        super(message);
    }
}

 

5. UserPasswordMismatchException (비밀번호 오류 Exception)

public class UserPasswordMismatchException extends Exception {
    public UserPasswordMismatchException(String message) {
        super(message);
    }
}

 

6. UserRepository

import com.barcode.solution_challenge_7_back.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, String> {

    Optional<User> findById(String id);

    Optional<User> findByNickname(String nickname);
}

 

7. UserService

import com.barcode.solution_challenge_7_back.domain.User;
import com.barcode.solution_challenge_7_back.domain.dto.UserDto;
import com.barcode.solution_challenge_7_back.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;

@Service
@Transactional
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;


    public void save(UserDto userDto) {
        userDto.setPassword(passwordEncoder.encode(userDto.getPassword()));
        userRepository.save(userDto.toEntity());
    }

    public String login(String id, String password){ // 로그인
        Optional<User> user = userRepository.findById(id);
        if(user.isPresent() && passwordEncoder.matches(password, user.get().getPassword())){
            return "true";
        }
        else{
            return "false";
        }
    }

    public boolean checkLogin(String id, String password) {
        Optional<User> user = userRepository.findById(id);
        if(!user.isPresent()){
            return false;
        }
        return passwordEncoder.matches(password, user.get().getPassword());
    }

    public boolean checkDuplicateNickname(String username) {
        return userRepository.findByNickname(username).isPresent();
    }

    public boolean checkDuplicateId(String id){
        return userRepository.findById(id).isPresent();
    }
}

 

8. Controller

import com.barcode.solution_challenge_7_back.domain.User;
import com.barcode.solution_challenge_7_back.domain.dto.UserDto;
import com.barcode.solution_challenge_7_back.domain.request.LoginRequest;
import com.barcode.solution_challenge_7_back.exception.UserPasswordMismatchException;
import com.barcode.solution_challenge_7_back.repository.UserRepository;
import com.barcode.solution_challenge_7_back.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;

@RestController
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;
    private final UserRepository userRepository;

    @PostMapping("/users/new-user") // 회원가입
    public ResponseEntity<String> join(@RequestBody UserDto userDto) throws UserPasswordMismatchException {
        if (!userDto.getPassword().equals(userDto.getCheckpassword())) {
            throw new UserPasswordMismatchException("패스워드가 일치하지 않습니다.");
        }
        userService.save(userDto);
        return ResponseEntity.ok("join success");
    }

    @PostMapping("/login") // 로그인
    public ResponseEntity<Boolean> login(@RequestBody LoginRequest request) {
        boolean isAuthenticated = userService.checkLogin(request.getId(), request.getPassword());
        return isAuthenticated ? ResponseEntity.ok(true) : ResponseEntity.badRequest().body(false);
    }

    @GetMapping("/checkDuplicateId/{id}") // 아이디 중복 확인
    public boolean checkDuplicateId(@PathVariable String id) {
        return userService.checkDuplicateId(id);
    } // 중복이면 true, 중복 아니면 false

    @GetMapping("/checkDuplicateNickname/{nickname}")
    public boolean checkDuplicateNickname(@PathVariable String nickname) {
        return userService.checkDuplicateNickname(nickname);
    }

    @GetMapping("/user/{userId}/day")
    public ResponseEntity<String> getUserCustomDay(@PathVariable String userId) {
        Optional<User> optionalUser = userRepository.findById(userId);
        if (optionalUser.isPresent()) {
            User user = optionalUser.get();
            String date = user.getDate();
            if (date != null && !date.isEmpty()) {
                return ResponseEntity.ok(date);
            } else {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body("Custom day not found for user " + userId);
            }
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body("User not found with id " + userId);
        }

    }
}

 

9. SecurityConfig

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors().disable()
                .csrf().disable()
                .httpBasic().disable();
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

 

코드 전체는 

 

GitHub - GDSC-SKHU/Solution-Challenge-7team-Backend: 솔루션챌린지 7팀 백엔드

솔루션챌린지 7팀 백엔드. Contribute to GDSC-SKHU/Solution-Challenge-7team-Backend development by creating an account on GitHub.

github.com

 

에서 확인할 수 있다.

 

리팩토링한 코드는 다음과 같다.

 

1. Entity

import lombok.*;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name="User")
public class User {

    @Id
    @Column(name="user_id", unique = true)
    private String id; // 아이디

    @Column(name = "user_pw", unique = true)
    private String password; // 비밀번호

    @Column(name = "user_nickname", unique = true, length = 20)
    private String nickname; // 닉네임

    private String date; // 분리수거 버리는 날 지정

    @Builder
    public User(String id, String password, String nickname, String date){
        this.id = id;
        this.password = password;
        this.nickname = nickname;
        this.date = date;
    }
}

@Builder를 클래스 위에 선언한다기 보다는, 클래스 내부에 직접 정의한다든가

@NoArgsConstructor는 (access = AccessLevel.PROTECTED)로 설정해둔다든가,

조건에 맞게 정리해줬다.

 

2. UserDto

import com.barcode.solution_challenge_7_back.domain.User;
import lombok.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class UserDto {

    @NotNull(message = "아이디는 필수 입력 값입니다.")
    private String id; // 유저 아이디

    @NotBlank(message = "비밀번호는 필수 입력 값입니다.")
    @Pattern(regexp = "(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\\W)(?=\\S+$).{8,16}", message = "비밀번호는 8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.")
    private String password; // 유저 비밀번호

    @NotBlank
    @Pattern(regexp = "^[가-힣a-zA-Z]{2,10}$", message = "닉네임 형식에 맞지 않습니다.")
    private String nickname; // 유저 닉네임

    @NotBlank(message = "쓰레기 버리는 날은 필수 입력 값입니다.")
    private String date; // 쓰레기 버리는 날

    @Builder
    public UserDto(String id, String password, String nickname, String date){
        this.id = id;
        this.password = password;
        this.nickname = nickname;
        this.date = date;
    }
}

validation을 사용하여 메세지를 작성해줬다.

 

3. ApiResponseDto

import com.barcode.solution_challenge_7_back.status.ErrorStatus;
import com.barcode.solution_challenge_7_back.status.SuccessStatus;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ApiResponseDto<T> {

    private final int code;
    private final String message;
    private T data;

    public static ApiResponseDto success(SuccessStatus successStatus) {
        return new ApiResponseDto<>(successStatus.getHttpStatus().value(), successStatus.getMessage());
    }

    public static <T> ApiResponseDto<T> success(SuccessStatus successStatus, T data) {
        return new ApiResponseDto<T>(successStatus.getHttpStatus().value(), successStatus.getMessage(), data);
    }

    public static ApiResponseDto error(ErrorStatus errorStatus) {
        return new ApiResponseDto<>(errorStatus.getHttpStatus().value(), errorStatus.getMessage());
    }
}

클라이언트에게 일관된 응답을 보내기 위해 ApiResponseDto를 사용했다.

success일 때와 error일 때 모두를 만들어줬다.

 

4. LoginRequest

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public final class LoginRequest { // 로그인 요정
    private String id;
    private String password;
}

 

 

5. SignupRequest

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class SignupRequest { // 회원가입 요청
    private String id;

    private String password;

    private String nickname;

    private String date;
}

회원가입을 userDto로 받지 않고 SignupRequest를 사용했다.

 

6. LoginResponse

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class LoginResponse {
    private String id;

    public static LoginResponse of(String id){
        return new LoginResponse(id);
    }
}

로그인 응답을 생성해줬다. id만 리턴할 수 있도록 매개변수는 id만 받아줬다.

 

7. SignupReponse

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class SignupResponse {

    private String userId;
    private String nickname;
    private String date;

    public static SignupResponse of(String userId, String nickname, String date) {
        return new SignupResponse(userId, nickname, date);
    }
}

회원가입을 했을 때는 아이디와 닉네임, 분리수거 날짜를 리턴하도록 Response를 생성했다.

 

8. DataResponse

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class DateResponse {
    private String date;

    public static DateResponse of(String date){

        return new DateResponse(date);
    }
}

회원가입 시 지정했던 날짜를 리턴하는 Response를 생성했다.

 

9. UserService

import com.barcode.solution_challenge_7_back.domain.User;
import com.barcode.solution_challenge_7_back.domain.dto.UserDto;
import com.barcode.solution_challenge_7_back.domain.request.SignupRequest;
import com.barcode.solution_challenge_7_back.domain.response.SignupResponse;
import com.barcode.solution_challenge_7_back.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    @Transactional
    public SignupResponse save(SignupRequest request){
        User user = User.builder()
                .id(request.getId())
                .password(passwordEncoder.encode(request.getPassword()))
                .nickname(request.getNickname())
                .date(request.getDate())
                .build();

        userRepository.save(user);

        return SignupResponse.from(user.getId(), user.getNickname(), user.getDate());
    }

    public boolean checkLogin(String id, String password) {
        Optional<User> user = userRepository.findById(id);
        if(!user.isPresent()){
            return false;
        }
        return passwordEncoder.matches(password, user.get().getPassword());
    }

    public boolean checkDuplicateNickname(String username) {
        return !userRepository.findByNickname(username).isPresent();
    }

    public boolean checkDuplicateId(String id){
        return !userRepository.findById(id).isPresent();
    }
}

- 회원가입

회원가입 시 SingupResponse를 리턴하도록 로직을 수정했다. 

빌더 패턴을 사용하여 아이디, 비밀번호, 닉네임, 날짜를 생성해줬다.

레포지토리에 저장한 후, SingupResponse에 만들었던 from 메소드를 리턴하도록 한다.

 

- 로그인 확인

레포지토리에서 아이디를 찾아와서, 유저가 존재하지 않으면 false를 리턴하고 유저가 존재한다면 비밀번호가 맞는지 확인하여 boolean 값을 리턴한다.

 

- 닉네임 중복 확인

레포지토리에서 닉네임을 가져온 후, 존재한다면 false(중복 x를 의미)를 리턴한다.

 

- 아이디 중복 확인

레포지토리에서 아이디를 가져온 후, 존재한다면 false(중복 x를 의미)를 리턴한다.

 

10. SuccesStatus

import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;

@Getter
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public enum SuccessStatus {

    SIGNUP_SUCCESS(HttpStatus.CREATED, "회원가입이 완료되었습니다."),

    CREATE_ID_SUCCESS(HttpStatus.OK, "사용 가능한 아이디입니다."),

    CREATE_NICKNAME_SUCCESS(HttpStatus.OK, "사용 가능한 닉네임입니다."),


    LOGIN_SUCCESS(HttpStatus.OK, "로그인 성공!"),

    CERTIFICATION_SUCCESS(HttpStatus.OK, "유저 인증 성공"),

    BRING_DATE_SUCCESS(HttpStatus.OK, "사용자 지정 요일 가져오기 성공")
    ;

    private final HttpStatus httpStatus;
    private final String message;
}

성공적으로 요청이 완료되었을 때의 메세지를 저장하는 SuccessStatus이다.

 

11. ErrorStatus

@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public enum ErrorStatus {

    /*
    BAD_REQUEST
     */
    VALIDATION_EXCEPTION(HttpStatus.BAD_REQUEST, "잘못된 요청입니다."),
    USER_CERTIFICATION_FAILED(HttpStatus.UNAUTHORIZED, "해당 아이디나 비밀번호를 가진 유저가 존재하지 않습니다."),
    USER_NOT_JOIN(HttpStatus.FORBIDDEN, "해당 사용자가 존재하지 않습니다."),


    /*
    CONFLICT
     */
    CONFLICT_ID_EXCEPTION(HttpStatus.CONFLICT, "이미 등록된 id입니다."),
    CONFLICT_NICKNAME_EXCEPTION(HttpStatus.CONFLICT, "이미 등록된 닉네임입니다."),

    /*
    SERVER_ERROR
     */
    INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "예상치 못한 서버 에러가 발생했습니다."),
    BAD_GATEWAY_EXCEPTION(HttpStatus.BAD_GATEWAY, "일시적인 에러가 발생하였습니다.\n잠시 후 다시 시도해주세요!"),
    ;

    private final HttpStatus httpStatus;
    private final String message;
}

오류가 발생했을 때의 메세지를 나타내는 ErrorStatus 이다.

 

12. Controller

import com.barcode.solution_challenge_7_back.domain.User;
import com.barcode.solution_challenge_7_back.domain.dto.ApiResponseDto;
import com.barcode.solution_challenge_7_back.domain.dto.UserDto;
import com.barcode.solution_challenge_7_back.domain.request.LoginRequest;
import com.barcode.solution_challenge_7_back.domain.response.DateResponse;
import com.barcode.solution_challenge_7_back.domain.response.LoginResponse;
import com.barcode.solution_challenge_7_back.domain.response.SignupResponse;
import com.barcode.solution_challenge_7_back.repository.UserRepository;
import com.barcode.solution_challenge_7_back.service.UserService;
import com.barcode.solution_challenge_7_back.status.ErrorStatus;
import com.barcode.solution_challenge_7_back.status.SuccessStatus;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;

@RestController
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;
    private final UserRepository userRepository;

    @ApiOperation(value = "회원가입", notes = "새로운 사용자를 회원으로 등록합니다.")
    @ApiResponses(value = {
            @io.swagger.annotations.ApiResponse(code = 200, message = "회원가입 성공"),
            @io.swagger.annotations.ApiResponse(code = 400, message = "잘못된 요청 형식"),
            @io.swagger.annotations.ApiResponse(code = 500, message = "서버 오류")
    })
    @PostMapping("/users/new-user") // 회원가입
    public ApiResponseDto<SignupResponse> join(@RequestBody SignupRequest request) {
        try {
            return ApiResponseDto.success(SuccessStatus.SIGNUP_SUCCESS, userService.save(request)); // 회원가입 성공
        } catch (Exception e) { // 그 밖의 예외 발생시
            return ApiResponseDto.error(ErrorStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @ApiOperation(value = "로그인", notes = "아이디, 비밀번호로 로그인")
    @ApiResponses(value = {
            @io.swagger.annotations.ApiResponse(code = 200, message = "로그인 성공"),
            @io.swagger.annotations.ApiResponse(code = 400, message = "잘못된 요청 형식"),
            @io.swagger.annotations.ApiResponse(code = 500, message = "서버 오류")
    })
    @PostMapping("/login") // 로그인
    public ApiResponseDto<LoginResponse> login(@RequestBody LoginRequest request) {
        boolean isAuthenticated = userService.checkLogin(request.getId(), request.getPassword());
        return isAuthenticated ? ApiResponseDto.success(SuccessStatus.LOGIN_SUCCESS, LoginResponse.of(request.getId())) : ApiResponseDto.error(ErrorStatus.USER_CERTIFICATION_FAILED);
    }

    @ApiOperation(value = "아이디 중복 확인", notes = "해당 id가 이미 존재한다면 true, 존재하지 않다면 false를 반환합니다.")
    @ApiImplicitParam(name = "id", value = "사용자가 생성한 id")
    @GetMapping("/checkDuplicateId/{userId}") // 아이디 중복 확인
    public ApiResponseDto<String> checkDuplicateId(@PathVariable String userId) {
        return userService.checkDuplicateId(userId) ? ApiResponseDto.success(SuccessStatus.CREATE_ID_SUCCESS, userId)
                : ApiResponseDto.error(ErrorStatus.CONFLICT_ID_EXCEPTION, userId);
    }

    @ApiOperation(value = "닉네임 중복 확인", notes = "해당 닉네임이 이미 존재한다면 true, 존재하지 않다면 false를 반환합니다.")
    @ApiImplicitParam(name = "nickname", value = "사용자가 생성한 닉네임")
    @GetMapping("/checkDuplicateNickname/{nickname}")
    public ApiResponseDto<String> checkDuplicateNickname(@PathVariable String nickname) {
        return userService.checkDuplicateNickname(nickname) ? ApiResponseDto.success(SuccessStatus.CREATE_NICKNAME_SUCCESS, nickname)
                : ApiResponseDto.error(ErrorStatus.CONFLICT_NICKNAME_EXCEPTION, nickname);
    }

    @ApiOperation(value = "유저 날짜 가져오기", notes = "회원가입할 때 저장한 날짜를 가져옵니다.")
    @ApiImplicitParam(name = "userId", value = "사용자의 userId")
    @GetMapping("/user/{userId}/day")
    public ApiResponseDto<DateResponse> getUserCustomDay(@PathVariable String userId) {
        Optional<User> optionalUser = userRepository.findById(userId);
        if (optionalUser.isPresent()) {
            User user = optionalUser.get();
            return ApiResponseDto.success(SuccessStatus.BRING_DATE_SUCCESS, DateResponse.of(user.getDate()));
        } else {
            return ApiResponseDto.error(ErrorStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

- 회원가입

SingupResponse를 응답으로 리턴한다. 회원가입 요청이 성공적으로 저장이 된다면 SIGNUP_SUCCESS 메세지를 리턴한다.

그 밖의 에러가 발생한다면 INTERNAL_SERVER_ERROR 메세지를 리턴한다.

 

- 로그인

서비스단의 checkLogin 로직을 활용하여 아이디와 비번을 확인하고 성공 시에는 LOGIN_SUCCESS 메세지와 로그인 한 아이디를 리턴하고, 실패 시에는 USER_CERTIFICATION_FAILED 메세지를 리턴한다.

 

- 중복 확인 

 

[Spring] 중복 확인 Rest API 설계

아이디와 닉네임에 대해 중복을 확인할 수 있는 Rest API이다. 1. Entity @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name="User") public class User { @Id @Column(name="user_id", unique = true) private String i

jiyoungmerong.tistory.com

블로그에 자세히 정리해뒀다.

 

- 유저 날짜 가져오기

레포지토리에서 아이디를 가져와 유저 존재 여부를 확인 후, 존재한다면 BRING_DATE_SUCCESS 메세지와 날짜를 리턴해준다.

존재하지 않다면 INTERNAL_SERVER_ERROR 메세지를 리턴한다.

 

13. SwaggerConfig

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api(){
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }
}

스웨거 사용을 위해 SwaggerConfig를 작성했다.

 

UserRepository와 SecurityConfig는 동일하다!

 

코드 전체는

 

GitHub - jiyoungmerong/Solution-Challenge-7team-Backend: 솔루션챌린지 7팀 백엔드

솔루션챌린지 7팀 백엔드. Contribute to jiyoungmerong/Solution-Challenge-7team-Backend development by creating an account on GitHub.

github.com

링크를 통해 확인할 수 있다.


코드를 리팩토링 하면서 나쁜 코드가 무엇인지를 내 코드를 통해 알게 되었다.

어노테이션의 개념에 대해서도 잘 모르면서 남용했단 것 같다.

앞으로는 왜 사용되는지 꼭 생각하며 코드를 작성해야겠다!