@PostMapping("/register")
public String registerMember(@ModelAttribute Member member, RedirectAttributes redirectAttributes, Model model) {

    // 검증 오류 결과 보관
    Map<String, String> errors = new HashMap<>();

    // 검증 로직
    if (ObjectUtils.isEmpty(member.getId())) {
        errors.put("id", 아이디를 입력하셔야합니다.");
    }
    
    if (!ObjectUtils.isEmpty(member.getId()) 
        && !ObjectUtils.isEmpty(memberService.getMemberById(member.getId()))) {
        errors.put("id", "이미 존재하는 아이디입니다");
    }
    
    String pattern = "(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,20}";
    if (ObjectUtils.isEmpty(member.getPassword())
            || !(member.getPassword().matches(pattern))) {
        errors.put("password", "패스워드는 대문자, 소문자, 특수문자가 적어도 하나씩은 있어야 하며 최소 8자리여야 하며 최대 20자리까지 가능합니다.");
    }
                   
    if (ObjectUtils.isEmpty(member.getYear())
            || !(member.getYear() >= 1900 && member.getYear() <= 2021)) {
        errors.put("year", "태어난 해는 1900 ~ 2021 사이 숫자여야합니다.");   
    }
                   
    // 검증에 실패하면 다시 입력 폼으로
    if (errors.isEmpty() == false) {
        model.addAttribute("errors", errors);
        return "register";
    }
                   
    // 성공 로직
    redirectAttributes.addAttribute("memberId", member.getId());
    redirectAttributes.addAttribute("successYn", "Y");
    
    return "redirect:/member/{memberId}";
}