Spring MVC에서 AJAX 요청 처리하기

AJAX를 통한 클라이언트와 서버 간 비동기 통신은 현대 웹 애플리케이션에서 필수적인 요소입니다. Spring MVC에서는 이러한 AJAX 요청을 효과적으로 처리할 수 있도록 @RequestBody@ResponseBody 어노테이션을 제공합니다.

@RequestBody 사용법

기본적으로 HTML 폼에서 전송되는 데이터는 application/x-www-form-urlencoded 형식으로 처리되며, 일반적인 요청 파라미터로 바인딩됩니다. 하지만 AJAX를 통해 JSON 형식의 데이터를 전달할 경우, 이는 요청 본문(request body)에 포함되며 application/json과 같은 미디어 타입으로 전송됩니다. 이런 경우 스프링은 자동 파라미터 바인딩이 불가능하므로 @RequestBody 어노테이션을 사용해 요청 몸체 전체를 직접 읽어야 합니다.

@ResponseBody의 역할

일반적인 @RequestMapping 메서드는 반환값을 뷰 이름으로 해석하여 JSP나 Thymeleaf 같은 템플릿으로 이동시킵니다. 반면 @ResponseBody를 선언하면 해당 반환값이 뷰가 아니라 HTTP 응답 본문(response body)에 직접 쓰여집니다. 특히 JSON 형태의 데이터를 반환할 때 매우 유용하며, 클라이언트에서 XMLHttpRequest 또는 fetch로 응답을 받을 수 있습니다.

실제 예제: JSON 기반 AJAX 요청 처리

다음은 클라이언트에서 JSON 데이터를 POST 방식으로 전송하고, 이를 Spring MVC 컨트롤러에서 처리하는 예제입니다.

JSP 페이지 (클라이언트 측)

<html>
<body>
    <button onclick="sendAjaxRequest()">AJAX 요청 보내기</button>

    <script>
        function sendAjaxRequest() {
            const xhr = new XMLHttpRequest();
            const data = {
                username: 'user123',
                phone: '010-1234-5678',
                password: 'pass987'
            };

            xhr.open('POST', '/SpringMVCDemo/ajax/process', true);
            xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');

            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    const response = JSON.parse(xhr.responseText);
                    console.log('결과:', response.message);
                    console.log('상태:', response.status);
                }
            };

            xhr.send(JSON.stringify(data));
        }
    </script>
</body>
</html>

서버 측 컨트롤러 (Java)

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/ajax")
public class AjaxProcessingController {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @ResponseBody
    @PostMapping(value = "/process", consumes = "application/json", produces = "application/json")
    public String handleJsonRequest(@RequestBody String rawJson) throws Exception {
        // JSON 문자열을 객체로 변환
        UserData userData = objectMapper.readValue(rawJson, UserData.class);
        
        System.out.println("수신된 사용자명: " + userData.getUsername());
        System.out.println("전화번호: " + userData.getPhone());

        // 응답 생성
        ResponseData response = new ResponseData();
        response.setStatus("success");
        response.setMessage("데이터 처리 완료: " + userData.getUsername());

        return objectMapper.writeValueAsString(response);
    }

    // 데이터 수신용 DTO 클래스
    static class UserData {
        private String username;
        private String phone;
        private String password;

        // 기본 getter 및 setter
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }

        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }

        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }

    // 응답용 DTO 클래스
    static class ResponseData {
        private String status;
        private String message;

        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }

        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
    }
}

위 예제에서 @RequestBody는 클라이언트가 전송한 JSON 문자열 전체를 문자열로 수신하며, Jackson 라이브러리를 사용해 이를 자바 객체로 변환합니다. 반대로 응답 시에는 @ResponseBody 덕분에 문자열로 변환된 JSON이 바로 클라이언트에게 전달됩니다.

또한, HttpServletResponse 객체를 직접 사용해 응답을 구성할 수도 있지만, @ResponseBody를 사용하는 것이 코드가 더 깔끔하고 유지보수가 쉬워집니다.

태그: Spring MVC AJAX @RequestBody @ResponseBody JSON

6월 20일 22:16에 게시됨