#24 simple sns: join

This commit is contained in:
haerong22
2022-10-18 23:53:30 +09:00
parent edd9482d49
commit f86f895fea
11 changed files with 175 additions and 7 deletions

View File

@@ -1,8 +1,13 @@
package com.example.sns.controller;
import com.example.sns.controller.request.UserJoinRequest;
import com.example.sns.controller.response.Response;
import com.example.sns.controller.response.UserJoinResponse;
import com.example.sns.model.User;
import com.example.sns.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -14,7 +19,9 @@ public class UserController {
private final UserService userService;
@PostMapping("/join")
public void join() {
userService.join(username, password);
public Response<UserJoinResponse> join(@RequestBody UserJoinRequest request) {
User user = userService.join(request.getUsername(), request.getPassword());
return Response.success(UserJoinResponse.fromUser(user));
}
}

View File

@@ -0,0 +1,20 @@
package com.example.sns.controller.response;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class Response<T> {
private String resultCode;
private T result;
public static <T> Response<T> success(T result) {
return new Response<>("SUCCESS", result);
}
public static Response<Void> error(String errorCode) {
return new Response<>(errorCode, null);
}
}

View File

@@ -0,0 +1,21 @@
package com.example.sns.controller.response;
import com.example.sns.model.User;
import com.example.sns.model.UserRole;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class UserJoinResponse {
private Integer id;
private String username;
private UserRole role;
public static UserJoinResponse fromUser(User user) {
return new UserJoinResponse(
user.getId(),
user.getUsername(),
user.getUserRole()
);
}
}

View File

@@ -0,0 +1,17 @@
package com.example.sns.exception;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;
@Getter
@AllArgsConstructor
public enum ErrorCode {
DUPLICATED_USER_NAME(HttpStatus.CONFLICT, "Username is duplicated.")
;
private HttpStatus status;
private String message;
}

View File

@@ -0,0 +1,19 @@
package com.example.sns.exception;
import com.example.sns.controller.response.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalControllerAdvice {
@ExceptionHandler(SnsApplicationException.class)
public ResponseEntity<?> applicationHandler(SnsApplicationException e) {
log.info("Error occurs {}", e.toString());
return ResponseEntity.status(e.getErrorCode().getStatus())
.body(Response.error(e.getErrorCode().name()));
}
}

View File

@@ -1,4 +1,23 @@
package com.example.sns.exception;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class SnsApplicationException extends RuntimeException {
private ErrorCode errorCode;
private String message;
@Override
public String getMessage() {
if (message==null) {
return errorCode.getMessage();
}
return String.format("$s, $s", errorCode.getMessage(), message);
}
}

View File

@@ -1,7 +1,32 @@
package com.example.sns.model;
import com.example.sns.model.entity.UserEntity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.sql.Timestamp;
@Getter
@AllArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
private UserRole userRole;
private Timestamp registeredAt;
private Timestamp updatedAt;
private Timestamp deletedAt;
public static User fromEntity(UserEntity entity) {
return new User(
entity.getId(),
entity.getUsername(),
entity.getPassword(),
entity.getRole(),
entity.getRegisteredAt(),
entity.getUpdatedAt(),
entity.getDeletedAt()
);
}
}

View File

@@ -0,0 +1,5 @@
package com.example.sns.model;
public enum UserRole {
ADMIN, USER
}

View File

@@ -1,13 +1,20 @@
package com.example.sns.model.entity;
import com.example.sns.model.UserRole;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import javax.persistence.*;
import java.sql.Timestamp;
import java.time.Instant;
@Entity
@Table
@Table(name = "\"user\"")
@Getter @Setter
@SQLDelete(sql = "UPDATE \"user\" SET deleted_at = NOW() where id=?")
@Where(clause = "deleted_at IS NULL")
public class UserEntity {
@Id
@@ -16,4 +23,28 @@ public class UserEntity {
private String username;
private String password;
@Enumerated(EnumType.STRING)
private UserRole role;
private Timestamp registeredAt;
private Timestamp updatedAt;
private Timestamp deletedAt;
@PrePersist
void registeredAt() {
this.registeredAt = Timestamp.from(Instant.now());
}
@PreUpdate
void updatedAt() {
this.updatedAt = Timestamp.from(Instant.now());
}
public static UserEntity of(String username, String password) {
UserEntity userEntity = new UserEntity();
userEntity.setUsername(username);
userEntity.setPassword(password);
return userEntity;
}
}

View File

@@ -1,5 +1,6 @@
package com.example.sns.service;
import com.example.sns.exception.ErrorCode;
import com.example.sns.exception.SnsApplicationException;
import com.example.sns.model.User;
import com.example.sns.model.entity.UserEntity;
@@ -18,12 +19,14 @@ public class UserService {
public User join(String username, String password){
// username 확인
Optional<UserEntity> userEntity = userEntityRepository.findByUsername(username);
userEntityRepository.findByUsername(username).ifPresent(it -> {
throw new SnsApplicationException(ErrorCode.DUPLICATED_USER_NAME, String.format("$s is duplicated", username));
});
// 회원가입 진행
userEntityRepository.save(new UserEntity());
UserEntity userEntity = userEntityRepository.save(UserEntity.of(username, password));
return new User();
return User.fromEntity(userEntity);
}
public String login(String username, String password) {

View File

@@ -2,6 +2,7 @@ package com.example.sns.controller;
import com.example.sns.controller.request.UserJoinRequest;
import com.example.sns.controller.request.UserLoginRequest;
import com.example.sns.exception.ErrorCode;
import com.example.sns.exception.SnsApplicationException;
import com.example.sns.model.User;
import com.example.sns.service.UserService;
@@ -52,7 +53,7 @@ public class UserControllerTest {
String username = "username";
String password = "password";
when(userService.join(username, password)).thenThrow(new SnsApplicationException());
when(userService.join(username, password)).thenThrow(new SnsApplicationException(ErrorCode.DUPLICATED_USER_NAME, ""));
mockMvc.perform(post("/api/v1/users/join")
.contentType(MediaType.APPLICATION_JSON)