서버와 클라이언트 간의 데이터 교환 프로토콜인 HTTP에서 서버가 특정 동작을 하도록 클라이어트에 전송하는 메세지 포맷은 다음으로 구성되어 있다.
스프링에서 HTTP request 정보를 저장한 객체로 Header, Parameter, Cookie, URL, Body를 담고 있고 이에 대한 읽기 메소드를 지원하고 있다.
request의 body가 json 포맷으로 들어온 경우 HttpMessageConverter의 objectMapper를 통해 원하는 객체 형태로 변환한다.
@Getter
@AllArgsConstructor
public class UserDto {
private String name;
private int age;
}
@Controller
public class UserController {
@PostMapping("/user")
public String age(@RequestBody UserDto userDto) {
System.out.println(userDto.getName());
return "result";
}
}
Jackson 라이브러리에서 제공되는 객체 역직렬화를 수행하는 객체로 기본 생성자를 호출해 객체를 생성한 후 getter나 setter 메소드를 통해 객체의 필드를 알아낸 다음 Reflection api를 통해 직접 필드에 값을 넣어주기 때문에 역직렬화 대상 클래스에는 기본 생성자와 필드에 대한 getter 혹은 setter 메소드가 있어야 한다.
class ObjectMapperTest {
private ObjectMapper objectMapper = new ObjectMapper();
@Test
@DisplayName("기본 생성자만 존재하는 객체 역직렬화 테스트 - 실패")
public void test1() {
String body = "{\"test\": \"11\"}";
assertThrows(UnrecognizedPropertyException.class, () -> objectMapper.readValue(body, TestBody.class));
}
@Test
@DisplayName("setter만 존재하는 객체 역직렬화 테스트 - 성공")
public void test2() throws JsonProcessingException {
String body = "{\"test\": \"11\"}";
TestBodyWithSetter testBody = objectMapper.readValue(body, TestBodyWithSetter.class);
assertThat(testBody.toString(), is("11"));
}
@Test
@DisplayName("getter만 존재하는 객체 역직렬화 테스트 - 성공")
public void test3() throws JsonProcessingException {
String body = "{\"test\": \"11\"}";
TestBodyWithGetter testBody = objectMapper.readValue(body, TestBodyWithGetter.class);
assertThat(testBody.toString(), is("11"));
}
@Test
@DisplayName("setter와 getter 모두 존재하는 객체 역직렬화 테스트 - 성공")
public void test4() throws JsonProcessingException {
String body = "{\"test\": \"11\"}";
TestBodyWithGetterNSetter testBody = objectMapper.readValue(body, TestBodyWithGetterNSetter.class);
assertThat(testBody.toString(), is("11"));
}
}
request url에 존재하는 쿼리 파라미터(?id=123&name=test) 정보를 역직렬화해주는 아노테이션이다. 필드의 이름과 동일한 파라미터에 자동으로 값을 넣어주고 다중 필드의 경우 map이나 다중 필드를 변수로 가진 객체에 값을 넣어준다.
@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(defaultValue = "test" required=false) String id) {
return "ID: " + id;
}
@PostMapping("/api/foos")
@ResponseBody
public String updateFoos(@RequestParam Map<String,String> allParams) {
return "Parameters are " + allParams.entrySet();
}