ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] ajax로 form 데이터 serialize() 전송하여 controller에서 객체로 받기/ajax로 json 데이터 전송하여 controller에서 객체로 받기(@RequestBody)
    JAVA/Spring(Springboot) 2023. 7. 22. 21:33
    728x90
    728x90

    ajax로 데이터를 전송하여 controller에서 데이터를 받는 방법에 대해 알아보겠다.
    데이터를 ajax로 넘길때
    form 데이터를 serialize() 해서 보내는 방식이 있고 
    json으로 데이터를 전송하는 방식이 있다.
    이 두가지를 코드로 살펴보자.

     


    우선 form에 있는 데이터를 전부 보내는 방식을 살펴보자.

     

    html
    <form id="form" name="form" th:object="${categoryCreateForm}">
        <div>
            <label for="name">카테고리명</label>
            <input type="text" id="name" name="name" placeholder="카테고리명">
            <p class="text-error" id="nameErr"></p>
        </div>
        <div>
            <label for="name">활성화</label>
            <input type="checkbox" id="isDel" th:field="*{isDel}">
        </div>
        <div>
            <input type="button" value="등록" onclick="createCategory()">
            <input type="button" value="취소" class="close-btn">
        </div>
        <p id="globalErr" class="text-error"></p>
    </form>

    html 코드이다.
    form에서 input 태그로 넘어갈 값들은 name(카테고리명), isDel(활성화여부) 이다.
    등록 버튼을 클릭하면 createCategory() 함수가 실행된다. 

     

     

    javascript
    function createCategory() {
        // 이름이 중복인지, 유효성 확인
        $.ajax({
            url: '/admin/category/create',
            data: $("#form").serialize(),
            type: 'POST',
            dataType: 'json',
            success: function(data) {
                location.reload();
            },
            error: function(data){
                console.log(data);
                if(data.responseJSON.code == "name") {
                    document.getElementById('name').classList.add("fieldError");
                    document.getElementById("nameErr").innerHTML = data.responseJSON.message;
                } else {
                    document.getElementById("globalErr").innerHTML = data.responseJSON.message;
                }
            }
        });
    }

    $("#form").serialize() 를 하면 form 에 있는 데이터가 정리되어서 controller에 넘어가게 된다.
    serialize() 는 표준 URL-encoded 표기법으로 form 요소를 문자열로 표기해준다.
    위 코드의 경우에는 name=xxx&isDel=xxx 이러한 방식으로 쿼리 스트링을 만들어준다.

    그리고 controller 반환 값으로 json 데이터를 받아야하기 때문에 dataType은 json으로 해두었다.

    controller가 성공적으로 마치면 페이지를 새로고침하고 
    오류가 나면 오류 내역을 페이지에 보여주게 작성하였다.

     

     

    controller
    @PostMapping("/category/create")
    @ResponseBody
    public ResponseEntity categoryNameCreate(@Validated CategoryCreateForm categoryCreateForm, 
    					BindingResult result) {
        // 유효성 검사 - 카테고리 이름 중복 검사
        // 유효성 통과된다면 카테고리 등록하기
        try {
            categoryService.saveCategory(categoryCreateDto);
        } catch (IllegalStateException e) {
            ErrorResult errorResult = new ErrorResult("name", e.getMessage());
            return new ResponseEntity(errorResult, HttpStatus.BAD_REQUEST);
        }
    
        HashMap<String, String> validationResult = new HashMap<>();
        validationResult.put("status", "ok");
    
        return new ResponseEntity(validationResult, HttpStatus.OK);
    }

    ajax로 넘어온 데이터는 form 데이터를 그대로 전송하였기 때문에
    원하는 객체를 파라미터로 바로 받을 수 있다.
    로직을 수행하고 controller에서 오류가 발생한다면 오류 내역을 반환하고,
    성공한다면 간단하게 성공하였다는 내역을 반환하였다.

     

    ErrorResult는 code와 message로 구성되어 있는 클래스이다.

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class ErrorResult {
    
        private String code;
        private String message;
        
    }

     

    serialize() 방식은 간단하게 쿼리 스트링으로 데이터를 넘기는 방식이라 
    controller에서 기존 form에서 submit 하던 방식과 동일하게 데이터를 받아오면 된다.

     

     

     

     


    다음으로 데이터를 json으로 보내는 방식을 살펴보자.

     

    원하는 데이터를 json 으로 생성하고 controller에 넘기는 방식이다.

    html
    <tr>
        <td>32</td>
        <td id="td-name_32">
            <span id="originalName_32" style="display: none;">한식</span>
            <input type="search" id="modifyName" value="한식" required="">   <!-- 전송값1 -->
            <p class="text-error" id="modifyNameErr"></p>
        </td>
        <td id="td-isDel_32">
            <span id="originalIsDel_32" class="none">false</span>
            <input type="checkbox" id="isDel_32" disabled checked="checked"> <!-- 전송값2 -->
        </td>
        <td id="td-btn_32">
            <input type="button" value="수정" id="modifyFormBtn_32" onclick="modifyCategory('32')">
        </td>
        <td></td>
        <td>2023-07-22 18:09:56</td>
    </tr>

    카테고리를 수정하는 코드인데, ajax로 넘길 값은 modifyName과 isDel_32 값이다.
    수정 버튼을 클릭하면 modifyCategory가 실행된다.

     

    javascript
    function modifyCategory(id) {
        var name = document.getElementById("modifyName").value;
        var isDel = $("#isDel_" + id).prop('checked');
    
        var param = {"id":id, "name":name, "isDel":isDel};
    
        // 이름이 중복인지, 비활성화 가능한지 유효성 확인
        $.ajax({
            url: '/admin/category/modify',
            data: JSON.stringify(param),
            contentType: "application/json; charset=UTF-8",
            type: 'POST',
            dataType: 'json',
            success: function(data) {
                location.reload();
            },
            error: function(data){
                console.log(data);
                if(data.responseJSON.code == "name") {
                    document.getElementById('modifyName').classList.add("fieldError");
                }
    
                document.getElementById('modifyNameErr').innerHTML = data.responseJSON.message;
            }
        });
    }

    json 데이터를 만드는 순서는
    1. json으로 넘길 값을 먼저 가져온다.
    2. param으로 json 데이터를 생성한다.
    3. controller에 넘기기 위해서 data: JSON.stringify(param) 으로 객체를 문자열로 변환하여 넘겨준다.

    여기서 중요한 것은 contentType: "application/json; charset=UTF-8" 을 꼭 기입해줘야한다는 것이다.
    기입하지 않는다면 x-www-form-urlencoded 이렇게 오류가 나서 controller가 제대로 동작하지 않는다.

     

     

    controller
    @PostMapping("/category/modify")
    @ResponseBody
    public ResponseEntity categoryNameModify(@RequestBody @Validated CategoryModifyForm categoryModifyForm, 
    					BindingResult result) {
        // 유효성 통과된다면 카테고리 등록하기
        try {
            categoryService.modifyCategory(categoryModifyDto);
        } catch (IllegalStateException e) {
            ErrorResult errorResult = new ErrorResult("name", e.getMessage());
            return new ResponseEntity(errorResult, HttpStatus.BAD_REQUEST);
        }
    
        HashMap<String, String> validationResult = new HashMap<>();
        validationResult.put("status", "ok");
    
        return new ResponseEntity(validationResult, HttpStatus.OK);
    }

    json으로 넘어온 데이터를 받기 위해서는 객체 앞에 꼭 @RequestBody를 작성해줘야지 객체로 변환이 된다.
    아니면 objectMapper를 통해서 변환해주는 방법이 있으나
    @RequestBody만 작성한다면 자동으로 변환해주니 이 방법이 더 간단하다.

     

     


    ajax로 데이터를 넘기는 두 가지 방법에 대해 알아보았다.
    form 데이터를 다 넘기고 싶으면 첫 번째 방법,
    원하는 데이터만 넘기고 싶다면 두 번째 방법을 사용하는 것이 좋아보인다.

     

     

     

     

    728x90
    728x90
Designed by Tistory.