스프링부트와 jquery ajax로 rest api 통신하기

새로고침 없이 html의 변경을 위하여

  • 렌더링 된 html 파일을 새로고침 없이 변경하기 위해서는 자바 스크립트의 도움이 필요하다. 이 경우 스프링에서는 rest api로 데이터만 송수신 하기 위한 컨트롤러가 필요하고, 뷰에서는 스프링에 요청하고 응답을 받을 통신 수단이 필요하다. 현재 예제는 ajax를 사용하였다.
  • 스프링 부트에서 rest api 를 만드는 방법과 ajax 통신하는 방법을 간단하게 정리한다.

스프링 부트와 controller

  • @RestController를 사용할 경우 다음과 같이 작성한다.
  • ResponseEntity을 사용하였다. http status를 간단하게 작성 가능하다. 제네릭으로 설정한 객체는 자동으로 json으로 변환한다. 이 경우 getter를 필요로 한다.
@GetMapping(value = "/board/{bno}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<ReplyDTO>> getListByBoard(@PathVariable("bno")Long bno){
    return new ResponseEntity<>(replyService.getList(bno), HttpStatus.OK);
}
  • get이 아닌 post 메서드이며 body가 있을 경우 반드시 @RequestBody 를 사용해야 한다. 클래스를 파라미터로 할 경우 json을 해당 객체로 바인딩한다.
@PostMapping("")
public ResponseEntity<Long> register(@RequestBody ReplyDTO replyDTO){
    Long rno = replyService.register(replyDTO);
    return new ResponseEntity<>(rno, HttpStatus.OK);
}

javascript와 ajax

function loadJSONData(){
    $.getJSON('/replies/board/'+bno, function(arr){
        console.log(arr);

        var str = "";

        $('.replyCount').html("Reply Count : "+arr.length)

        $.each(arr, function (idx, reply){
           str+='<div class="card-body" data-rno="'+reply.rno+'"><b>'+reply.rno+'</b>'
            str+='<h5 class="card-title">'+reply.text+'</h5>'
            str+='<h6 class="card-subtitle mb-2 text-muted">'+reply.replyer+'</h6>'
            str+='<p class="card-text">'+formatTime(reply.regDate)+'</p>'
            str+='</div> '
        });
        listGroup.html(str);
    });
};

function formatTime(str){
    var date = new Date(str);

    return date.getFullYear() + '/' +
        (date.getMonth()+1)+ '/' +
        date.getDate() + ' ' +
        date.getHours() + ':' +
        date.getMinutes();
}

$('.replySave').click(function (){
    var reply = {
        bno: bno,
        text: $('input[name="replyText"]').val(),
        replyer: $('input[name="replyer"]').val()
    }
    console.log(reply);
    $.ajax({
        url : '/replies/',
        method : 'post',
        data : JSON.stringify(reply),
        contentType : 'application/json; charset=utf-8',
        dataType : 'json',
        success : function (data){
            console.log(data);

            var newRno = parseInt(data);

            alert(newRno + "번 댓글이 등록되었다. ")
            modal.modal('hide');
            loadJSONData();
        }
    });
});

http method에 따라 body의 존재 유무가 다르다.

  • 마지막으로 delete 통신 방식을 통해 body를 전달하려다 실패한 경험을 공유하고자 한다. delete를 body 형태로 통신하려 하였지만 계속 에러가 발생했다.
  • 스프링에서는 바디를 읽지만 ajax에서는 ajax는 통신 결과를 error로 하였다.
$.ajax({
    url: '/replies/',
    method:'delete',
    data: JSON.stringify(reply),
    contentType:'application/json; charset=utf-8',
    dataType:'json',
    success : function (data){
        alert(data);
    }, error : function (request,status,error) {
        alert("code:" + request.status + "\n" + "message:" + request.responseText + "\n" + "error:" + error);
    }
});

// 메시지 코드 출처: https://shonm.tistory.com/454 [정윤재의 정리노트]
  • 에러의 발생 이유를 찾아본 결과, delete 메서드 방식은 페이로드를 지원하지 않는다. 그러니까 json(body)을 지원하지 않는다. get과 같이 @PathVariable(url 매개변수)를 통해서는 가능하다.

    페이로드 관련 내용 : https://blog.naver.com/lewisel/221829301069

  • 결국 바디가 아닌 query parameter로 변경하였다.
$.ajax({
    url: '/replies/'+id,
    method:'delete',
    success : function (data){
        alert(data);
    }
});