먼저 프로젝트 구조입니다.
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 때문에 들어있는거라 시큐리티를 사용하지 않으실거면 따로 넣으실 필요는 없습니다.
GET을 이용하여 API에 요청하니 JSON값으로 반환이 잘 되는것을 볼 수가 있습니다.
28번 아이디의 유저 이메일을 abc@dfg.com으로 바꿔보겠습니다.
정상적으로 바뀌었습니다.
새 유저를 요청하여 보겠습니다.
41번 id의 유저로 생성 되었습니다.
id숫자가 불규칙한 이유는 생성했다가 지웠다가 반복하면서 sequence를 소비해서 그렇습니다..
41번 유저만 요청하는것도 잘 동작합니다.
삭제도 잘 되네요.