프론트엔드/Ajax

AJAX 실습 - GET 방식 구현

두개의 문 2023. 8. 18. 16:02

◉ 예제 실습 

▪︎ 이전 시간에 실습하던 HelloJSON 프로젝트에서 진행 

 

▪︎ 의존성 추가 

 

▪︎ templates 폴더에 index.html 생성 

  - html 파일에 css 스타일 적용  

    : <style> 태그 안에 입력 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ajax (XMLHttpRequest 객체 이용) 연습</title>
<style >
    * {
        text-align : center;
    }

    div {
        padding: 30px 30px 100px 30;
        border: 5px solid lightblue;
    }
</style>

</head>
<body>
    <div id="contents">
        <p>
            <a href="ajax/getAjaxExam"> 
                <h1>Ajax GET 연습</h1>
            </a>
        </p>
        <p>
            <a href="ajax/postAjaxExam">
                <h1>Ajax POST 연습</h1>
            </a>
        </p>
        <p>
            <a href="ajax/member/all">
                <h1>Ajax GET 연습 (member 목록 요청)</h1>
            </a>
        </p>
    </div>
</body>
</html>

 

 

▪︎ AjaxExamController.java 생성 

@Controller
@Slf4j
public class AjaxExamController {
    // * http://localhost/  
    //   또는 http://localhost 주소에 대한 요청 처리 
    //  - http://localhost : 기본값으로 루트 생략됨 
    @GetMapping("/")
    public String home() {
    	return "index";
    }	
}

 

 

▪︎ 실행 결과 

 

 - Ajax GET 연습 클릭 시, 현재 서버에 문서가 존재하지 않으므로 404 에러 발생 

 

 

▪︎ templates/ajax/get_ajax_exam 에 index.html 생성 

▪︎ templates/ajax/get_ajax_exam 에 index.html 생성 

 

 

▪︎ AjaxExamController.java에 각각의 요청주소에 대한 라우팅 메서드 작성 

// * http://localhost/ajax/getAjaxExam 주소에 대한 요청 처리 
//  - 실행 후 templates/ajax/get_ajax_exam/index.html 뷰 파일을 리턴함 
@GetMapping("/ajax/getAjaxExam")
public String getAjaxExam() {
    return "ajax/get_ajax_exam/index";
}

 

 

▪︎ templates/ajax/get_ajax_get/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>getAjaxExam 뷰</title>

    <style>
        span {
            color: navy;
            background : lightgrey;
        }
    </style>
    
    <script>
        // * XMLHttpRequest 객체를 이용한 ajax 실행방법 
        // 1. HTML 위젯 객체를 다루는 UI 
        // 2. Ajax 객체를 다루는 Http 처리 부분 
        
        // 1. HTML 위젯 다루기 
        //    - 일단 HTML 태그가 모두 다운로드되어야 자바스크립트로 DOM API에 접근 가능 
        //      따라서 </body> 태그 위에 script 태그를 두거나, 
        //      window.onload 이벤트를 이용해 처리하면 됨 
        
        window.onload = function(){
        	// * DOM API를 이용하여 양식 HTML 태그와 button 태그 찾기 
        	//  - button 객체 찾기 
        	let button = document.getElementById("ajaxCall")
        	//  - text 입력상자 객체 찾기 
        	let inputText = document.getElementById("inputName")
        	
        	// * 응답이 오면 즉석에서 출력한 span 객체를 찾기 
        	let spanName = document.getElementById("name")
       		let spanAge = document.getElementById("age")
        	
       		// * 버튼 클릭 시, ajax 실행이 일어남 
       		//   - 버튼에 이벤트리스너를 추가함.
       		button.addEventListener('click', function(){
       			//  - click 이벤트 발생하면 처리할 콜백 익명함수 정의 
       			//    이 부분에서 ajax를 이용하여 비동기로 서버에 요청함. 
       			//  - 서버에 요청할 때 요청 데이터로 name의 값을 제공하고, 
       			//    응답데이터로 요청 name의 값과 나이 문자열을 응답 받게 됨.
       			//  - ajax 처리 순서 
       			//  ① ajax(XMLHttpRequest 내장객체 이용) 객체를 먼저 생성 
       			//  ② ajax 객체의 현재 진행상태 및 서버 응답상태를 계속 모니터링할
       			//    ( = readystatechange 이벤트 ) 이벤트 리스너 등록 
       			//  ③ 이벤트리스터 등록을 마친 후, 일단 서버에 연결해야 함. 
       			//     → ajax객체.open() 메서드 호출
       			//     1) 요청방식 2) 요청주소 3) 비동기 및 동기 여부 
       			//  ④ ajax 객체가 서버와 연결이 된 후, 
       			//    추가 요청 데이터가 있으면 전송 : send() 이용 
       			//  ⑤ 서버로부터 응답데이터가 도착하면, onreadystatechange 이벤트가 
       			//    발생하여 등록된 이벤트리스너가 CallBack으로 실행됨. 
       			
       			//  ① XMLHttpRequest 객체 생성 
       			let httpRequest = new XMLHttpRequest();
       			
       			//  ② onreadystatechange 이벤트 리스너 등록 
       			httpRequest.onreadystatechange = function(){
       				// * readyState가 Done(=ajax 객체 준비완료 및 응답할 준비완료)이고,
       				//   서버로부터 응답이 200(서버 요청 성공)이면, 
       				//   -> 응답데이터(name, age)를 span태그(보여줄 위치)에 출력함. 
       			    if( httpRequest.readyState == XMLHttpRequest.DONE ){
       			    	// * 이 이후에 응답결과가 옴. 
       			    	//  - 200 응답일 경우 
       			    	if( httpRequest.status == 200) {
       			    		// 응답 데이터를 저장할 변수 선언 
       			    		let result = httpRequest.response
       			    		
       			    		// span 태그에 결과 데이터 표시 
       			    	    spanName.innerHTML = result.name
       			    	    spanAge.innerHTML = result.age
       			    	
       			    	//  - 서버 실행 에러일 경우 ( 300, 400, 500 )
       			    	} else {
       			    	    alert("Ajax 요청 처리 실패!")
       			    	}
       			    }
       			}
       			
       			//  ③ 서버로 보낼 Ajax 요청의 형식 설정 
       			httpRequest.open(
       					"GET", `/ajax/getAgeByName?inputName=${inputText.value}`);
       			
       			//  ④ 서버로 데이터를 요청 : send()
       			//   - 데이터를 요청하기 전, 서버로부터 응답 형식을 'JSON'으로 지정. 
       			httpRequest.responseType = "json"
       			httpRequest.send()
       		})	
        	// * 마우스로 button 태그 클릭 시, click 이벤트 발생 
        	document.getElementById("ajaxCall").addEventListener()
        }
    
    </script>
    
    
</head>
<body>
    <h1>Ajax GET 방식 요청</h1>
    <!-- * 여기에 입력양식 위젯을 추가함. 
         단, <form> 태그가 없음. ajax를 이용해서 <form> 태그를 대신 처리함. 
    -->
    name: <input type="text" id="inputName"><br>
    <button id="ajaxCall">ajax호출</button>
    <!-- * ajax 호출로 응답받은 데이터 name과 age를 여기에 응답결과를 출력함.  -->
    <!-- 응답결과 출력 레이어 -->
    <h2>
        <span id="name">여기에 이름이 옴.</span>
        <span id="age">여기에 나이가 옴.</span>
    </h2>
    
</body>
</html>

 

 

▪︎ AjaxExamController.java

// * http://localhost/ajax/getAgeByName 
@GetMapping("/ajax/getAgeByName")
// * 스프링은 웹 브라우저에서 요청한 Request 요청객체로부터 요청 파라미터를 자동으로 추출 가능 
//   if (request.getParameter("키이름") != null ){
//			...
//	 }   
//   → 위와 같은 명령 블록 필요없이 @RequestParam 이용하면 됨. 
public Map<String, Object> getAgeByName(@RequestParam String inputName) {

    // * 데이터베이스에 데이터를 추가한 데이터 테이블 생성 
    Map<String, Integer> ageMap = new HashMap<>();

    //  - 실제로는 DB에서 가져와야 함.
    ageMap.put("구름", 10);
    ageMap.put("하늘", 15);
    ageMap.put("바람", 20);
    ageMap.put("Tom", 25);
    ageMap.put("Json", 30);


    // * 비즈니스 로직 : service 객체가 처리하는 부분 
    //  - 검색한 데이터의 결과를 저장할 맵 객체를 하나 만듦 
    Map<String, Object> returnMap = new HashMap<>();
    //  - 리턴할 데이터의 형식의 검색 조건 : 이름 
    returnMap.put("name", inputName);
    returnMap.put("age", ageMap.get(inputName));
         // Map.get(Object key) : Key(이름)에 해당하는 value인 나이가 반환됨 
    return returnMap;

    // * 비즈니스 로직 : service 객체가 처리하는 부분 	
}

 

 

▪︎ 실행 결과 

 

 

 로그 추가

  - {} : 형식지정자로, 개수만큼 변수 입력하기 

log.info("{}>>>{}", "getAgeByName()", "시작" ); 

 

 

• 500 에러 발생 ( template 에러 ) 

 

 

• index.html에서 서버로 데이터 요청하기 전에, 응답 형식을 JSON으로 지정했음 ( 즉, 문자열 형태! ) 

 

 

• 하지만,

   ❶ AjaxExamController의 애너테이션 확인 결과, @Controller! 

   ❷ getAgeByName()의 반환타입 : Map으로 객체! 

 

   ⇒ getAgeByName() 메서드에 애너테이션 @responsebody 추가해주어야 함

 

 


< 참고 >

• @RestController 

  - @Controller에 @ResponseBody가 추가된 것

  - 주로 JSON 형태로 객체 데이터를 반환하기 위해 사용함 

  - 데이터를 응답으로 제공하는 REST API를 개발할 때 주로 사용하며, 객체를 ResponseEntity로 감싸서 반환함  

 


 

 

▪︎ 다시 실행해보자.

 - 제대로 출력됨 

 

 - 로그도 제대로 출력됨

 

'프론트엔드 > Ajax' 카테고리의 다른 글

타임리프와 JS을 활용한 AJAX 구현  (0) 2023.08.21
AJAX 실습 - POST 방식 구현  (0) 2023.08.18
AJAX  (0) 2023.08.18