Spring에서 Ajax 사용하기 - 실전편 (GET) (23.08.17)

·2023년 8월 17일
0

Spring

목록 보기
14/36
post-thumbnail

🌷 Spring에서 Ajax 사용하기 - 실전편 (GET)


이전 포스팅에서 개념 알기
Spring에서 Ajax 사용하기 - 이론편


👀 코드로 살펴보기

🌼 이메일로 닉네임 조회

🌱 main.js

// 비동기로 이메일이 일치하는 회원의 닉네임 조회
function selectNickname(email){

    fetch("/selectNickname?email=" + email)
        // 지정된 주소로 GET방식 비동기 요청(ajax)
        // 전달하고자 하는 파라미터를 주소 뒤 쿼리스트링으로 추가

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

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

🌱 AjaxController.java

package edu.kh.project.member.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import edu.kh.project.member.model.service.AjaxService;

@Controller // 요청/응답 제어 + bean 등록
public class AjaxController {
	
	@Autowired // DI
	private AjaxService service;
	
	// 이메일로 닉네임 조회
	@GetMapping(value="/selectNickname", produces = "application/text; charset=UTF-8")
	@ResponseBody
	public String selectNickname(String email) {
									// 쿼리스트링에 담긴 파라미터
		return service.selectNickname(email);
	}
}	

🌱 AjaxService.java

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

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

🌱 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;

	// 이메일로 닉네임 조회
	@Override
	public String selectNickname(String email) {
		return dao.selectNickname(email);
	}
}

🌱 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);
	}
}

🌱 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>
</mapper>  

💻 출력 화면

콘솔에 입력한 이메일에 해당하는 닉네임이 조회되는 모습을 볼 수 있다.


🌼 닉네임으로 전화번호 조회

🌱 main.jsp

...
                <h3>닉네임이 일치하는 회원의 전화번호 조회</h3>

                <input type="text" id="inputNickname">
                <button id="btn1">조회</button>
                <h4 id="result1"></h4>
...

🌱 main.js

...
// 닉네임이 일치하는 회원의 전화번호 조회
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.text() : 응답 객체 내용을 문자열로 변환하여 반환

    .then( tel => {
        /* 비동기 요청 후 수행할 코드 */
        result1.innerText = tel; // 조회 결과를 result1에 출력
    })
    // tel : 파싱되어 반환된 값이 저장된 변수

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

🌱 AjaxController.java

...
	// 닉네임으로 전화번호 조회
	@GetMapping("/selectMemberTel")
	@ResponseBody
	public String selectMemberTel(String nickname) {
									// 쿼리스트링에 담긴 파라미터
		
		// return 리다이렉트 / 포워드; -> 새로운 화면이 보임(동기식)
		
		// return 데이터; -> 데이터를 요청한 곳으로 반환(비동기식)
		
		return service.selectMemberTel(nickname);
	}

🌱 AjaxService.java

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

}

🌱 AjaxServiceImpl.java

...
	// 닉네임으로 전화번호 조회
	@Override
	public String selectMemberTel(String nickname) {
		return dao.selectMemberTel(nickname);
	}
}

🌱 AjaxDAO.java

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

🌱 ajax-mapper.xml

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

💻 출력 화면

input 창에 입력한 닉네임에 해당하는 전화번호가 조회되는 모습을 볼 수 있다.


🌼 이메일 중복 검사

🌱 signUp.js

...
    // 정규 표현식을 이용해서 유효한 형식인지 판별
    // 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.add("confirm");
                emailMessage.classList.remove("error");
        
                checkObj.memberEmail = true; // 유효 O

            } else {
                emailMessage.innerText = "이미 사용 중인 이메일입니다.";
                emailMessage.classList.add("error");
                emailMessage.classList.remove("confirm");
        
                checkObj.memberEmail = false; // 유효 X
            }
        }) // 파싱한 데이터를 이용해서 수행할 코드 작성
 
        .catch(err => console.log(err)) // 예외 처리

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

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

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

})
...

🌱 AjaxController.java

...
	// 이메일 중복 검사
	@GetMapping("/dupCheck/email")
	@ResponseBody // HttpMessageConverter를 이용해
				  // JS에서 인식할 수 있는 형태(TEXT/JSON) 반환
				  // + 비동기 요청한 곳으로 돌아감
	public int checkEmail(String email) {
		return service.checkEmail(email);
	}

🌱 AjaxService.java

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

🌱 AjaxServiceImpl.java

...
	// 이메일 중복 검사
	@Override
	public int checkEmail(String email) {
		return dao.checkEmail(email);
	}

🌱 AjaxDAO.java

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

🌱 ajax-mapper.xml

...
	<!-- 이메일 중복 검사 -->
	<select id="checkEmail" resultType="_int">
		SELECT COUNT(*) FROM MEMBER
		WHERE MEMBER_EMAIL = #{email}
		AND MEMBER_DEL_FL = 'N'	
	</select>

🌱 pom.xml

💭 Jackson이란?

Java ObjectJson으로 변환하거나 Json을 Java Object로 변환하기 위한 Java 라이브러리

Jackson-databind 라이브러리는 jackson-core 및 jackson-annotation 라이브러리의 의존성을 포함하기 때문에
Maven을 사용하는 경우 pom.xml에 jackson-databind 라이브러리만 추가해 주면 된다. 👍

...
		<!-- Jackson-databind -->
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>2.14.2</version>
		</dependency>
...

🌼 닉네임 중복 검사

🌱 signUp.js

...
    // 정규 표현식으로 유효성 검사
    const regEx = /^[가-힣\w\d]{2,10}$/;

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

        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("/dupCheck/nickname")
	@ResponseBody
	public int checkNickname(String nickname) {
		return service.checkNickname(nickname);
	}

🌱 AjaxService.java

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

🌱 AjaxServiceImpl.java

...
	// 닉네임 중복 검사
	@Override
	public int checkNickname(String nickname) {
		return dao.checkNickname(nickname);
	}

🌱 AjaxDAO.java

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

🌱 ajax-mapper.xml

...
	<!-- 닉네임 중복 검사 -->
	<select id="checkNickname" resultType="_int">
		SELECT COUNT(*) FROM MEMBER
		WHERE MEMBER_NICKNAME = #{nickname}
		AND MEMBER_DEL_FL = 'N'	
	</select>

profile
풀스택 개발자 기록집 📁

0개의 댓글