ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] @RequestBody와 @ResponseBody를 사용해 JSON 형식의 데이터 주고받기
    Spring 2023. 8. 31. 20:46

     

    Dispatcher-servlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:p="http://www.springframework.org/schema/p"
            xmlns:context="http://www.springframework.org/schema/context"
            xmlns:mvc="http://www.springframework.org/schema/mvc"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
                    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    
    ...
        <!-- 애노테이션 기능 활성화 -->
        <mvc:annotation-driven/>
    ...
    <beans>

    HTTP Request의 body 데이터를 json 형식의 파라미터로 받아서 객체로 매핑해주는 @RequestBody 객체를 json 형식의 데이터로 매핑해서 Response의 body에 제공하기 위해서 사용하는 @ResponseBody 사용하기 위해서, xml 설정 파일에 <mvc:annotation-driven/> 코드를 추가합니다.

     

     

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xmlns="http://java.sun.com/xml/ns/javaee" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
     
      <display-name>myapp</display-name>
      
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:myapp/spring/context-*.xml</param-value>
      </context-param>
      
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      
      <servlet>
      	<servlet-name>dispatcherServlet</servlet-name>
      	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      	<init-param>
      		<param-name>contextConfigLocation</param-name>
      		<param-value>/WEB-INF/config/springmvc/dispatcher-servlet.xml</param-value>
      	</init-param>
      	<load-on-startup>1</load-on-startup>
      </servlet>
      
      <servlet-mapping>
      	<servlet-name>dispatcherServlet</servlet-name>
      	<url-pattern>*.json</url-pattern>
      </servlet-mapping>
      
      ...
    </web-app>

     

     

    UserController.java

    @RestController // @Controller + @ResponseBody
    @RequestMapping("/users")
    @RequiredArgsConstructor
    public class UserController {
        
        private final UserService userService;
        
        @GetMapping("/{userId}.json")
        public UserVO findUser(@PathVariable String userId) {
            return userService.findById(userId);
        }
        
        @PatchMapping("/updateUser.json")
        public String updateUser(@RequestBody UserVO userVO) {
        	int updatedRowCount = userService.updateUser(userVO);
            
            if (updatedRowCount == 1)
                return "Y";
            else
                return "N";
        }
    }

     

    @RequestBody는 HTTP 요청 바디를 읽어서 내부적으로 메서드의 인수로서 기본 타입 또는 커스텀 객체로 변환해서 호출하도록 해주는 어노테이션입니다.

    * 내부적인 변환RequestMappingHandlerAdapter, ArgumentResolver그리고 HttpMessageConverter 인터페이스와 구현체 MappingJackson2HttpMessageConverter, FormHttpMessageConverter 등을 참고. MappingJackson2HttpMessageConverter는 ObjectMapper를 사용해서 JSON을 읽고 쓸 수 있는 구현체이다.

     

    @RestController 애노테이션은 컨트롤러의 메서드에 @ResponseBody를 추가해줍니다. 따라서 @Controller가 명시된 클래스의 모든 메서드에 @ResponseBody가 명시된 것과 같습니다. @ResponseBody는 기본 타입 또는 커스텀 타입 객체를 일반 문자열이나 JSON 문자열 형식 등으로 변환해서 HTTP 응답 바디에 쓰도록 해주는 애노테이션 입니다.

    user.jsp

    조회

    function requestUser(userId) {
        $.ajax({
            url: "${contextPath}/users/" + userId + ".json", 
            type: "GET", 
            success: function(user) {
                console.log(user.name);
            }, 
            error: function() {
                // ...
            }
        });
    }

     

    갱신

    ...
        function requestUpdateUser(postData) {
            $.ajax({
                url: "${contextPath}/users/updateUser.json", 
                type: "PATCH", 
                contentType: "application/json", 
                data: JSON.stringify(postData), 
                success: function(isSucceeded ) {
                    // ...
                }, 
                error: function() {
                    // ...
                }
            });
        }
    ...

    요청 헤더의 Content-Type: application/json

     

    클라이언트 코드에서 쿼리 파라미터 형식 또는 폼 형식의 데이터를 서버로 보내려고 한다면, @RequestBody 애노테이션을 제거하여, @RequestParam 또는 @ModelAttribute를 적용해야 합니다. 폼 형식으로 데이터를 보낼 때는 Content-Type이 x-www-form-urlencoded로 설정되는데, @RequestBody가 application/json 또는 application/xml Content-Type을 기대하고 있기 때문에 충돌이 발생하기 때문입니다.

    댓글

Designed by Tistory.