전체 흐름 요약


[요청]  /find/check/password.do?uid=xxx&email=xxx
   ↓
[PASSCheckController]
   ↓ (service.findUserByUidAndEmail)
[UserService]
   ↓ (dao.selectUserByUidAndEmail)
[UserDAO] → DB 조회 (uid, email 일치 확인)
   ↑
[UserDTO 생성 (uid 값으로 인증 성공/실패 판단)]
   ↑
[인증번호 이메일 발송 후 code 생성 및 세션에 저장]
   ↑
[JSON 응답: {uid, code}]


정리

항목 예시
페이지/기능명 비밀번호 찾기 - 이메일 인증
사용 기술 JSP, Servlet, Java, AJAX, JSON, JavaMail API
주요 흐름 Controller → Service → DAO → DTO → 이메일 전송 → JSON 응답
클라이언트 처리 JavaScript로 인증번호 발송, 인증코드 입력, 인증 성공 시 다음 단계 이동
설계 의도 보안성 확보를 위해 이메일 인증번호 발송 및 세션에 저장, AJAX 비동기 처리

[1] password_find.jsp — 비밀번호 찾기 화면


<form name="formRegister">
    <input type="text" name="uid" placeholder="아이디 입력"/>
    <input type="email" name="email" placeholder="이메일 입력"/>
    <button id="btnSendEmail">인증번호 받기</button><span class="emailResult"></span>

    <input type="text" name="authCode" placeholder="인증번호 입력"/>
    <button id="btnAuthCode">확인</button><span class="codeResult"></span>

    <a href="#" id="next">다음</a>
</form>

<script>
document.addEventListener('DOMContentLoaded', function() {
    let code = "";
    let preventDoubleClick = false;
    let nextBtnClick = false;

    // 이메일 인증번호 요청
    btnSendEmail.onclick = async function(e) {
        e.preventDefault();
        if(preventDoubleClick) return;

        const uid = formRegister.uid.value;
        const email = formRegister.email.value;
        preventDoubleClick = true;

        const response = await fetch('/farmStory/find/check/password.do?uid='+uid+'&email='+email);
        const data = await response.json();
        code = data.code;

        if(data.uid !== "인증실패"){
            emailResult.innerText = "이메일로 인증번호를 발송했습니다.";
            emailResult.style.color = "green";
        } else {
            emailResult.innerText = "이메일이 일치하지 않습니다.";
            emailResult.style.color = "red";
        }
        preventDoubleClick = false;
    };

    // 인증번호 확인
    btnAuthCode.onclick = function(e) {
        e.preventDefault();
        if(formRegister.authCode.value === code){
            codeResult.innerText = "인증에 성공하셨습니다.";
            codeResult.style.color = "green";
            nextBtnClick = true;
        } else {
            codeResult.innerText = "인증에 실패하셨습니다.";
            codeResult.style.color = "red";
        }
    };

    // 다음 버튼 (비밀번호 변경 페이지로 이동)
    next.onclick = function(e) {
        e.preventDefault();
        if(nextBtnClick){
            location.href = "./changePassword.do";
        } else {
            alert("인증하세요");
        }
    };
});
</script>

[2] PASSCheckController.java — 인증번호 발송 및 사용자 검증 서블릿

java
코드 복사
@WebServlet("/find/check/password.do")
public class PASSCheckController extends HttpServlet {
    private UserService userservice = UserService.INSTANCE;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uid = req.getParameter("uid");
        String email = req.getParameter("email");
        String code = "";

        UserDTO dto = userservice.findUserByUidAndEmail(uid, email);

        if(dto.getUid().equals("인증실패")) {
            // 인증 실패 시
            code = "";
        } else {
            // 인증 성공 시 이메일 인증번호 발송
            code = userservice.sendEmailCode(email);
            HttpSession session = req.getSession();
            session.setAttribute("sessAuthCode", code);
            session.setAttribute("sessUser", dto);
        }

        // JSON 응답 생성
        JsonObject json = new JsonObject();
        json.addProperty("uid", dto.getUid());
        json.addProperty("code", code);

        resp.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = resp.getWriter();
        writer.println(json);
    }
}

[3] UserService.java — 사용자 검증 및 인증번호 발송

java
코드 복사
public UserDTO findUserByUidAndEmail(String uid, String email) {
    return dao.selectUserByUidAndEmail(uid, email);
}

public String sendEmailCode(String receiver) {
    int code = ThreadLocalRandom.current().nextInt(100000, 1000000);
    // Gmail SMTP 설정 및 메일 전송 로직
    // 생략...

    return String.valueOf(code);
}