Spring Boot를 활용하여 OPEN API 조회기능을 구현할 예정이다.
그에 앞서서, 회원가입과 로그인 기능을 구현하고자 한다.
테이블로 매핑할 클래스 정의, 하나의 생성된 인스턴스가 테이블의 한 행에 해당.
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "userId")})
public class UserEntity {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String id;
@Column(nullable = false)
private String userId;
@Column(nullable = false)
private String password;
}
package com.example.demo.controller;
import com.example.demo.dto.ResponseDTO;
import com.example.demo.dto.UserDTO;
import com.example.demo.model.UserEntity;
import com.example.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@RequestMapping("/user")
@CrossOrigin(originPatterns = "http://localhost:3000")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/signup")
public ResponseEntity<?> registerUser(@RequestBody UserDTO userDTO){
System.out.println(userDTO.getUserId());
try {
UserEntity user = UserEntity.builder()
.userId(userDTO.getUserId())
.password(userDTO.getPassword())
.build();
UserEntity registeredUser = userService.create(user);
UserDTO responseDTO = UserDTO.builder()
.userId(registeredUser.getUserId())
.id(registeredUser.getId())
.build();
return ResponseEntity.ok().body(responseDTO);
}
catch(Exception e) {
ResponseDTO responseDTO = ResponseDTO.builder().error(e.getMessage()).build();
return ResponseEntity.badRequest().body(responseDTO);
}
}
@PostMapping("/signin")
public ResponseEntity<?> authenticate(@RequestBody UserDTO userDTO){
UserEntity user = userService.getByCredentials(
userDTO.getUserId(),
userDTO.getPassword());
if(user != null){
UserDTO responseUserDTO = UserDTO.builder()
.userId(user.getUserId()).password(user.getPassword())
.build();
System.out.println(ResponseEntity.ok().body(responseUserDTO));
return ResponseEntity.ok().body(responseUserDTO);
}
else {
ResponseDTO responseDTO = ResponseDTO.builder().error("로그인 실패하였습니다.").build();
return ResponseEntity.badRequest().body(responseDTO);
}
}
}
persistence layer(repository)에 요청할 CRUD 함수를 함수를 구현한다.
package com.example.demo.service;
import com.example.demo.model.UserEntity;
import com.example.demo.persistence.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public UserEntity create(final UserEntity userEntity){
if(userEntity == null || userEntity.getUserId()==null){
throw new RuntimeException("가입된 회원이 아닙니다.");
}
final String userId = userEntity.getUserId();
if(userRepository.existsByUserId(userId)){
log.warn("이미 가입된 회원입니다.",userId);
throw new RuntimeException("이미 가입된 아닙니다.");
}
return userRepository.save(userEntity);
}
public UserEntity getByCredentials(final String userId, final String password){
return userRepository.findByUserIdAndPassword(userId, password);
}
}
JpaRepository interface는 정의된 Entity로 DB에 저장, 조회할 수 있는 메소드가 정의되어 있다. 이것을 상속 받아서 우리가 사용할 repository interface를 구현한다.
package com.example.demo.persistence;
import com.example.demo.model.UserEntity;
import org.apache.catalina.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<UserEntity, String>{
UserEntity findByUserId(String userId);
Boolean existsByUserId(String userId);
UserEntity findByUserIdAndPassword(String userId, String password);
}
Entity는 DB에 테이블의 구조와 유사하므로, 캡슐화를 위해 Entity를 DTO로 변환하고,
토큰이나 상태코드의 정보를 DTO에 추가하여 전달한다.
package com.example.demo.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
private String userId;
private String password;
private String id;
}