본문 바로가기

Server Programming/Spring Boot Full-Stack Programming

[스프링 풀스택 클론 코딩 - 계정 설정] (2-9) 닉네임 변경

반응형

1. 리팩토링

패키지별로 구분

com.demo.settings.form

: Nicknameform, Notifications, PasswordForm, Profile, SignUpForm 이동

 

com.demo.settings.validator

: NicknameValidator, PasswordFormValidator 이동

 

2.객체를 미리 검증해주는 nicknameFormInitBinder 작성

: validator를 직접 호출하지 않고 사용할 수 있게 해주는 어노테이션

-> Validator를 사용 시 @Valid 어노테이션으로 검증할 객체를 가져오기 전 수행할 method를 지정해주는 어노테이션

@InitBinder("passwordForm")
public void passwordFormInitBinder(WebDataBinder webDataBinder) {
    webDataBinder.addValidators(new PasswordFormValidator());
}

@InitBinder("nicknameForm")
public void nicknameFormInitBinder(WebDataBinder webDataBinder) {
    webDataBinder.addValidators(nicknameValidator);
}

 


1. 링크 변수 설정

 

SettingsController

//닉네임 설정 위한 뷰 네임, URL
private static final String SETTINGS_ACCOUNT_VIEW_NAME="settings/account";
private static final String SETTINGS_ACCOUNT_URL="/"+SETTINGS_ACCOUNT_VIEW_NAME;

2. 변경 설정 처리 [폼과 변경]

//닉네임 변경 설정 처리
@GetMapping(SETTINGS_ACCOUNT_URL)
public String updateAccountForm(@CurrentUser Account account, Model model) {
    model.addAttribute(account);
    model.addAttribute(modelMapper.map(account, NicknameForm.class));
    return SETTINGS_ACCOUNT_VIEW_NAME;
}
//닉네임 변경 처리
@PostMapping(SETTINGS_ACCOUNT_URL)
// 현재 업데이트하려는 사용자는 현재 사용자, valid를 통해 바인딩하고 검증, 바인딩을 담을 모델, 만약 에러발생시 에러 바인딩받는 객체,
// 잘 되었을 경우 메시지 전송
public String updateNickname(@CurrentUser Account account, @Valid NicknameForm nicknameForm, Errors errors,
                             Model model, RedirectAttributes attributes){
    if (errors.hasErrors()) {
        model.addAttribute(account);
        return SETTINGS_ACCOUNT_VIEW_NAME;
    }
    accountService.updateNickname(account, nicknameForm.getNickname());
    attributes.addFlashAttribute("message", "닉네임을 변경했습니다.");
    return "redirect:" + SETTINGS_ACCOUNT_URL;
}

 

3. Account에 적용하고, DB에 반영

 

AccountService의 updateNickname 메서드

//닉네임 변경
public void updateNickname(Account account, String nickname) {
    account.setNickname(nickname);
    accountRepository.save(account);
    //detached객체이기 때문에 변경이력을 감지하지 않기 때문에 직접 저장 -> DB 저장
    login(account);
    //닉네임 변경후 재로그인을 통해 프론트엔드에 닉네임 변경사항을 적용하기 위해서
}

 

4. 페이지 설정

 

Account

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments.html :: head"></head>
<body class="bg-light">
    <nav th:replace="fragments.html :: main-nav"></nav>
    <div class="container">
        <div class="row mt-5 justify-content-center">
            <div class="col-2">
                <div th:replace="fragments.html :: settings-menu(currentMenu='account')"></div>
            </div>
            <div class="col-8">
                <div th:if="${message}" class="alert alert-info alert-dismissible fade show mt-3" role="alert">
                    <span th:text="${message}">완료</span>
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="row">
                    <h2 class="col-12">닉네임 변경</h2>
                </div>
                <div class="row">
                    <form class="needs-validation col-12" th:object="${nicknameForm}" th:action="@{/settings/account}" method="post" novalidate>
                        <div class="alert alert-warning" role="alert">
                            닉네임을 변경하면 프로필 페이지 링크도 바뀝니다!
                        </div>
                        <div class="form-group">
                            <input id="nickname" type="text" th:field="*{nickname}" class="form-control" aria-describedby="nicknameHelp" required>
                            <small id="nicknameHelp" class="form-text text-muted">
                                공백없이 문자와 숫자로만 3자 이상 20자 이내로 입력하세요. 가입후에 변경할 수 있습니다.
                            </small>
                            <small class="invalid-feedback">닉네임을 입력하세요.</small>
                            <small class="form-text text-danger" th:if="${#fields.hasErrors('nickname')}" th:errors="*{nickname}">nickname Error</small>
                        </div>
                        <div class="form-group">
                            <button class="btn btn-outline-primary" type="submit" aria-describedby="submitHelp">변경하기</button>
                        </div>
                    </form>
                </div>
                <div class="dropdown-divider"></div>
                <div class="row">
                    <div class="col-sm-12">
                        <h2 class="text-danger">계정 삭제</h2>
                        <div class="alert alert-danger" role="alert">
                            이 계정은 삭제할 수 없습니다.
                        </div>
                        <button class="btn btn-outline-danger disabled">계정 삭제</button>
                    </div>
                </div>
            </div>
        </div>

        <div th:replace="fragments.html :: footer"></div>
    </div>
    <script th:replace="fragments.html :: form-validation"></script>
</body>
</html>
반응형