티스토리 뷰

저번 포스팅에서는 기본적인 셋팅을 위한 작업을 했었습니다. 

프로젝트 생성과 서비스등록, 그리고 DB의 연동작업을 했죠!

이번에는 회원가입을 위한 서비스를 만들거에요.

회원가입은 POST 방식으로 /users/라는 URL로 접속하면 회원가입이 이루어지도록 제작하겠습니다. 

그럼 서론은 던져버리고 바로 개발을 진행할게요. 

 

먼저 여러분들을 위한 전체 코드를 먼저 첨부할게요.

#UserController.java

package com.example.userservice.controller;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/")
public class UsersController {

    private Environment env;

    @Autowired
    public UsersController(Environment env){
        this.env = env;
    }

    @GetMapping("/health_check")
    public String status(){
        return "It's Working in User Service";
    }
    @GetMapping("/welcome")
    public String welcome(){
        return env.getProperty("greeting.message");
    }
    @PostMapping("/users")
    public String createUser(@RequestBody RequestUser user){
        return "Create user method is called";
    }

    @Data
    public class RequestUser{
        private String email;
        private String pwd;
        private String name;
    }
}

 

그럼 추가된 녀석들만 확인해볼까요? 

먼저 Post형태로 Mapping이 된 /users 입니다.

    @PostMapping("/users")
    public String createUser(@RequestBody RequestUser user){
        return "Create user method is called";
    }

보시면 RequestBody를 통해서 객체를 받아야하는데, 해당 부분을 입력하시면 오류가 발생할거에요. 

왜냐면 RequestUser라는 클래스는 추후 저희가 임의로 작성할 데이터이기 때문이에요. 아래와 같이 

Inner Class를 작성해줍니다.

    @Data
    public class RequestUser{
        private String email;
        private String pwd;
        private String name;
    }

혹은 Class를 새로 만들어줘도 되지만, 사실 번거로운 작업이기 때문에 저는 InnerClass방식으로 제작했습니다. 

하지만.. 이렇게 제작하고 나니 허점이 하나 보이네요. 유효성은 어떻게 체크를 해야할까요..? 그래서 아래와 같이

코드를 수정해줬습니다. 아 그전에 유효식을 조금 더 쉽게 작성하기 위한 Dependency가 있습니다.

바로 아래와 같은 Dependency를 추가해줍시다.

<dependency>
    <groupId>jakarta.validation</groupId>
    <artifactId>jakarta.validation-api</artifactId>
</dependency>

그럼 다음 과 같이 @NotNull, @Size, @Email등을 사용이 가능해집니다.

각각 역할은 너무나도 명확합니다!

@NotNull은 널체크를 해서 공백이면 안됨을 명시하고

@Size는 말그대로 길이를 지정해줄 수 있습니다. 

@Email은 E-Mail이 맞는지 유효식을 체크줍니다. 기존에 사용하던 방식에 비해서 굉장히 간단하게 사용할 수 있으니

반드시 Dependency를 추가 하는게 좋겠죠? 그럼 RequestUser 클래스를 수정해줍니다.

@Data
public class RequestUser{
    @NotNull(message = "Email cannot be null")
    @Size(min = 2, message = "Email not be less than two characters")
    @Email
    private String email;
    
    @NotNull(message = "Password cannot be null")
    @Size(min = 8, message = "Password must be equal or grater than 8 characters and less than 16 characters")
    private String pwd;
    
    @NotNull(message = "Name cannot be null")
    @Size(min = 2, message = "Name not be less than two characters")
    private String name;
}

 

자 이제 데이터 교환을 위해서 DTO클래스를 하나 생성해줍니다. 

위치는 저는 아래와 같이 DTO 패키지를 하나 생성했습니다. 

그리고 UserDto라는 클래스를 생성 후 아래와 같이 입력해줬습니다. 

#UserDto.java

package com.example.userservice.dto;

import lombok.Data;

import java.util.Date;

@Data
public class UserDto {

    private String email;
    private String name;
    private String pwd;
    private String userId;
    private Date createdAt;

    private String encryptedPwd;

}

pwd는 따로 암호화된 패스워드를 저장하기 위해서 encryptedPwd라는 변수를 하나 더 추가해줬어요. 

그럼 이제 UserDto를 활용할 UserService를 작성해볼까요?

#UserService

#UserService(Interface)

package com.example.userservice.service;

import com.example.userservice.dto.UserDto;


public interface UserService {
    UserDto createUser(UserDto userDto);
}

#UserServiceImpl

회원가입을 위한 createUser를 작성해 봅시다!

또한 서비스로 사용할 예정이니 @Service를 통해서 등록해주는 것도 잊지 않았어요!

package com.example.userservice.serviceimpl;

import com.example.userservice.dto.UserDto;
import com.example.userservice.jpa.UserEntity;
import com.example.userservice.jpa.UserRepository;
import com.example.userservice.service.UserService;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserRepository userRepository;
    @Override
    public UserDto createUser(UserDto userDto) {
        userDto.setUserId(UUID.randomUUID().toString());

        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        UserEntity userEntity = mapper.map(userDto,UserEntity.class);
        userEntity.setEncryptedPwd("encrypted_password");

        userRepository.save(userEntity);

        UserDto returnUserDto = mapper.map(userEntity, UserDto.class);

        return returnUserDto;
    }
}

아마 여기까지 작성을 완료하셨다면 오류가 보이실텐데 금방 해결할테니 걱정말고 따라와주세요.

조금 설명을 덧붙이면 userDto에서 ID값은 UUID의 기능중 하나인 랜덤으로 ID를 생성해주는 기능을 사용할 거에요. 

바로 아래의 코드에요! 

userDto.setUserId(UUID.randomUUID().toString());

 

그 뒤에는 mapper를 활용해서 나머지 정보를 입력해줄거에요.  마지막으로 userRepository.save를 활용해서 관련 내용을 저장해줄거에요! 

 ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        UserEntity userEntity = mapper.map(userDto,UserEntity.class);
        userEntity.setEncryptedPwd("encrypted_password");

        userRepository.save(userEntity);

그럼 해당 메서드가 원활하게 동작하도록 userRepository와 UserEntity를 작성해봅시다!

#UserEntity

package com.example.userservice.jpa;

import lombok.Data;

import javax.persistence.*;

@Data
@Entity
@Table(name = "USERS" )
public class UserEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 50,unique = true)
    private String email;
    @Column(nullable = false, length = 50)
    private String name;
    @Column(nullable = false, unique = true)
    private String userId;
    @Column(nullable = false, unique = true)
    private String encryptedPwd;
}

UserEntity는 데이터베이스의 테이블을 생성하는 클래스라고 생각해주세요, 컬럼의 종류와 제한 등 익숙한 표현들이 많이 보이죠? DB에 연동되기 위한 정보들을 셋팅하는 공간이라고 생각해주세요. 아래의 UserRepository는 해당 Entity를 바탕으로 저희의 메서드가 동작할 수 있도록 도와줄거에요.

#UserRepository

package com.example.userservice.jpa;

import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<UserEntity, Long> {

}

완성! 

 

...? 정말 끝인가요?

네 정말 끝이에요! Repository 를 보시면 상속을 받았는데 CrudRepository라는 클래스를 상속받았습니다.

해당 클래스는 말그대로 CRUD를 원활하게 이루어지게 하는 클래스에요! 편하게 회원가입을 만들라는 

킹갓제작자님이 누군지는 모르겠지만 감사의 인사 드립니다... 

 

겉핥기를 살짝 해보자면 UserServiceImpl로 다시 돌아가보세요!  

userRepository.save(userEntity);

이 부분 기억나시나요? 부모클래스에서 .save를 통해서 H2 DB에 원활하게 회원정보가 입력되도록 도와줄거에요. 

자아 이제 Controller만 수정하면 이 길고도 길었던 여정도 끝이 나겠네요...

기존에 작성했던 /users가 기억나시나요?  조금 추가하고 수정해봅시다.

#UsersController

package com.example.userservice.controller;

import com.example.userservice.dto.UserDto;
import com.example.userservice.service.UserService;
import com.example.userservice.vo.RequestUser;
import com.example.userservice.vo.ResponseUser;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/")
public class UsersController {

    private Environment env;
    private UserService userService;
    @Autowired
    public UsersController(Environment env, UserService userService){
        this.env = env;
        this.userService = userService;
    }

    @GetMapping("/health_check")
    public String status(){
        return "It's Working in User Service";
    }
    @GetMapping("/welcome")
    public String welcome(){
        return env.getProperty("greeting.message");
    }
    @PostMapping("/users")
    public ResponseEntity<ResponseUser> createUser(@RequestBody RequestUser user){
        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        UserDto userDto = mapper.map(user, UserDto.class);
        userService.createUser(userDto);

        ResponseUser responseUser = mapper.map(userDto, ResponseUser.class);

        return ResponseEntity.status(HttpStatus.CREATED).body(responseUser);

    }

}

하단에 /users부분을 수정했습니다. 하나하나 살펴볼게요. 

일단 RequestBody를 통해서 저희는 회원 정보를 등록할예정이에요 user안에 담겨있는 정보죠!

ModelMapper를 통해서 model을 생성해줍니다.

setMatchingStrategy를 통해서 완전한 매칭이 이루어지도록 하고

UserDto객체를 생성해 mapper.map(user, UserDto.Class)의 정보를 넣었어요 해당 정보는 Requestbody안에 있는 정보를 UserDto형태로 변환해서 저장했다고 생각하면 편할 것 같아요 그 뒤 createUser 서비스에 접근해서 회원등록을 진행해요!

머리 아프지 않나요 저는 머리 쥐어뜯어봤지만 이해가 잘 되진 않네요 ㅋ

    @PostMapping("/users")
    public ResponseEntity<ResponseUser> createUser(@RequestBody RequestUser user){
        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        UserDto userDto = mapper.map(user, UserDto.class);
        userService.createUser(userDto);

        ResponseUser responseUser = mapper.map(userDto, ResponseUser.class);

        return ResponseEntity.status(HttpStatus.CREATED).body(responseUser);

    }

밑에 있는 ResponseUser는 저장된 정보를 리턴해주기 위한 정보에요! 이제 Return값으로 상태코드와 저희가 

회원 가입한 아이디와 비밀번호가 출력 될거에요!  뒤에 있는 내용은 속성으로 빨리 빨리 넘어갈게요! 여러분의 시간은

소중하니까요

#ResponseUser 생성

package com.example.userservice.vo;

import lombok.Data;

@Data
public class ResponseUser {
    private String email;
    private String name;
    private String userId;
}

#yml파일 수정 ( DB 연동을 위해서 )

server:
   port: 0

spring:
   application:
      name: user-service
   h2:
      console:
         enabled: true
         settings:
            web-allow-others: true
         path: /h2-console
   datasource:
      driver-class-name: org.h2.Driver
      url: jdbc:h2:mem:testdb

greeting:
   message: Welcome to the Simple E-Commerce.
eureka:
   instance:
      instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
   client:
      register-with-eureka: true
      fetch-registry: true
      service-url:
         defaultZone: http://localhost:8761/eureka

datasource의 추가 => 참조할 데이터소스를 제공해야함 url은 특히 신경써야함 

로그인 화면에서 URL을 지정할 수 있고 이건 임의로 변경 가능

JDBC URL과 YML의 URL은 일치
접속시 뜨는 화면

그리고 USERS테이블이 자동으로 생성되어 있어야함.

POST-MAN으로 실행해보고 Body 에 다음과 같이 입력 그리고 POST방식으로 하는거 까먹지 말 것

리턴 값으로 입력한 내용을 볼 수 있고, userID까지는 출력을 되면 성공

대단한 당신 굿굿 따봉

 

다음 시간엔 최종적으로 Security와 관련한 설정을 하도록 하겠습니다.

감사합니다. 

 

이번 프로젝트는 조금 클래스간 복잡도가 있었던 것 같아서 아래와 같이 첨부파일을 첨부합니다. 혹시 진행하시면서 문제가 생기면 아래의 첨부파일을 이용하시길 바랍니다. 감사합니다. 

userservice.zip
0.09MB

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함