Backend/Thymeleaf

[Thymeleaf]ajax 사용법 및 예제(SpringBoot)

Chung-A 2020. 7. 23. 12:15

[Thymeleaf]ajax 사용법 및 예제(SpringBoot)

 

안녕하세요!

 

오늘은 SpringBoot에서 Ajax를 사용하는 방법에 대하여 정리해보려고 합니다.

 

흔히 웹 개발을 진행할 때 비동기통신을 사용하여 진행하고싶을 때가 있습니다.

 

예를 들면 버튼을 눌렀을 때 화면 전체를 새로고침 하지 않고 뷰를 갱신한다던가 하는 일입니다.

 

이번 포스팅은 뷰 템플릿 엔진으로 Thymeleaf를 이용하였고 SpringBoot로 개발하였습니다.

 

참고해주세요!

 


1. 뷰 페이지 작성

 

먼저 뷰 페이지를 작성해야겠죠?

 

저는 간단하게 input 박스와 버튼을 넣어서 

 

버튼을 클릭시 서버로 데이터를 보내고

 

받아온 데이터를 뷰에서 갱신하는 방식으로 진행하였습니다.

 

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script src="/js/storeDataSendAjax.js"></script>
    <h3>1. 데이터 전송</h3>
        <div class="col-sm-12">
            <div class="row">
                <div class="col-sm-4">
                    <input id="input" placeholder="데이터를 입력해주세요..">
                </div>
            </div>
        </div>
        <input value="등록" type="button" onclick="dataSend()">
        <div id="resultDiv">
            <p th:if="${msg}!=null" th:text="${msg}"></p>
        </div>
    </form>
    <br>
</body>
</html>

 

뷰 소스코드입니다.

 

input에 데이터를 입력하고 버튼을 누르면 dataSend()가 호출되어 ajax통신을 한 뒤 

그 결과에 따라 resultDiv 뷰가 갱신이 되는 방식입니다.

 


2. JavaScript로 Ajax 통신 코드 작성

 

등록 버튼을 누른 뒤 서버와 통신하는 부분, dataSend함수를 작성합니다.

 

function dataSend() {

    var data=$("#input").val();

    var messageDTO={
        result:data
    };

    $.ajax({
        url: "/dataSend",
        data: messageDTO,
        type:"POST",
    }).done(function (fragment) {
        $("#resultDiv").replaceWith(fragment);
    });
}

 

dataSend는 Jquery로 ajax통신을 진행하였습니다.

 

먼저  var data=$("#input").val(); 코드로 입력값을 받아온 뒤 그 값을 객체에 넣어줍니다.

 

그 후 $.ajax를 통해 통신을 시작합니다.

 

그리고 done 부분에 갱신하고자하는 부분의 id를 적고 replaceWith로 해당 영역을 통신 후 교체하겠다고 명시해줍니다.

 

 

 

 

SpringSecurity를 적용하신 분들에게

 

이때 SpringSecurity를 적용하신 분들은 forbidden 에러가 뜨실겁니다. 

 

csrf 토큰문제가 발생해서 접근을 못하는 문제가 발생한것으로 보여집니다.

 

따라서 뷰 페이지 헤더에 아래 두 meta태그를 넣어주신 뒤 

 <meta id="_csrf" name="_csrf" th:content="${_csrf.token}"/>
    <meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}"/>

javaScript에서 ajax를 하기 전에 token, header를 추가하고

 

beforeSend에서 헤더에 그 값들을 넣어주면 에러없이 통신을 진행할 수 있습니다.

 

  var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");

    $.ajax({
        beforeSend: function(xhr){
            xhr.setRequestHeader(header,token);
        },
        url: ...
        ...
        success:function (result) {

        },
        error:function (e) {
        }
    });

참고 바랍니다:)


3. Controller 코드 작성

뷰를 다 만들었으면 이제 Controller에 가서 코드를 작성해줍니다.

 

   @RequestMapping(value = "/dataSend",method = RequestMethod.POST)
    public String dataSend(Model model,MessageDTO dto){
        model.addAttribute("msg",dto.getResult()+"/ 서버에서 붙여준 값입니다");
        return "/testPage :: #resultDiv";
    }

메시지는 기본적으로 서버통신했다는 것을 알 수 있게 뒤에 텍스트를 덧붙이겠습니다.

 

한가지 특이한 점은 ajax로 통신하여 뷰를 갱신해주고자 할 때

 

반환값에 "/testPage :: #resultDiv" 이런식으로 찾아갈 페이지 뒤에 갱신해주고자 하는 영역의 id값을 써줘야 합니다.

 


4. 테스트

 

다 만들었다면 테스트를 진행해보겠습니다.

 

페이지 기본 뷰

데이터를 입력하고 보내면 

 

전송받은 데이터 결과

이와같이 페이지를 새로고침 하지 않고 ajax통신을 통해

 

화면이 부분적으로 갱신되는 것을 볼 수 있습니다.

 

이상으로 타임리프 ajax 정리 및 예제 포스팅을 마칩니다

 

혹시 이상한 점이나 궁금한 점이 있으시다면 댓글로 알려주시면 감사드리겠습니다ㅎㅎ