본문 바로가기

Study/Spring & Spring Boot

[Spring Boot] AJAX를 사용한 비동기 통신

AJAX란?


AJAX란 비동기 자바스크립트와 XML (Asynchronous JavaScript And XML)을 말합니다. 간단히 말하면, 서버와 통신하기 위해 XMLHttpRequest 객체를 사용하는 것을 말합니다. JSON, XML, HTML 그리고 일반 텍스트 형식 등을 포함한 다양한 포맷을 주고 받을 수 있습니다. AJAX의 강력한 특징은 페이지 전체를 리프레쉬 하지 않고서도 수행 되는 "비동기성"입니다. 이러한 비동기성을 통해 사용자의 Event가 있으면 전체 페이지가 아닌 일부분만을 업데이트 할 수 있게 해줍니다. (-- MDN --)

비동기 통신을 위해 사용하는 것으로 지금은 다소 퇴보되었다고 항간에서 이야기 한다. 대안책으로 axios를 많이 사용하는 추세이다..


AJAX 사용을 위한 준비


사용법을 빠르게 익히기 위해 jQuery를 사용한다.

그리고 서버단에는 다음과 같은 컨트롤러가 존재한다.

package com.example.sample02.controller;

import com.example.sample02.dto.MemberDto;
import com.example.sample02.service.MemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequiredArgsConstructor
public class Controller {

    private final MemberService service;
    public Logger logger = LoggerFactory.getLogger(Controller.class);

    @GetMapping("/base")
    public String base() {
        logger.info("Hello World!");
        return "base";
    }

    @GetMapping("/conParamGet")
    public String conParamGet (String title) {
        logger.info("HelloController conParamGet");
        logger.info("title: " + title);
        return "link success";
    }

    @GetMapping("/getMember")
    public MemberDto getMember() {
        System.out.println("HelloController getMember()");
        MemberDto dto = new MemberDto("홍길동", "gildong123", "aaa", "aaa@naver.com", 1);

        return dto;
    }

    @GetMapping("/getMemberList")
    public List<MemberDto> getMemberList(MemberDto dto) {
        logger.info("HelloController getMemberList()");

        List<MemberDto> list = new ArrayList<MemberDto>();
        list.add(new MemberDto("gildong", "gildong123", "aaa", "aaa@naver.com", 1));
        list.add(new MemberDto("chunhyang", "chy122", "bbb", "chy122@naver.com", 3));
        list.add(new MemberDto("hyunjun", "hjunp", "ccc", "hjp12@naver.com", 1));

        logger.info(dto.toString());

        return list;
    }

    @GetMapping("/dbTest")
    public List<MemberDto> dbTest() {
        logger.info("Controller getMember()");
        return service.allMember();
    }

    @GetMapping("/addMember")
    public void addMember(MemberDto dto) {
        logger.info("Controller addMember()");
        service.addMember(dto);
        System.out.println("추가됨");
    }

}

HTML에서 처리할 내용


프론트엔드단에서는 자바스크립트를 통해 AJAX를 구현한다. 각각의 컨트롤러에 매핑할 패턴을 따라 컨트롤러가 반응한다.

화면단의 구성은 아래와 같다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>

    <p id="demo"></p>
    <button type="button">클릭</button>

    <table border="1" id="tab"></table>

</body>
</html>

여기에서 버튼을 클릭할 때 이벤트를 발생시킨다.

서버단에서 가져온 정보를 <p> 태그에 추가하거나 <table>안에 행, 열을 구분하여 서버로 부터 불러온 정보를 넣어준다.

이는 완전히 독립된 환경으로부터 실행된다는 점에 착안해야 한다.

$(document).ready(function () {
  $("button").click(function () {
    // alert('click');


    $.ajax({
        url: "http://localhost:3000/base",
        type: "GET",
        success: function(data) {
            // alert("success");
            $("#demo").text(data);
        },
        error: function() {
            alert("error");
        }
    });

버튼 클릭 시 @GetMapping("/base")를 통해 리턴된 값을 data로 받아서 <p> 태그에 넣어준다.


    $.ajax({
        url: "http://localhost:3000/conParamGet",
        type: "GET",
        data: { title: "제목입니다." },
        success: function(data) {
            // alert('success');
            $("#demo").text(data);
        },
        error: function() {
            alert('error');
        }
    });

버튼 클릭 시 @GetMapping("/conParamGet")에 JSON 형식으로 title을 전달해준다.
이를 통해 리턴된 값을 함수의 매개변수인 data로 받아서 처리해준다.


    $.ajax({
        url: "http://localhost:3000/getMember",
        type: "GET",
        success: function (json) {
           console.log(json);
            alert(JSON.stringify(json));

            $("#demo").append(json.id + "<br/>");
            $("#demo").append(json.pwd + "<br/>");
            $("#demo").append(json.name + "<br/>");
            $("#demo").append(json.email + "<br/>");
        },
        error: function() {
            alert('error');
        }
    });

버튼 클릭 시 @GetMapping("/getMember")에서 리턴되는 값을 json 매개변수에 받아주는데, 이 때 getMember 함수를 보면

@GetMapping("/getMember")
public MemberDto getMember() {
    System.out.println("HelloController getMember()");
    MemberDto dto = new MemberDto("홍길동", "gildong123", "aaa", "aaa@naver.com", 1);

    return dto;
}

리턴되는 타입이 MemberDto이므로 프론트엔드단에서 객체형식으로 넘겨받게 된다.

이는 JSON 형태이며 문자열로 바꿔주기 위해 JSON.stringify를 사용한다.


    $.ajax({
        url: "http://192.168.35.104:3000/getMemberList",
        type: "GET",
        data: { 
            id: 'system', 
            pwd: '34567',
            name: '시스템',
            email: 'admin@system.kr',
            auth: 1
        },
        success: function(json) {
            // alert("success");
            // alert(JSON.stringify(json));

            // alert(json.length);

            let str = "";
            for(let i = 0; i < json.length; i++) {
                 str += "<tr>";
                str += `<td>${json[i].id}</td>`;
                str += `<td>${json[i].pwd}</td>`;
                str += `<td>${json[i].name}</td>`;
                str += `<td>${json[i].email}</td>`;
                str += `<td>${json[i].auth}</td>`;
                str += "</tr>";
             }

             $("#tab").append(str);
        },
        error: function() {
            alert("error");
        }
    });

getMemberListList를 반환하는 함수이다. 매개변수는 MemberDto형식이다.

반복문을 돌려서 표 형태로 뿌려주게 된다.


    $.ajax({
      url: "http://192.168.35.104:3000/dbTest",
      type: "GET",
      success: function(json) {
        console.log("success");
        console.log(JSON.stringify(json));

        let str = ""
        json.forEach(e => {
          JSON.stringify(e);
          str += "<tr>";
          str += `<td>${e.id}</td>`
          str += `<td>${e.pwd}</td>`
          str += `<td>${e.name}</td>`
          str += `<td>${e.email}</td>`
          str += `<td>${e.auth}</td>`
          str += "</tr>"
        });
        $("#tab").append(str);
      },
      error: function() {
        console.log("error");
      },
    })

  });
});

위와 비슷하지만 여기서는 forEach를 사용하였다.