Spring Boot 로 웹 서비스 출시하기 -3. 게시판 구현하기 (JPA + RestAPI + Oracle)

실수·2021년 3월 23일
0

먼저 프로젝트 구조입니다.

프로젝트 수정

컨트롤러

UserRestController라는 컨트롤러를 새로 만들어주겠습니다.

@RestController
public class UserRestController {

    @Autowired
    UserService userService;

	//전체 회원 리스트
    @GetMapping("/member/all")
    public List<UserDto> list(){
        return userService.getUserList();
    }

	//회원 추가
    @PostMapping("/member/new")
    public void insert(@RequestBody UserDto userDto){

        userService.joinUser(userDto);
    }

	//회원 수정
    @PutMapping("/member/{id}")
    public void updateUser(@PathVariable Long id, @RequestBody UserDto userDto){

        userService.updateUser(id, userDto);
    }

	//회원 상세
    @GetMapping("/member/{id}")
    public UserDto getUser(@PathVariable Long id){

        return userService.getUser(id);
    }

	//회원 삭제
    @DeleteMapping("/member/{id}")
    public void deleteUser(@PathVariable Long id){

        userService.deleteUser(id);
    }
}

@RestController는 Spring MVC Controlle에 @ResponseBody가 추가된 것입니다. 당연하게도 RestController의 주용도는 Json 형태로 객체 데이터를 반환하는 것입니다.

/member/all 이라는 주소로 들어가면 모든 유저의 정보를 JSON객체 형태로 반환 받을 수 있습니다.

다음으로 UserController를 수정하겠습니다.

    // 회원가입 페이지
    @GetMapping("/user/signup")
    public String dispSignup() {
        return "/signup";
    }

    //회원 리스트
    @GetMapping("member")
    public String memList(){
        return"/member/list";
    }
	
    //회원 상세보기
    @GetMapping("{id}")
    public String getUser(@PathVariable Long id){

        return "member/detail";
    }

이번에는 저번프로젝트와 다르게 유저 정보로 설정을 했기때문에 엔티티와 DTO, Service가 다 달라졌기때문에 전부 수정을 하거나 새 프로젝트를 만드는것을 권장합니다.

UserEntity

package com.everyday.everymap.domain.entity;

import com.everyday.everymap.domain.Role;
import lombok.*;

import javax.persistence.*;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Setter
@Entity
@Table(name = "users")
public class UserEntity extends TimeEntity {
    @Id
    @GeneratedValue(strategy= GenerationType.SEQUENCE)
    private Long id;

    @Column(length = 30, nullable = false)
    private String email;

    @Column(length = 100)
    private String password;

    @Column(length = 20)
    private String name;

    @Column(length = 20)
    private String nickname;

    @Column(length = 20)
    private String rrn;

    @Column(length = 20)
    private String gender;

    @Column(length = 20)
    private String phone;

    @Enumerated(EnumType.STRING)
    private Role role;

    @Builder
    public UserEntity(Long id, String email, String password, String name,
                      String nickname, String rrn, String gender,
                      String phone, Role role){
        this.id= id;
        this.email = email;
        this.password = password;
        this.name = name;
        this.nickname = nickname;
        this.rrn = rrn;
        this.gender = gender;
        this.phone = phone;
        this.role = role;
    }
    
    public UserEntity update(String name) {
        this.name = name;

        return this;
    }


    public String getRoleKey(){
        return this.role.getKey();
    }

}

TimeEntity

package com.everyday.everymap.domain.entity;

import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class TimeEntity {
    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdDate;

}

UserEntity는 TimeEntity를 extends하여 시간값을 같이 데이터베이스에 넣어줍니다.

UserDto

package com.everyday.everymap.dto;

import com.everyday.everymap.domain.entity.UserEntity;
import lombok.*;

import java.time.LocalDateTime;

@Getter
@Setter
@ToString
@NoArgsConstructor
public class UserDto {
    private Long id;
    private String email;
    private String password;
    private String name;
    private String nickname;
    private String rrn;
    private String gender;
    private String phone;
    private LocalDateTime createdDate;

    public UserEntity toEntity(){
        return UserEntity.builder()
                .id(id)
                .email(email)
                .password(password)
                .name(name)
                .nickname(nickname)
                .rrn(rrn)
                .gender(gender)
                .phone(phone)
                .build();
    }

    @Builder
    public UserDto(Long id, String email, String password, String name, String nickname, String rrn, String gender, String phone, LocalDateTime createdDate) {
        this.id = id;
        this.email = email;
        this.password = password;
        this.name = name;
        this.nickname = nickname;
        this.rrn = rrn;
        this.gender = gender;
        this.phone = phone;
        this.createdDate = createdDate;
    }
}

UserService

package com.everyday.everymap.service;

import com.everyday.everymap.domain.Role;
import com.everyday.everymap.domain.entity.UserEntity;
import com.everyday.everymap.domain.repository.UserRepository;
import com.everyday.everymap.dto.UserDto;
import lombok.AllArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
@AllArgsConstructor
public class UserService implements UserDetailsService {
    private UserRepository userRepository;

    @Transactional
    public List<UserDto> getUserList(){
        List<UserEntity> userEntities = userRepository.findAllByOrderByIdAsc();
        List<UserDto> userDtoList = new ArrayList<>();

        for ( UserEntity userEntity : userEntities) {
            UserDto userDTO = UserDto.builder()
                    .id(userEntity.getId())
                    .email(userEntity.getEmail())
                    .password(userEntity.getPassword())
                    .name(userEntity.getName())
                    .nickname(userEntity.getNickname())
                    .rrn(userEntity.getRrn())
                    .gender(userEntity.getGender())
                    .phone(userEntity.getPhone())
                    .createdDate(userEntity.getCreatedDate())
                    .build();

            userDtoList.add(userDTO);
        }
        return userDtoList;
    }

    @Transactional
    public void joinUser(UserDto userDto) {
        // 비밀번호 암호화
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        userDto.setPassword(passwordEncoder.encode(userDto.getPassword()));

        userRepository.save(userDto.toEntity());
    }

    @Transactional
    public void updateUser(Long id, UserDto userDto){
        Optional<UserEntity> user = userRepository.findById(id);
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        userDto.setPassword(passwordEncoder.encode(userDto.getPassword()));

        user.ifPresent(selectUser ->{
            selectUser.setEmail(userDto.getEmail());
            selectUser.setPassword(userDto.getPassword());
            selectUser.setGender(userDto.getGender());
            selectUser.setName(userDto.getName());
            selectUser.setNickname(userDto.getNickname());
            selectUser.setPhone(userDto.getPhone());
            selectUser.setRrn(userDto.getRrn());
        });
    }

    @Transactional
    public UserDto getUser(Long id) {
        Optional<UserEntity> userEntityWrapper = userRepository.findById(id);
        UserEntity userEntity = userEntityWrapper.get();

        return UserDto.builder()
                .id(userEntity.getId())
                .email(userEntity.getEmail())
                .password(userEntity.getPassword())
                .name(userEntity.getName())
                .nickname(userEntity.getNickname())
                .rrn(userEntity.getRrn())
                .gender(userEntity.getGender())
                .phone(userEntity.getPhone())
                .createdDate(userEntity.getCreatedDate())
                .build();
    }

    @Transactional
    public void deleteUser(Long id){
        userRepository.deleteById(id);
    }

}

UserRestController에서 쓰일 로직들을 만들어주는 곳입니다.

비밀번호 암호화는 여기서는 다루지 않았지만 SpringSecurity 때문에 들어있는거라 시큐리티를 사용하지 않으실거면 따로 넣으실 필요는 없습니다.

POSTMAN을 이용한 API 테스트


GET을 이용하여 API에 요청하니 JSON값으로 반환이 잘 되는것을 볼 수가 있습니다.

28번 아이디의 유저 이메일을 abc@dfg.com으로 바꿔보겠습니다.

정상적으로 바뀌었습니다.

새 유저를 요청하여 보겠습니다.

41번 id의 유저로 생성 되었습니다.
id숫자가 불규칙한 이유는 생성했다가 지웠다가 반복하면서 sequence를 소비해서 그렇습니다..

41번 유저만 요청하는것도 잘 동작합니다.


삭제도 잘 되네요.

profile
컴린이

0개의 댓글