AnnotationMethod 관련@RequestBody@ResponseBody@RequestHeader@RequestParam (QueryParameter)LocalDate parsing 이슈@PathVariableHTTP Message ConverteeJackson2ObjectMapperMessageConverter Servlet에 추가하기ResponseEntity@JsonFormat
Annotation
Method 관련

- @RequestMapping : 기본적으로 모든 method로 접근 가능함(get, post, put, delete). method 인자로 http method 제한 가능
- @PathVariable : path variable 인자로 받을 때
- @JsonProperty : data body를 보낼 때의 이름과 parsing할 때 매핑해야할 변수의 이름이 다를 때 사용
- @JsonNaming : class 전체에 변수명 규칙 적용하기
- @JsonInclude

@RequestBody

- @RequestBody —parameter에 붙이는 어노테이션
- 해당 파라미터가 json 형태로 들어오면, 그 json 을 오브젝트에 자동으로 매핑되도록 도와줌
- 참고로, Form 데이터 같이 key, value 형태로 들어오는 데이터는 @RequestBody를 써주지 않고도 자동으로 오브젝트에 매핑이 됨 ( 이 부분은 ModelAttributeMethodProcessor.java 의 resolveArgument() 에서 진행됨)
HttpRequest body
→Java domain object
Automatic deserialization
- 디폴트로 @RequestBody 파라미터는 JSON 데이터에 대응함
- 내부적으로 ObjectMapper를 활용하여 deserialize를 진행함 → Object Mapper
@ResponseBody

- @Responsebody — 반환한 값을 자동적으로 JSON으로 serialize하고 HttpResponse로 바꾸어서 전달해줌

- 중간에 HTTP 메시지 컨버터가 들어가 있어서 들어온 Argument나 나가는 Response를 HTTP ↔ 웹 어플리케이션 타입 간에 변환을 해줌
- MappingJackson2HttpMessageConverter.java — json으로 변환
@RequestHeader
- @ResponseBody 를 사용하고 있을 시, @RequestBody와 @RequestHeader는 혼용하여 사용이 불가
- 이때 해결책 :
HttpServletRequest
의getHeader
메서드를 사용
@RequestParam (QueryParameter)
LocalDate parsing 이슈
- @RequestBody 에서는 2022-08-01 와 같이 형태 보내주면 알아서 잘 parsing이 되는데 @RequestParam에서는 그냥은 안됨
- 그 이유는 object Mapper를 쓰지 않고 내부적으로 ConversionUtils에 FormattingConversionService를 쓰는데 여기서 기본 Parser(LocalDate의 경우
java.time.format.DateTimeForamtter.parse
) 를 쓰기에 그냥은 안됨
@PathVariable
@GetMapping("/path-var/{name}") public String pathVariable( @PathVariable(name="name") String pathName){ System.out.println("PathVariable : " + pathName); return pathName; }
- path 에 path variable 자리에 { } 를 이용하여 변수명 입력
- 함수의 parameter로 @PathVariable을 붙여주고 변수 선언
- 이 때 path의 변수와 이름이 같다면 아무 문제 없음
- path의 변수와 이름이 다르다면 @PathVariable(name=”path에 있는 변수명”) 을 지정해주어야함
HTTP Message Convertee
Jackson2ObjectMapper
- java object를 json으로 바꿀 때 얘를 많이 사용함
MessageConverter Servlet에 추가하기
class ServletConfig implements WebMvcConfigurer{ @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(); var xStreamMarshaller = new XStreamMarshaller(); converter.setMarshaller(xStreamMarshaller); converter.setUnmarshaller(xStreamMarshaller); converters.add(0, converter); JavaTimeModule javaTimeModule = new JavaTimeModule(); javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME)); var modules = Jackson2ObjectMapperBuilder.json().modules(javaTimeModule); converters.add(1, new MappingJackson2HttpMessageConverter(modules.build())); } }
ResponseEntity
- 원래는 그냥 Entity를 반환하는 형식인데, 해당 객체로 반환을 하게 되면 Http header나 상태 코드 이런 것들이 추가로 처리하게 됨
public ReponseEntity<Cusomter> findCustomer(@PathVariable UUID customerId){ Optional<Customer> customer = customerService.getCustomer(customerId); return customer.map(v => ResponseEntity.ok(v)) .orElse(ResponseEntity.notFound().build());