스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - (32) 로그인 처리 - 쿠키 세션 - 회원 가입
인프런 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술편을 학습하고 정리한 내용 입니다.
회원 가입
도메인
hello.login.domain.member.Member
1
2
3
4
5
6
7
8
9
10
11
12
13
@Data
public class Member {
private Long id;
@NotEmpty
private String loginId; // 사용자 입력 로그인 ID
@NotEmpty
private String name; // 사용자 이름
@NotEmpty
private String password;
}
id 는 pk용이고 loginId는 사용자가 입력한 로그인 id이다.
추가적으로 @NotEmpty로 Validator 사용했다.
리포지토리
hello.login.domain.member.MemberRepository
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@Slf4j
@Repository
public class MemberRepository {
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L; // static
public Member save(Member member) {
member.setId(++sequence);
log.info("save : member={}", member);
store.put(member.getId(), member);
return member;
}
public Member findById(Long id) {
return store.get(id);
}
public Optional<Member> findByLoginId(String loginId) {
return findAll().stream()
.filter(m -> m.getLoginId().equals(loginId))
.findFirst();
/*
위와 같은 코드.
List<Member> all = findAll();
for (Member m : all) {
if (m.getLoginId().equals(loginId)) {
return Optional.of(m);
}
}
return Optional.empty();
*/
}
public List<Member> findAll() {
return new ArrayList<>(store.values());
}
public void clearStore() {
store.clear();
}
}
여기선 DB를 사용하지 않고, 메모리에서만 사용하기 때문에
1
2
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L; // static
이렇게 map 과 시퀀스로 쓸 데이터를 하나 만들어 줬다.
그리고 저장, id로 조회, 로그인 id로 조회, 전체 조회, 테스트때 사용할 초기화 메서드를 만들었다.
다른건 어렵지 않은데,
1
2
3
4
5
public Optional<Member> findByLoginId(String loginId) {
return findAll().stream()
.filter(m -> m.getLoginId().equals(loginId))
.findFirst();
}
로그인 아이디로 멤버를 찾아내는 메서드이다.
스트림을 사용했고 혹시 없을 수도 있기 때문에 Optional로 감싸줬다.
1
2
3
4
5
6
7
8
9
public Optional<Member> findByLoginId(String loginId) {
List<Member> all = findAll();
for (Member m : all) {
if (m.getLoginId().equals(loginId)) {
return Optional.of(m);
}
}
return Optional.empty();
}
이 코드와 같은 의미 이다. Stream 문법을 사용 하니까 가독성이 많이 올라 갔다.
컨트롤러
hello.login.web.member.MemberController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Controller
@RequiredArgsConstructor
@RequestMapping("/members")
public class MemberController {
private final MemberRepository memberRepository;
@GetMapping("/add")
public String addForm(@ModelAttribute("member") Member member) {
return "members/addMemberForm";
}
@PostMapping("/add")
public String save(@Validated @ModelAttribute("member") Member member, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "members/addMemberForm";
}
memberRepository.save(member);
return "redirect:/";
}
}
폼을 띄워주고, 지난번에 배운 Validator를 사용해서 검증도 했다.
이제 뷰 템플릿 만들자.
뷰 템플릿
resources/templates/members/addMemberForm.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link th:href="@{/css/bootstrap.min.css}"
href="../css/bootstrap.min.css" rel="stylesheet">
<style>
.container {
max-width: 560px;
}
.field-error {
border-color: #dc3545;
color: #dc3545;
}
</style>
</head>
<body>
<div class="container">
<div class="py-5 text-center">
<h2>회원 가입</h2>
</div>
<h4 class="mb-3">회원 정보 입력</h4>
<form action="" th:action th:object="${member}" method="post">
<div th:if="${#fields.hasGlobalErrors()}">
<p class="field-error" th:each="err : ${#fields.globalErrors()}" th:text="${err}">전체 오류 메시지</p>
</div>
<div>
<label for="loginId">로그인 ID</label>
<input type="text" id="loginId" th:field="*{loginId}" class="form-control"
th:errorclass="field-error">
<div class="field-error" th:errors="*{loginId}"></div>
</div>
<div>
<label for="password">비밀번호</label>
<input type="password" id="password" th:field="*{password}" class="form-control"
th:errorclass="field-error">
<div class="field-error" th:errors="*{password}"></div>
</div>
<div>
<label for="name">이름</label>
<input type="text" id="name" th:field="*{name}" class="form-control"
th:errorclass="field-error">
<div class="field-error" th:errors="*{name}"></div>
</div>
<hr class="my-4">
<div class="row">
<div class="col">
<button class="w-100 btn btn-primary btn-lg" type="submit">회원 가입</button>
</div>
<div class="col">
<button class="w-100 btn btn-secondary btn-lg" onclick="location.href='items.html'"
th:onclick="|location.href='@{/}'|"
type="button">취소</button>
</div>
</div>
</form>
</div> <!-- /container -->
</body>
</html>

검증도 잘 된다.


지금 따로 처리가 없어서, 로그에서 가입이 된걸 볼 수 있다.
댓글남기기