Spring - JavaScript방식 Ajax(1)

맑은 눈의 코드 👀·2023년 8월 17일
0

06_framework 이론

목록 보기
11/23

👀fetch()API

  • JS의 Promise 객체를 이용한 비동기 요청 방법으로 JS에서 기본 제공함
  • Promise(약속)객체: 비동기 요청에 대한 처리가 완료되면 바로 결과를 제공하겠다고 약속 -> 비동기 요청시 동시에 다른 JS 코드가 실행되고 있음
  • fetch(가지고오다)API :비동기 요청이 끝나면 응답 결과를 가져와서 현재화면에서 다룰 수 있는 방법을 제공하는 API

💎요청 방식에 따른 작성 방법

⛏️GET 방식

fetch("요청주소") // 지정된 주소로 GET방식 비동기 요청(ajax)
// 전달하고자 하는 파라미터를 주소 뒤 쿼리스트링으로 추가
.then(response => response 파싱 ) // 요청에 대한 응답 객체(response)를 필요한 형태로 파싱
.then(response 파싱 데이터 => {}) // 첫 번째 then에서 파싱한 데이터를 이용한 동작 작성
.catch( e => {}) // 예외 발생 시 처리할 내용을 작성

⛏️POST 방식

fetch("요청주소“, { // 지정된 주소로 비동기 요청(ajax)
method : “POST”, // 데이터 전달 방식을 POST로 지정
headers: {"Content-Type": "application/json"}, // 요청 데이터의 형식을 JSON으로 지정
body : JSON.stringify( {K:V, K:V} ) // JS객체를 JSON 형태로 변환하여 Body에 추가
})
.then(response => response 파싱 ) // 요청에 대한 응답 객체(response)를 필요한 형태로 파싱
.then(response 파싱 데이터 => {}); // 첫 번째 then에서 파싱한 데이터를 이용한 동작 작성
.catch( err => {}) // 예외 발생 시 처리할 내용을 작성

👷자, Get방식으로 Ajax 먼저 해보자!

main.js

const loginFrm = document.getElementById("loginFrm");

const memberEmail = document.querySelector("#loginFrm input[name='memberEmail']");
const memberPw = document.querySelector("#loginFrm input[name='memberPw']");


if(loginFrm != null){

    //로그인 시도를 할 때 
    loginFrm.addEventListener("submit", e =>{
        //alert("로그인");
    
        if(memberEmail.value.trim() == "" ){
            alert("이메일을 입력해주세요");
            // form 기본 이벤트 제거 
           
            //잘못입력된 값(공백)제거
            //이메일 input 태그에 초점 맞추기
            
            memberEmail.value ="";
            memberEmail.focus();
            //제출 못하게 막기
            e.preventDefault();
            return;
        }
        if(memberPw.value.trim() == "" ){
            alert("비밀번호을 입력해주세요");
            // form 기본 이벤트 제거 
           
            //잘못입력된 값(공백)제거
            //비밀번호 태그에 초점 맞추기
            memberPw.value = "";
            memberPw.focus();
            
            //제출 못하게 막기
            e.preventDefault();
            return;
        }
        
    
    
    });
}

// 비동기로 이메일이 일치하는 회원의 닉네임 조회
function selectNickname(email){
    
    fetch("/selectNickname?email="+ email) 
        // 지정된 주소로 GET방식 비동기 요청(ajax)
        // 전달하고자 하는 파라미터를 주소 뒤 쿼리스트링으로 추가

    .then(response => response.text()) // 요청에 대한 응답 객체(response)를 필요한 형태로 파싱
           //promise객체      //.text() 문자열 형태로 변환
    .then(nickname => {console.log(nickname)}) // 첫 번째 then에서 파싱한 데이터를 이용한 동작 작성

    .catch(e => {console.log(e)}) // 예외 발생시 처리할 내용을 작성

}


// 닉네임이 일치하는 회원의 전화번호 조회
const inputNickname = document.getElementById("inputNickname");
const btn1 = document.getElementById("btn1");
const result1 = document.getElementById("result1");

btn1.addEventListener("click", ()=>{
    
    // fetch()API를 이용해서 Ajax(비동기 통신)

    //GET방식요청(파라미터를 쿼리스트링으로 추가)
    fetch("/selectMemberTel?nickname="+inputNickname.value)
    .then( resp => resp.text() )
    // resp : 응답객체
    // resp : 응답객체의 내용을 문자열로 변환하여 반환
    
    .then( tel => {
        /* 비동기 요청 후 수행할 코드 */
        result1.innerText = tel; // 조회결과를 result1에 출력
    })
    //tel : 파싱되어 반환된 값이 저장된 변수

    .catch( err => console.log(err));
    // 에러 발생 시 콘솔에 출력 


})

signUp.js

const checkObj = {
    "memberEmail" : false
    ,"memberPw": false
    , "memberPwConfirm" : false
    , "memberNickname" : false
    , "memberTel" : false
}

//이메일 유효성 검사 
const memberEmail = document.getElementById("memberEmail");
const emailMessage = document.getElementById("emailMessage");

//이메일이 입력될 때 마다
memberEmail.addEventListener("input",  ()=>{

    //입력된 이메일이 없을 경우 
    if(memberEmail.value.trim().length == 0 ){
        emailMessage.innerText ="";
        
        emailMessage.innerText = "메일을 받을 수 있는 이메일을 입력해주세요";
        
        emailMessage.classList.remove("confirm", "error");
        
        checkObj.memberEmail = false; //빈칸 == 유효 X
        return;
    }
    // 정규 표현식을 이용해서 유효한 형식인지 판별
    // 1) 정규표현식 객체 생성
    const regEx = /^[A-Za-z\d\-\_]{4,}@[가-힣\w\-\_]+(\.\w+){1,3}$/
    


    //2)입력 받은 이메일과 정규식 일치하는지 여부 판별
    if(regEx.test(memberEmail.value)){//유효한 경우

        /***************************************************************** */
        /* fetch()API를 이용한 Ajax(비동기통신) */
        
        // GET 방식 ajax요청(파라미터는 쿼리스트링으로!)
        fetch("/dupCheck/email?email=" + memberEmail.value)
        .then(response => response.text()) // 응답객체 -> 파싱 (parsing , 데이터 형식 변환)
        .then( count => {
            //count : 중복되면 1, 아니면 0 

            if(count == 0){
                emailMessage.innerText="사용가능한 이메일입니다.";
                emailMessage.classList.remove("error");
                emailMessage.classList.add("confirm");
                checkObj.memberEmail = true; // 유효 O
            }else{
                emailMessage.innerText="이미 시용중인 이메일 입니다.";
                emailMessage.classList.remove("confirm");
                emailMessage.classList.add("error");
                checkObj.memberEmail = false; // 유효 O

            }

        }) // 파싱한 데이터를 이용해서 수행할 코드 작성
        .catch( err => console.log(err)) // 예외 처리
        
        /***************************************************************** */

    }else{//유효하지 않은 경우 
        emailMessage.innerText="유효하지 않은 이메일 입니다."
        emailMessage.classList.remove("confirm");
        emailMessage.classList.add("error");

        checkObj.memberEmail = false; //유효 X
    }

})

// 닉네임 유효성 검사 
 const memberNickname = document.getElementById("memberNickname");
 const nickMessage = document.getElementById("nickMessage");

//닉네임이 입력이 되었을 때 
memberNickname.addEventListener("input", ()=>{

    // 닉네임이 입력되지 않은 경우
    if(memberNickname.value.trim().length == 0){
        nickMessage.innerText = "한글,영어,숫자로만 2~10글자"
        nickMessage.classList.remove("error", "confirm");

        checkObj.memberNickname=false;
        memberNickname.value="";
        return;
    }
    
    //정규표현식으로 유효성 검사 
    const regEx = /^[A-Za-z가-힣0-9]{2,10}$/

    if(regEx.test(memberNickname.value)){ //유효O

        /******************************************************/

        fetch("/dupCheck/nickname?nickname="+ memberNickname.value)
        .then(resp => resp.text()) //응답객체를 text로 파싱(변환)
        .then(count => {

            if(count == 0){ // 중복이 아닌 경우
                nickMessage.innerText="사용 가능한 이매일입니다.";
                nickMessage.classList.add("confirm");
                nickMessage.classList.remove("error");

                checkObj.memberNickname=true;

            }else{
                nickMessage.innerText="이미 사용 중인 이메일입니다.";
                nickMessage.classList.add("error");
                nickMessage.classList.remove("confirm");

                checkObj.memberNickname=false;

            }
        })
        .catch( err => console.log(err))
        
        
        /******************************************************/
        
        
    }else{ //무효
        nickMessage.innerText="닉네임이 유효하지 않습니다.";
        nickMessage.classList.add("error");
        nickMessage.classList.remove("confirm");

        checkObj.memberNickname=false;
    }
})

AjaxController.java 클래스

// 닉네임으로 전화번호 조회
	@GetMapping(value = "/selectMemberTel", produces = "application/text; charset=UTF-8")
	@ResponseBody
	public String selectMemberTel(String nickname) {
		// 쿼리스트링에 담긴 파라미터
		// return 리다이렉트 / 포워드; -> 새로운 화면이 보임(동기식)

		// return 데이터; -> 데이터를 요청한 곳으로 반환(비동기식)

		return service.selectMemberTel(nickname);
	}

AjaxService.java 인터페이스

package edu.kh.project.member.model.service;

public interface AjaxService {

	/** 이메일로 닉네임 조회
	 * @param email
	 * @return nickname
	 */
	String selectNickname(String email);

	/** 닉네임으로 전화번호 조회
	 * @param nickname
	 * @return tel
	 */
	String selectMemberTel(String nickname);

	/** 이메일 중복검사
	 * @param email
	 * @return count
	 */
	int dupCheckEmail(String email);

	/** 닉네임 중복검사
	 * @param nickname
	 * @return count
	 */
	int dupCheckNickname(String nickname);

}

AjaxServiceImpl.java 클래스

package edu.kh.project.member.model.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import edu.kh.project.member.model.dao.AjaxDAO;

@Service // 서비스임을 명시 + bean등록
public class AjaxServiceImpl implements AjaxService{
	
	@Autowired // DI
	private AjaxDAO dao;
	
	// 이메일로 닉네임 조회dao
	@Override
	public String selectNickname(String email) {

		return dao.selectNickname(email);
	}

	// 닉네임으로 전화번호 조회
	@Override
	public String selectMemberTel(String nickname) {
		return dao.selectMemberTel(nickname);
	}
	
	// 이메일 중복검사
	@Override
	public int dupCheckEmail(String email) {
		return dao.dupCheckEmail(email);
	}
	
	//닉네임 중복검사 
	@Override
	public int dupCheckNickname(String nickname) {
		return dao.dupCheckNickname(nickname);
	}
}

AjaxDAO.java 클래스

package edu.kh.project.member.model.dao;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository // DB 연결 의미 + bean등록
public class AjaxDAO {
	
	@Autowired // bean 중에서 타입이 같은 객체를 DI
	private SqlSessionTemplate sqlSession;

	/** 이메일로 닉네임 조회
	 * @param email
	 * @return nickname
	 */
	public String selectNickname(String email) {

		return sqlSession.selectOne("ajaxMapper.selectNickname", email);
	}

	/** 닉네임으로 전화번호 조회
	 * @param nickname
	 * @return tel
	 */
	public String selectMemberTel(String nickname) {
		return sqlSession.selectOne("ajaxMapper.selectMemberTel", nickname);
	}

	/** 이메일 중복검사 
	 * @param email
	 * @return count
	 */
	public int dupCheckEmail(String email) {
		return sqlSession.selectOne("ajaxMapper.checkEmail", email);
	}

	/** 닉네임 중복검사
	 * @param nickname
	 * @return count
	 */
	public int dupCheckNickname(String nickname) {
		return sqlSession.selectOne("ajaxMapper.checkNickname", nickname);
	}

}

ajax-mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="ajaxMapper">

	<!-- 이메일로 닉네임조회 -->
	<select id="selectNickname" parameterType="string" resultType="string">
		SELECT MEMBER_NICKNAME
		FROM MEMBER
		WHERE MEMBER_EMAIL=#{email}
		AND MEMBER_DEL_FL= 'N'
	</select>
	
	<!-- 닉네임으로 전화번호 조회 -->
	<!--  parameterType : 전달 받은 파라미터의 자료형 작성(선택사항)
				-> 작성을 안하면 TypeHandler가 알아서 처리
	 -->
	<select id="selectMemberTel" resultType="string">
		SELECT MEMBER_TEL
		FROM MEMBER
		WHERE MEMBER_NICKNAME = #{nickname}
		AND MEMBER_DEL_FL= 'N'
	</select>
	
	<!-- 이메일 중복검사 -->
	<select id="checkEmail" resultType="_int">
		SELECT COUNT(*) FROM MEMBER
		WHERE MEMBER_EMAIL = #{email}
		AND MEMBER_DEL_FL = 'N'
	</select>
	
	<!-- 닉네임 중복검사 -->
	<select id="checkNickname" resultType="_int">
		SELECT COUNT(*) FROM MEMBER
		WHERE MEMBER_NICKNAME = #{nickname}
		AND MEMBER_DEL_FL = 'N'
	</select>

</mapper>
profile
나를 죽이지 못하는 오류는 내 코드를 더 강하게 만들지ㅋ

0개의 댓글