Skip to content
This repository has been archived by the owner on Aug 13, 2022. It is now read-only.

회원가입 및 로그인 기능 추가 #3

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,33 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
compile group: 'commons-codec', name: 'commons-codec', version: '1.10'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java' //mysql connect 드라이버 설치
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
compile 'org.springframework.boot:spring-boot-starter-log4j2'
compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.10.3'

testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.springframework.boot:spring-boot-starter-log4j2'
testImplementation 'mysql:mysql-connector-java'
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'org.hamcrest:hamcrest-library:2.2'



/**
* (10/11) Intellij 내부적으로 JUnit을 지원해주고 있습니다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intellij 지원이면 intellij가 아닌 환경에서는 에러가 나지 않나요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 내용은 개인적으로 블로그 글을 잘못 이해했습니다. 스프링 내부(org.springframework.boot:spring-boot-starter-test)에서 jupiter를 제공해주고 있으며, 따라서 추가했던 jupiter는 삭제했습니다.

* 따라서 아래 jupiter를 설정하면, version conflict로 인해 테스트코드가 정상적으로 동작하지 않을 수 있습니다.(MemberService Test 코드 작성 중 발견)
* 참고 : https://youtrack.jetbrains.com/issue/IDEA-178404
*/
// JUnit5의 경우 api, engine을 함께 사용해야 한다.
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'

testRuntimeOnly 'com.h2database:h2'
// testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
// testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}

test {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package me.naming.onlineshoppingmall.config;

import java.time.LocalDateTime;
import me.naming.onlineshoppingmall.domain.ResponseData;
import me.naming.onlineshoppingmall.exception.MessageException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

// @Controller or @RestController에서 발생하는 예외를 관리 할 수 있게 만들어주는 어노테이션
// @ExceptionHandler를 통해 각각의 예외처리 메세지를 원하는 형태로 작성 할 수 있다.
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler(value = { MessageException.class })
protected ResponseEntity handleConflict(MessageException messageException, WebRequest request) {
String path = ((ServletWebRequest)request).getRequest().getRequestURI();
int code;

if(messageException.getStatusCode() != 0) {
code = messageException.getStatusCode();
} else {
code = HttpStatus.INTERNAL_SERVER_ERROR.value();
}

ResponseData responseData = ResponseData.builder()
.localDateTime(LocalDateTime.now())
.statusCode(code)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게하면 status code가 body에 들어가지 않을까요?

.path(path)
.message(messageException.getMessage())
.build();

return new ResponseEntity<>(responseData, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

//상수만을 관리하기 위한 클래스
public class CommonConstant {

private CommonConstant() {};

public static final String LOGIN_INFO = "loginInfo";
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,55 @@
package me.naming.onlineshoppingmall.controller;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import lombok.Getter;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import me.naming.onlineshoppingmall.domain.Member;
import me.naming.onlineshoppingmall.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class MemberController {

private static final Logger logger = LogManager.getLogger(MemberController.class);
private final MemberService memberService;

@GetMapping
public void hello() {
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}

// 회원가입
@PostMapping(value = "/members/signup")
@ResponseStatus(HttpStatus.CREATED)
public void memberJoin(@RequestBody @Valid Member member) {
memberService.signUp(member);
}

// 회원정보 갖고오기
@GetMapping(value = "/members/{memNo}")
@ResponseStatus(HttpStatus.OK)
public Member getMemberInfo(@PathVariable(name = "memNo") Long memNo) {
return memberService.getMemberInfo(memNo);
}

@GetMapping(value = "/login")
@ResponseStatus(HttpStatus.OK)
public void login(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
memberService.doLogin(userLoginRequest.getEmail(), userLoginRequest.getPassword(), request);
}

@Getter
private static class UserLoginRequest {
@NonNull String email;
@NonNull String password;
}
}
67 changes: 47 additions & 20 deletions src/main/java/me/naming/onlineshoppingmall/domain/Member.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.naming.onlineshoppingmall.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
Expand All @@ -9,59 +10,85 @@
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import lombok.Setter;
import lombok.ToString;

@Entity
@Table(name = "MEMBERS")
@Getter
@NoArgsConstructor
@ToString
public class Member {

@Builder
public Member(String email, String password, String name, String gender, Date birthDate) {
this.email = email;
this.password = password;
this.name = name;
this.gender = gender;
this.birthDate = birthDate;
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "MEM_NO")
private Long memNo;

@Column
@Column(name = "EMAIL")
@NotNull
@Email(message = "이메일 형식에 맞지 않습니다.")
private String email;

@Column
// 영문(소문자, 대문자), 숫자, 특수문자 조합 9~12자리 조합
@Column(name = "PASSWORD")
@NotNull
@Setter
@Pattern(regexp = "^(?=.*\\d)(?=.*[~`!@#$%\\^&*()-])(?=.*[a-z])(?=.*[A-Z]).{9,12}$",
message = "비밀번호는 영문 대,소문자와 숫자, 특수기호가 적어도 1개 이상씩 포함된 9자 ~ 12자의 비밀번호여야 합니다.")
private String password;

@Column
@Column(name = "NAME", length = 30)
@NotBlank(message = "이름은 필수 입력 값입니다.")
@NotNull
private String name;

@Column(name = "GENDER", length = 1)
@NotBlank(message = "성별은 필수 입력 값입니다.")
@NotNull
private String gender;

@Temporal(TemporalType.TIMESTAMP)
@Column
@Column(name = "STATUS")
@Setter
private MemberStatus memberStatus;

@Column(name = "HP", length = 11)
@NotNull
private Long hp;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "BIRTH_DTS") @NotNull
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy/MM/dd", timezone = "Asia/Seoul)")
private Date birthDate;

@Temporal(TemporalType.TIMESTAMP)
@Column
@CreationTimestamp
@Column(name = "REG_DTS", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Date regDts;

@Temporal(TemporalType.TIMESTAMP)
@Column
@CreationTimestamp
@Column(name = "MOD_DTS", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Date modDts;
}

public enum MemberStatus{
// DEFAULT(가입), DELETE(탈퇴), DORMANT(휴면)
DEFAULT, DELETE, DORMANT
}

@Builder
public Member(String email, String password, String name, String gender, MemberStatus memberStatus, Date birthDate, Long hp) {
this.email = email;
this.password = password;
this.name = name;
this.gender = gender;
this.memberStatus = memberStatus;
this.birthDate = birthDate;
this.hp = hp;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package me.naming.onlineshoppingmall.domain;

import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import org.springframework.http.HttpStatus;

@Builder
@ToString
@Getter
public class ResponseData {
private LocalDateTime localDateTime;
private int statusCode;
private String path;
private String message;

public ResponseData(LocalDateTime localDateTime, int statusCode, String path, String message) {
this.localDateTime = localDateTime;
this.statusCode = statusCode;
this.path = path;
this.message = message;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package me.naming.onlineshoppingmall.exception;

import org.springframework.http.HttpStatus;

public class MessageException extends RuntimeException{

private int statusCode;

public MessageException(String message) {
super(message);
this.statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
}

public MessageException(String message, int statusCode) {
super(message);
this.statusCode = statusCode;
}

public int getStatusCode() {
return statusCode;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

public interface MemberRepository extends JpaRepository<Member, Long> {
Member findByMemNo(Long memNo);
}
Member findByEmail(String email);
Member findMemnoAndPasswordByEmail(String email);
}
Loading