[Web] Spring MVC & JavaScript Ajax 통신하기

더보기를 누르면 서버에서 4개의 데이터를 더 불러와서 출력하는 동작을 구현해야 한다.
Ajax는 아무리해도 어렵다.. 자료를 어제부터 몇 개나 봤는지 모르겠다. 막상 성공하고 보면 코드가 매우 간결해서 허탈하다.

Ajax 전송 404 오류가 났던 가장 큰 원인은 @ResponseBody 에 대해 몰랐기 때문이다.
@Controller 어노테이션이 붙은 클래스내에서 @ResponseBody가 있는 컨트롤러는 return 값이 MessageConvert로 설정된 MappingJacksonHttpMessageConverter에서 JSON으로 자동으로 변환 작업을 마쳐 전송된다.
@ResponseBody가 없는 경우 json으로 변환 해 주는 view가 필요하나 실제로는 view도 안 만들고 아무 servlet-config.xml에 구현하지 않아도 Jackson만 library에 추가하면 자동으로 JSON 변환이 이루어진다.

아래처럼 List 객체만 반환하면 자동으로 매핑이 된다!

    @GetMapping(path = "/ajax")
    @ResponseBody
    public List<Product> getAjax(@RequestParam(name = "start", required = false, defaultValue = "4"int start) {
        List<Product> productList = reservationService.getAllProduct(start);
        return productList;
    }
cs

예제 자료를 찾아봐도 jQuery로 쓰는 사용자들이 태반이라 순수 자바스크립트로 구현하는 나는 조금 수정해서 실행해봤을때 오류가 나면 jQuery 코드를 보고 해서 그런가 했는데 그게 아니었다 ...
코드를 보기 좋게 함수로 나눠서 재구성했다.


그리고 또 하나 주의해야 할 점은, replace 하려는 data가 두 번 사용되는 경우 두 자리 모두 같은 데이터로 replace 되어야 하더라도 두 번 써줘야 한다는 것이다. 여기서도 한참 헤맸다.

최종 코드
var more_btn = document.querySelector(".btn");
    var start = 4;
    
    more_btn.addEventListener('click',function(){
        start+=4;
        sendAjax("ajax?start="+start);
        }
    );
    
     function makeTemplate(data){
        var left = document.querySelector(".wrap_event_box").firstElementChild;
        var right = left.nextElementSibling;
            for(var i=0;i<data.length;i++){
                var product_html = document.querySelector("#itemList").innerHTML;
                var product = data[i];
                var resultHtml = product_html.replace("{id}",product.id)
                                    .replace("{placeName}",product.placeName)
                                    .replace("{description}",product.description)
                                    .replace("{description}",product.description)
                                    .replace("{imageUrl}",product.productImageUrl)
                                    .replace("{content}",product.content);
                if(i%2==0)
                    left.innerHTML += resultHtml;
                else
                    right.innerHTML += resultHtml;
                
                if(product.id == "${count}") more_btn.style.display="none";
            }
    
    };
    
    function sendAjax(url){
        var request = new XMLHttpRequest();
        request.addEventListener("load"function(){
            var data = JSON.parse(request.responseText);
            makeTemplate(data);
        })
        request.open("GET",url);
        request.send();
    } 
cs

더이상 들어오는 데이터가 없는 경우 '더보기' 버튼을 없애준다.
아직도 갈 길이 멀다.


No comments:

Powered by Blogger.