JSON 응답과 요청 처리
API사용시 HTML 뿐만 아니라 JSON이나 XML을 사용하여 응답하는 경우도 있습니다.
JSON(JavaScript Object Notation)
JSON은 간단한 형식을 갖는 문자열로 데이터 교환에 주로 사용합니다.
{"이름":"값"}의 형태로 객체를 표현합니다.
배열은 ["값", "값"]으로 ","로 구분한 값 목록으로 표현합니다.
Jackson
Jackson은 자바객체와 JSON 형식 간 변환을 처리하는 라이브러리입니다.
Jackson을 사용하기 위해선 pom.xml에 Jackson을 의존 설정 해주어야 합니다.
Jackson은 프로퍼티의 이름과 값을 JSON객체의 (이름,값)으로 사용합니다. 프로퍼티 타입이 배열이나 List이거나 배열인 경우 JSON배열로 변환됩니다.
@RestController로 JSON 응답
@RestController어노테이션을 사용하면 JSON 형식으로 응답이 가능합니다. 컨트롤러 객체에 @Controller어노테이션 대신 @RestController어노테이션을 사용하고 Jackson 라이브러리가 존재하면 요청 매핑 메소드가 객체를 리턴할때 이 객체들을 JSON 형식으로 변환해서 응답합니다.
JSONS 응답에 포함시키지 않을 대상은 객체의 필드에 @JsonIgnore를 사용하면 제외시킬 수 있습니다.
날짜 형식중 LocalDateTime은 배열로 변환이 되고 Date는 유닉스 타임 스탬프로 변환이 됩니다.
특정한 형식으로 나타내고 싶으면 @JsonFormat을 이용해 필드에 적용합니다.
shape으로 설정하면 지정되어져 있는 형식으로 변환되고 pattern으로 설정하면 원하는 형식으로 변환이 됩니다.
각 객체의 날짜 형식마다 @JsonFormat을 지정하는 것은 중복입니다. 그러므로 Jackson의 변환규칙을 모든 날짜타입에 적용하면 이 문제를 해결 할 수 있습니다.
JSON으로 변환할 때 사용하는 MappingJackson2HttpMessageConverter를 새롭게 등록해서 날짜 형식을 원하는 형식으로 변환하도록 설정하면 모든 날짜 형식에 동일한 변환 규칙을 적용할 수 있습니다.
WebMvcConfigurer의 extendMessageConverters()이용해 추가합니다. 이 메소드는 등록된 HttpMessageConverter의 목록을 파라미터로 받습니다. JSON으로 변환할 때 사용할 ObjecMapper를 생성하고 원하는 형식을 지정한 뒤 이객체를 사용하는 MappingJackson2HttpMessageConverter를 첫번째 항목으로 설정하면 됩니다.
@RequestBody로 JSON 요청
요청 매핑 메소드의 매개변수인 커맨드 객체에 @RequestBody어노테이션을 사용하면 JSON형식의 요청 데이터를 자바 객체로 변환 시켜줍니다.
JSON 형식으로 전송된 데이터를 올바르게 처리하려면 요청 컨텐츠 타입이 application/json이어야 합니다. 쿼리 문자열 대신 JSON 형식을 사용하려면 applicaion/json타입으로 데이터를 전송하는 별도의 프로그램이 필요합니다.
날짜 형식을 변경하기 위해서는 @JsonFormat어노테이션에 shape이나 pattern을 설정하여 필드에 사용하거나 해당 타입을 갖는 모든 속성에 적용하고 싶으면 스프링 MVC 설정에서 extendMessageConverter()메소드를 사용하고 메소드 내부에서 Jackson의 변환에 사용되는 ObjectMapper를 생성하고 원하는 형식을 지정하고 이객체를 사용하는 MappingJackson2HttpMessageConverter를 첫번째 항목으로 설정하면됩니다.
객체 검증은 JSON 데이터가 들어가는 커맨드 객체 앞에 @Valid어노테이션을 쓰거나 Validator 객체를 통해 검증할 수 있습니다.
ResponseEntity로 객체 리턴하고 응답 코드 지정
에러 페이지는 JSON 형식이 아닌 HTML 형식으로 응답 결과를 제공합니다. 이를 JSON 형식으로 표현 하고 싶으면 ResponseEntity를 사용합니다.
먼저 에러를 위한 클래스를 생성합니다. 스프링 MVC는 리턴타입이 ResponseEntity이면 status로 지정한 값을 응답상태코드로 사용하고 body로 지정한 객체를 사용해서 JSON변환을 처리합니다.
-> ResponseEntity.status(상태코드).body(객체)
body내용이 없을 경우 build로 바로 생성합니다.
동일한 상태 코드를 응답해야하는 기능이 많다면 에러 응답은 @ExceptioinHandler로 처리하고 요청처리 메소드는 객체를 리턴하면 @RestController에 의해 객체는 JSON형식으로 변환이 되고 익셉션에 대한 에러코드는 @ExcpetionHandler가 적용된 메소드에서 ResponseEntity를 통해 JSON 형식으로 변환하여 사용합니다.
@RestControllerAdvice 어노테이션을 사용해 별도의 클래스로 분리하여 여러 컨트롤러에서 발생한 동일 에러에 대한 응답을 JSON형식으로 변환할 수도 있습니다.
@Valid어노테이션을 사용해서 검증에 실패할 경우 HTML 형식을 응답합니다. HTML 대신 JSON 형식으로 응답하고 싶으면 Error객체를 추가해 직접 응답을 생성하면 됩니다. 에러가 존재하는지 확인 후 에러가 존재하면 에러 객체로부터 에러코드를 구하고 이를 이용해 ResponseEntity를 리턴하여 JSON으로 응답할 수 있습니다.