ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [김영한 스프링] 32. 로그인 처리1 쿠키, 세션 - 홈 화면 & 회원 가입
    Spring/스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 2023. 9. 12. 03:37

    홈 화면

     

    HomeController - home() 수정

    package hello.login.web;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Slf4j
    @Controller
    public class HomeController {
    
        @GetMapping("/")
        public String home() {
            return "home";
        }
    }

     

     

    templates/home.html 추가

    <!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">
    </head>
    
    <body>
    
    <div class="container" style="max-width: 600px">
        <div class="py-5 text-center">
            <h2>홈 화면</h2>
        </div>
    
        <div class="row">
            <div class="col">
                <button class="w-100 btn btn-secondary btn-lg" type="button"
                        th:onclick="|location.href='@{/members/add}'|">
                    회원 가입
                </button>
            </div>
            <div class="col">
                <button class="w-100 btn btn-dark btn-lg" onclick="location.href='items.html'"
                        th:onclick="|location.href='@{/login}'|" type="button">
                    로그인
                </button>
            </div>
        </div>
    
        <hr class="my-4">
    
    </div> <!-- /container -->
    
    </body>
    </html>

    main/resources/templates/home.html 생성

     

     

    실행

     

     

    회원 가입

     

    Member

    package hello.login.domain.member;
    
    import lombok.Data;
    
    import javax.validation.constraints.NotEmpty;
    
    @Data
    public class Member {
    
        private Long id;
    
        @NotEmpty
        private String loginId; // 로그인 id
    
        @NotEmpty
        private String name; // 사용자 이름
    
        @NotEmpty
        private String password;
    }

    main/java/hello/login/domain/member/Member 생성

     

     

    MemberRepository

    main/java/hello/login/domain/member/MemberRepository 생성

     

     

    package hello.login.domain.member;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Repository;
    
    import java.util.*;
    
    /**
     * 동시성 문제가 고려되어 있지 않음, 실무에서는 ConcurrentHashMap, AtomicLong 사용 고려
     */
    @Slf4j
    @Repository
    public class MemberRepository {
    
        private static Map<Long, Member> store = new HashMap<>(); // static 사용
        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 Member findByLoginId(String loginId) {
    //        List<Member> all = findAll();
    //        for (Member m : all) {
    //            if (m.getLoginId().equals(loginId)) {
    //                return m;
    //            }
    //        }
    //
    //        return null;
    //    }
    
        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();
    
            return findAll().stream().filter(m -> m.getLoginId().equals(loginId)).findFirst();
        }
    
        public List<Member> findAll() {
            return new ArrayList<>(store.values());
        }
    
        public void clearStore() {
            store.clear();
        }
    }

     

     

    MemberController

    main/java/hello/login/web/member/MemberRepository 생성

     

     

    package hello.login.web.member;
    
    import hello.login.domain.member.Member;
    import hello.login.domain.member.MemberRepository;
    import lombok.RequiredArgsConstructor;
    import org.springframework.stereotype.Controller;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.validation.Valid;
    
    @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(@Valid @ModelAttribute Member member, BindingResult bindingResult) {
            if (bindingResult.hasErrors()) {
                return "members/addMemberForm";
            }
    
            memberRepository.save(member);
    
            return "redirect:/";
        }
    }

    @ModelAttribute("member")를 @ModelAttribute로 변경해도 결과는 같다. 여기서는 IDE에서 인식 문제가 있어서 적용했다.

     

     

    회원 가입 뷰 템플릿 - addMemberForm.html

    <!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>
                <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>
                <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>
    
            <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>

    main/resources/templates/member/addMemberForm.html 생성

     

     

    실행

     

     

    결과

     

     

    회원용 테스트 데이터 추가

    편의상 테스트용 회원 데이터를 추가하자.

    • loginId : test
    • password : test!
    • name : 테스터

     

     

    TestDataInit

    package hello.login;
    
    import hello.login.domain.item.Item;
    import hello.login.domain.item.ItemRepository;
    import hello.login.domain.member.Member;
    import hello.login.domain.member.MemberRepository;
    import lombok.RequiredArgsConstructor;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    
    @Component
    @RequiredArgsConstructor
    public class TestDataInit {
    
        private final ItemRepository itemRepository;
        private final MemberRepository memberRepository;
    
        /**
         * 테스트용 데이터 추가
         */
        @PostConstruct
        public void init() {
            itemRepository.save(new Item("itemA", 10000, 10));
            itemRepository.save(new Item("itemB", 20000, 20));
    
            Member member = new Member();
            member.setLoginId("test");
            member.setPassword("test!");
            member.setName("테스터");
    
            memberRepository.save(member);
        }
    
    }

     

     

    실행

     

     

    출처 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2

     

    스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의

    웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있

    www.inflearn.com

Designed by Tistory.