SimpleEats 토이 프로젝트 (5)

유승선 ·2022년 11월 1일
0
post-thumbnail

Progress

Progress(클라이언트 홈 화면 / 가게 업주 홈 화면)

처음 프로젝트 구현을 생각할때 생각했던 기능이다. 우리가 흔하게 배달 어플을 사용할때도 음식을 시키는 손님과 음식을 등록시키는 가게의 화면은 다르고 각자 다른 화면에서 다른 구현을 할 수 있게 만드는게 처음 목표였고 원하는 구현을 할 수 있어서 기분 좋았다.

Progress(Home Controller)

@Controller
@RequiredArgsConstructor
@Slf4j
public class HomeController {
    private final LoginService loginService;
    private final MemberService memberService;
    @GetMapping("/")
    public String Home(@SessionAttribute(value = "loginMember", required = false) Member loginMember, Model model){

        if(loginMember == null){
            return "home";
        }

        model.addAttribute("member", loginMember);

        if(memberService.isCustomer(loginMember)){
            return "customerHome";
        }

        return "ownerHome";
    }

    @GetMapping("/login")
    public String login(@ModelAttribute("loginForm") LoginForm form){
        return "login";
    }

    @PostMapping("/login")
    public String loginUser(@Valid @ModelAttribute LoginForm form, BindingResult result, HttpServletRequest request){
        if(result.hasErrors()){
            return "login";
        }
        Member validatedMember = loginService.validate(form.getUserId(),form.getUserPassword());

        if(validatedMember == null){
            result.reject("loginFail", "아이디 또는 비밀번호가 맞지않습니다");
            return "login";
        }

        //로그인 정보가 맞다
        HttpSession session  = request.getSession();

        //세션에 멤버와 멤버 정보를 저장한다.
        session.setAttribute("loginMember", validatedMember);

        return "redirect:/";
    }

    @PostMapping("/logout")
    public String logout(HttpServletRequest request){
        HttpSession session = request.getSession(false);
        if(session != null){
            session.invalidate();
        }
        return "home";
    }
}

화면에서도 보이지만 원래 /login 매핑은 MemberController 안에 있었지만 점점 로직을 생각하다보니 HomeController 화면에 있는게 더 말이 맞는거 같아서 아예 통째로 옮겼다. 로그인 정보를 유지하기 위해 기존에 쿠키로 데이터를 넘기는것은 보안상 많은 문제가 있기에 HttpSession 을 사용해서 검증이 된 멤버를 세션에 등록시켰다. 그리고 서비스에서 일반 회원인지를 확인할 수 있는 기능을 만든 다음에 세션을 확인하고 멤버 정보를 이용해 위에 화면과 같이 사용자의 이름을 동적으로 올릴 수 있게 구현했다.

Progress(Login Service)

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
    private final MemberRepository memberRepository; //생성자로 주입

    @Transactional
    public Long join(Member member){
        memberRepository.save(member);
        return member.getId(); //확인할 수 있다.
    }

    public boolean isCustomer(Member member){
        return member.getMemberType().getDescription() == "일반 회원";
    }

}

구현을 하면서 생각이 들었던게 컨트롤러가 리포지토리를 직접 사용하는것은 MVC 패턴이랑 너무 어긋난다고 생각했다. 강의에서는 이해 못했지만 구현 로직을 생각하면 컨트롤러는 컨트롤러의 역활만 해야한다고 생각했기 때문에 회원에 일반 / 가게를 구분하기 위한 로직으로 멤버 서비스 로직에 담아야겠다고 생각했다. 물론 이것보다 더 좋은 방법이 있을 수 있지만 이렇게 구현헀고, 멤버의 타입을 조회하고 getDescription 방식으로 "일반회원" 이랑 일치하는지 bool 값을 리턴했다.


Error

큰 에러까지는 없었고 고치느라 바빠서 실수로 에러 캡쳐를 잘 못했다. 다만 생각나는 에러는 타임리프에서 멤버를 model 로 담았을때 내가 실수로 member 객체에 없는 정보를 접근하려 해서 스프링에서 에러를 주었다.

추가적으로 힘들었던 점은 JPQL을 사용하면서 원하는 정보를 바로 얻는 노하우가 부족한거같아서 아쉬웠다.


배운점, 고친점

원하는 구현을 문제 없이 했지만 그래도 많이 부족한게 느껴진다. 나름 프로젝트 구상하면서 생각했던 화면 구현까지는 성공한거 같다. 다음번에는 핵심기능인 음식 주문/등록을 최대한 구현 가능한 역량안에서 도전해봐야겠다.

profile
성장하는 사람

0개의 댓글