-
[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을 기대하고 있기 때문에 충돌이 발생하기 때문입니다.
'Spring' 카테고리의 다른 글
[Spring] 전자정부프레임워크 crypto를 활용한 암호화 (0) 2024.06.17 스프링 IoC 컨테이너와 빈의 생성 (0) 2023.06.26