시스템 구성
- Spring boot 2.7.5
- Gradle
- Java 11
- Intellij Ultimate
라이브러리
- thymeleaf
- jpa
- web
- lombok
- h2 DB
프로젝트 구조
프로젝트 구조는 위와 같은 구조를 따라갈 것이며 각 내용이 무엇을 하는지는
이 전에 작성한 내용을 보면 이해하기 쉬울 것 같다.
구현
우선 회원가입 관련한 페이지를 보기 위해서 간단한 컨트롤러를 구현한다.
package com.practice.board.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller // 해당 클래스가 컨트롤러임을 알리고 bean으로 등록하기 위함
@RequiredArgsConstructor // 나중에 의존관계 관련하여 필요한 어노테이션
public class MemberController {
@GetMapping("/")
public String Home() {
return "home";
}
}
그리고 메인 화면을 간단하게 작성해준다.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.ofg">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<div class="container">
<p>회원 기능</p>
<div>
<a href="/members/new">회원가입</a>
<a href="/members">회원 목록</a>
</div>
</div>
</body>
</html>
이제 회원가입 로직을 구현해보자 가장 처음으로 회원정보에 관한 테이블을 설계해야 한다.
Member Domain
package com.practice.board.domain;
import lombok.*;
import javax.persistence.*;
@Entity
@Data // Getter Setter
@Builder // DTO -> Entity화
@AllArgsConstructor // 모든 컬럼 생성자 생성
@NoArgsConstructor // 기본 생성자
@Table(name = "member")
public class Member {
@Id // 내가 PK
@GeneratedValue(strategy = GenerationType.IDENTITY) // 자동 id 생성
private Long id;
@Column(nullable = false, unique = true)
private String email;
@Column
private String username;
@Column(nullable = false)
private String password;
}
이제 테이블 설계가 끝났다면 해당 DB에 접근하여 컨트롤할 수 있도록 repository를 작성해야 한다.
MemberRepository
package com.practice.board.repository;
import com.practice.board.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MemberRepository extends JpaRepository<Member, Long> {
}
레포지토리는 직접 원하는 로직을 작성하여 구현할 수 있지만 아주 간단한 회원가입을 만들 것이기 때문에
JpaRepository를 상속받아서 사용하였다.
이제 해당 레포를 가지고 실질적으로 사용하는 비지니스 로직을 구현해야 한다.
MemberService
package com.practice.board.service;
import com.practice.board.dto.MemberFormDTO;
public interface MemberService {
Long join(MemberFormDTO memberFormDTO);
}
우선 Service를 바로 구현하지 않고 인터페이스를 한번 거쳐서 사용한다. 구현체를 바로 작성하지 않고
인터페이스를 사용하는 이유는 구글에 직접 검색해보거나
https://reinvestment.tistory.com/48
위 글을 읽어보면 좋겠다.
MemberServiceImpl
package com.practice.board.service.Impl;
import com.practice.board.domain.Member;
import com.practice.board.dto.MemberFormDTO;
import com.practice.board.repository.MemberRepository;
import com.practice.board.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service // 내가 서비스다
@RequiredArgsConstructor // 밑에 MemberRepository의 생성자를 쓰지 않기 위해서
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Override
public Long join(MemberFormDTO memberFormDTO) {
Member member = Member.builder()
.email(memberFormDTO.getEmail())
.username(memberFormDTO.getUsername())
.password(memberFormDTO.getPassword())
.build();
return memberRepository.save(member).getId();
}
}
간단한 회원가입이기 때문에 크게 상관은 없지만 나중에 Entity에 중요 정보가 있다면 해당 내용은 외부에 노출되지 않게끔
DTO를 사용하여 정보를 전달받고 Builder를 통해 Entity화 한다.
비지니스 로직까지 구현했다면 이제 컨트롤러를 통해 로직을 호출하기만 하면 된다.
MemberFormDTO
package com.practice.board.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MemberFormDTO {
private String email;
private String username;
private String password;
}
위 DTO 코드는 외부로부터 전달받기 위한 DTO이고 나중에 사용자에게 값을 return 해줘야 하는 상황에서
Entity를 전부 전달하지 않고 DTO를 통해 정보를 걸러낸 뒤 DTO를 return 하는 방식으로 사용할 수도 있다.
MemberController
package com.practice.board.controller;
import com.practice.board.dto.MemberFormDTO;
import com.practice.board.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@GetMapping("/")
public String Home() {
return "home";
}
@GetMapping("/members/new")
public String createMemberForm() {
return "members/createMemberForm";
}
@PostMapping("/members/new")
public String createMember(MemberFormDTO memberFormDTO) {
Long memberId = memberService.join(memberFormDTO);
return "home";
}
}
우선 /members/new로 접속하여 Form을 작성할 수 있도록 한다.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>회원가입</title>
</head>
<body>
<div class="container">
<form method="post">
<div class="form_group">
<label for="username">이름</label>
<input type="text" id="username" name="username" placeholder="이름을 입력하세요.">
<label for="email">이메일</label>
<input type="eamil" id="email" name="email" placeholder="이메일을 입력하세요.">
<label for="password">비밀번호</label>
<input type="password" id="password" name="password" placeholder="비밀번호를 입력하세요.">
<button type="submit">회원가입</button>
</div>
</form>
</div>
</body>
</html>
HTML form input name에 적혀있는 내용이 dto 이름과 동일해야 한다.
이렇게 되면 form으로 post한 내용을 DTO가 받아서
@PostMapping("/members/new")
public String createMember(String email, String username, String password) {
....
}
이런 식으로 인자를 따로 받지 않고 DTO만 인자로 받아주면 된다.
TEST
끝.
어노테이션이 의미하는 내용은 주석으로 달아뒀는데 혹시 해당 내용이 아니라면 답변 주시면 감사하겠습니다.
'Java > Spring Boot 게시판' 카테고리의 다른 글
spring boot 게시판 - 6 <bootstrap 적용하기> (0) | 2022.11.22 |
---|---|
spring boot 게시판 - 5 <thymeleaf layout 적용> (0) | 2022.11.21 |
spring boot 게시판 - 4 <spring security form login 구현> (0) | 2022.11.18 |
spring boot 게시판 - 3 <패스워드 암호화, 회원 목록 조회> (0) | 2022.11.11 |
spring boot 게시판 - 2 <회원 중복 체크 및 유효성 검사> (0) | 2022.11.11 |