본문 바로가기
스프링과 JPA 기반 웹 어플리케이션 개발/1부 (개발환경, 회원가입, 로그인, 계정설정)

28. 알림 설정

by Backchus 2020. 4. 22.

알림 설정 뷰

 

알림 설정

  • 특정 웹 서비스 이벤트(스터디 생성, 참가 신청 결과, 참여중인 스터디)에 대한 정보를 이메일로 받을지, 웹 알림 메시지로 받을지 선택하는 기능. 물론 둘 다 받을 수도 있음.

부트스트랩

  • Form

알림 설정을 전달할 Notifications DTO 작성

package me.weekbelt.studyolle.settings;

@Data
@NoArgsConstructor
public class Notifications {

    private boolean studyCreatedByEmail;

    private boolean studyCreatedByWeb;

    private boolean studyEnrollmentResultByEmail;

    private boolean studyEnrollmentResultByWeb;

    private boolean studyUpdatedByEmail;

    private boolean studyUpdatedByWeb;

    public Notifications(Account account) {
        this.studyCreatedByEmail = account.isStudyCreatedByEmail();
        this.studyCreatedByWeb = account.isStudyCreatedByWeb();
        this.studyEnrollmentResultByEmail = account.isStudyEnrollmentResultByEmail();
        this.studyEnrollmentResultByWeb = account.isStudyEnrollmentResultByWeb();
        this.studyUpdatedByEmail = account.isStudyUpdatedByEmail();
        this.studyUpdatedByWeb = account.isStudyUpdatedByWeb();
    }
}

 

알림 폼 페이지를 위한 GET 요청과 알림을 처리하는 POST요청을 위한 핸들러 추가

package me.weekbelt.studyolle.settings;
port javax.validation.Valid;

@RequiredArgsConstructor
@Controller
public class SettingsController {
    
    // 기존 코드 ......

    @GetMapping("/settings/notifications")
    public String updateNotificationsForm(@CurrentUser Account account, Model model) {
        model.addAttribute(account);
        model.addAttribute(new Notifications(account));
        return "settings/notifications";
    }

    @PostMapping("/settings/notifications")
    public String updateNotifications(@CurrentUser Account account, @Valid Notifications notifications,
                                      Errors errors, Model model, RedirectAttributes attributes) {
        if (errors.hasErrors()) {
            model.addAttribute(account);
            return "settings/notifications";
        }

        accountService.updateNotifications(account, notifications);
        attributes.addFlashAttribute("message", "알림 설정을 변경했습니다.");
        return "redirect:" + "/settings/notifications";
    }
}

 

알림 처리를 위한 updateNotifications메소드를 SettingsService에 추가

package me.weekbelt.studyolle.account;

@Transactional
@RequiredArgsConstructor
@Service
public class AccountService implements UserDetailsService {

    // 기존 코드 ........

    public void updateNotifications(Account account, Notifications notifications) {
        account.setStudyCreatedByEmail(notifications.isStudyCreatedByEmail());
        account.setStudyCreatedByWeb(notifications.isStudyCreatedByWeb());
        account.setStudyUpdatedByEmail(notifications.isStudyUpdatedByEmail());
        account.setStudyUpdatedByWeb(notifications.isStudyUpdatedByWeb());
        account.setStudyEnrollmentResultByEmail(notifications.isStudyEnrollmentResultByEmail());
        account.setStudyEnrollmentResultByWeb(notifications.isStudyEnrollmentResultByWeb());
        accountRepository.save(account);
    }
}

 

Account엔티티 수정

package me.weekbelt.studyolle.domain;

@Builder @AllArgsConstructor @NoArgsConstructor
@Getter @Setter @EqualsAndHashCode(of = "id")
@Entity
public class Account {

    // 기존 코드 ............

    private boolean studyCreatedByEmail;

    private boolean studyCreatedByWeb = true;              // true로 수정

    private boolean studyEnrollmentResultByEmail;

    private boolean studyEnrollmentResultByWeb = true;     // true로 수정

    private boolean studyUpdatedByEmail;

    private boolean studyUpdatedByWeb = true;              // true로 수정

    private LocalDateTime emailCheckTokenGeneratedAt;

    // 기존 코드 ...............
}

 

알림설정을 보여주는 settings/notifications.html 작성

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<!--head-->
<head th:replace="fragments.html::head"></head>

<body class="bg-light">
<!--네비게이션 바-->
<div th:replace="fragments.html::main-nav"></div>

<div class="container">
    <div class="row mt-5 justify-content-center">
        <div class="col-2">
            <div th:replace="fragments.html :: settings-menu(currentMenu='notifications')"></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">x</span>
                </button>
            </div>
            <div class="row">
                <h2 class="col-sm-12">알림 설정</h2>
            </div>
            <div class="row mt-3">
                <form class="col-12" action="#" th:action="@{/settings/notifications}" th:object="${notifications}" method="post" novalidate>
                    <div class="alert alert-light" role="alert">
                        <strong><a href="#" th:href="@{/settings/locations}">주요 활동 지역</a>에
                            <a href="#" th:href="@{/settings/keywords}">관심있는 주제</a>의 스터디가 만들어졌을 때</strong> 알림을 받을 방법을 설정하세요.
                    </div>
                    <div class="form-group">
                        <div class="custom-control custom-switch custom-control-inline">
                            <input type="checkbox" th:field="*{studyCreatedByEmail}" class="custom-control-input" id="studyCreatedByEmail">
                            <label class="custom-control-label" for="studyCreatedByEmail">이메일로 받기</label>
                        </div>
                        <div class="custom-control custom-switch custom-control-inline">
                            <input type="checkbox" th:field="*{studyCreatedByWeb}" class="custom-control-input" id="studyCreatedByWeb">
                            <label class="custom-control-label" for="studyCreatedByWeb">웹으로 받기</label>
                        </div>
                    </div>
                    <div class="alert alert-light" role="alert">
                        <strong>스터디 모임 참가 신청</strong> 결과 알림을 받을 방법을 설정하세요.
                    </div>
                    <div class="form-group">
                        <div class="custom-control custom-switch custom-control-inline">
                            <input type="checkbox" th:field="*{studyEnrollmentResultByEmail}" class="custom-control-input" id="studyEnrollmentResultByEmil">
                            <label class="custom-control-label" for="studyEnrollmentResultByEmil">이메일로 받기</label>
                        </div>
                        <div class="custom-control custom-switch custom-control-inline">
                            <input type="checkbox" th:field="*{studyEnrollmentResultByWeb}" class="custom-control-input" id="studyEnrollmentResultByWeb">
                            <label class="custom-control-label" for="studyEnrollmentResultByWeb">웹으로 받기</label>
                        </div>
                    </div>
                    <div class="alert alert-light" role="alert">
                        <strong>참여중인 스터디</strong>에 대한 알림을 받을 방법을 설정하세요.
                    </div>
                    <div class="form-group">
                        <div class="custom-control custom-switch custom-control-inline">
                            <input type="checkbox" th:field="*{studyUpdatedByEmail}" class="custom-control-input" id="studyWatchByEmail">
                            <label class="custom-control-label" for="studyWatchByEmail">이메일로 받기</label>
                        </div>
                        <div class="custom-control custom-switch custom-control-inline">
                            <input type="checkbox" th:field="*{studyUpdatedByWeb}" class="custom-control-input" id="studyWatchByWeb">
                            <label class="custom-control-label" for="studyWatchByWeb">웹으로 받기</label>
                        </div>
                    </div>
                    <div class="form-group">
                        <button class="btn btn-outline-primary" type="submit" aria-describedby="submitHelp">저장하기</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!-- footer -->
    <div th:replace="fragments.html::footer"></div>
</div>
<script th:replace="fragments.html::form-validation"></script>
</body>
</html>

 

 

참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1#

 

스프링과 JPA 기반 웹 애플리케이션 개발 - 인프런

이 강좌에서 여러분은 실제로 운영 중인 서비스를 스프링, JPA 그리고 타임리프를 비롯한 여러 자바 기반의 여러 오픈 소스 기술을 사용하여 웹 애플리케이션을 개발하는 과정을 학습할 수 있습니다. 이 강좌를 충분히 학습한다면 여러분 만의 웹 서비스를 만들거나 취직에 도움이 될만한 포트폴리오를 만들 수 있을 겁니다. 활용 웹 개발 프레임워크 및 라이브러리 Java Spring Spring Boot Spring Data JPA Thymeleaf 온라인 강의 스

www.inflearn.com