7/17, 7/18 JSON 응답과 요청 처리

박세현·2024년 7월 17일

Spring

목록 보기
13/15
post-thumbnail

JSON 응답과 요청 처리

1. JSON 개요

  • JSON(Javascript Object Notation) : 자바스크립트 객체 표기법
  • {"이름":"값", "이름":"값", ...}

2. Jackson 의존 설정

  • jackson-databind
    • implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.2'
  • jackson-datatype-jsr310
    • Date & Time API - java.time 패키지
    • implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2'

3. ObjectMapper

  • 문자열을 즉 자바객체를 json 문자열로 바꿔줌
  • 자바객체 ↔ json

1) writeObjectAsString()

  • 자바 객체 ➡️ JSON 문자열
  • writeObjectAsString(자바객체)


2) readValue()

  • JSON 문자열 ➡️ 자바객체
    -> readValue(...)



4. @RestController로 JSON 형식 응답

  • REST(RepresEntational State Transfer) - 표현적 상태 전이
    • GET /api/member/list - 조회 상태 URL
    • POST /api/member

1) 반환값⭕

  • 자바 객체(getter가 있는) : 자바 객체 ➡️ JSON 문자열 변환 후 출력
  • 응답헤더 : Content-Type : application/json

JSON Formatter
https://chromewebstore.google.com/detail/json-formatter/bcjindcccaagfpapjjmafapmmgkkhgoa?hl=ko&pli=1



2) 반환값이❌

  • 응답 body가 비어 있음


3) 반환값이 문자열인 경우

  • 문자열 그대로 출력(템플릿이 아니라)
  • 응답헤더 : Content-Type : text/plain

  • 원래 컨트롤러는 반환할 때 문자열 혹은 모델엔뷰
    응답할 때 템플릿 혹은 html로 반환
    • 보통 응답헤더 : text.html

예시) 반환값⭕

ㄴ 자바객체를 반환하면 getter를 호출해서 json형태로 반환



예시) 반환값이 문자열인 경우

ㄴ 한글 깨짐
ㄴ 그럼 응답헤더 콘텐트타입 쳌해보자

ㄴ consumes() : 요청 쪽 콘텐트타입

ㄴ produces() : 응답쪽 콘텐트타입
ㄴ 이거 활용해서 응답헤더 바꿔주자

ㄴ 이제 한글 안 깨짐



예시) 반환값이❌

ㄴ 응답바디 없음



예시)




5. @ResponseBody

  • @Controller로 설정된 일반 컨트롤러 메서드를 문자열이나 모델엔 뷰가 아닌 Rest로 응답(자바객체, 문자열, 반환값 없음...) 하게 만들어주는 애노테이션
  • Rest로 응답 : 자바 객체, 문자열, 반환값 없음...

예시) @ResponseBody




6. @Jsonlgnore

  • JSON 변환시 제외

예시) @Jsonlgnore를 이용한 제외 처리

ㄴ 비번은 중요한 개인정보니까 가리자

ㄴ 비번 안보임




7. @JsonFormat

  • 날짜 형식 변환 처리
  • 출력 날짜, 입력 날짜 형식을 한정


1) @JsonFormat

예시) @JsonFormat : 날짜 형식 변환

ㄴ 이거 날짜형식 보기 좀 그럼

ㄴ 근데 이렇게 귀찮아



2) MvcConfig 설정

  • MvcConfig 설정을 통해 날짜 형식 바꾸기

예시) MvcConfig 설정을 통해 날짜 형식 바꾸기

ㄴ 매개변수 쳌

ㄴ json() : 응답하는 형식 : json으로 응답한다
ㄴ converters.add(0, new MappingJackson2HttpMessageConverter(objectMapper)); : 그냥 add하면 우선순위가 떨어져서 0번째라고 해주어야 함



예시) 응답 형식을 json 말고 xml로
의존성

  • Jackson Dataformat XML
    • implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.17.2'

ㄴ xml로 바꿈




8. @RequestBody

  • JSON 요청 처리
  • HTTP 요청 본문 : JSON 또는 XML 데이터 ➡️ Java 객체로 변환
  • HTTP 요청의 본문(body)을 Java 객체로 변환하여 컨트롤러 메서드의 파라미터로 전달하는 데 사용
  • 커맨드 객체 앞에 @RequestBody를 추가하면 Content-Type: application/json으로 판단하고 데이터 변환
    • 데이터 바인딩: 클라이언트가 전송한 JSON 또는 XML 데이터를 Java 객체로 변환
    • 유효성 검사: Spring Validator를 통해 Java 객체의 유효성을 검사
  • 커맨드 객체 변환 기준
    • Content-Type : application/x-www-form-urlencoded;
  • Rest방식인데 POST방식으로 보내고 싶어...이럴때 사용
    • POST
    • PUT
    • PATCH
    • 등등등

참고) 테스트

  • POSTMAN : REST 테스트
  • ARC(Advanced Rest Client) : REST 테스트
  • MockMvc
    • 애를 쓰면 서버를 껏다키지 않아도 됨
    • 이거 더 자세한 정보가 나옴
      • 스프링 내에서 어떤컨트롤러 어떤 메서드...

예시) ARC(Advanced Rest Client) : REST 테스트

ㄴ 요청헤더 : 요청 데이터 json형식으로
ㄴ 요청바디 : 보낼 데이터

ㄴ 검증 실패시 에러가 나오는게 목적

ㄴ 여기로 유입되었다는 말
ㄴ 커맨드객체 검증 에러 발생 -> 해결이 목적
ㄴ 알려줘야 함 = 정보확인 = Errors에는 발생한 에러정보가 담겨있는 메서드들이 있음
ㄴ 근데 json형태의 에러는 우리가 가공해 주어야 한다...?
ㄴ 왜냐면 일반에러는 우리가 템플릿형태로 보여주ㅠ지만 애는 템플이이 없으니까...?




9. Errors

1) getFieldErrors()

  • 필드별 전체 에러 정보


2) getGlobalErrors()

  • 커맨드 객체 자체 에러 정보(reject(...)..) - 내가 정의한 에러가 대다수(미스매치, 페일로그인...)


3) getAllErrors()

  • 전체 에러 정보

예시) 필드에러 확인

ㄴ 가장 범위가 좁은것부터 나옴
ㄴ 커맨드객체 필드명 ...
ㄴ 디폴트 메세지 있지만 내가 정의한 메세지가 나왔으면 좋겠어

ㄴ 메세지 소스빈을 가져오면 내가 정의한 메세지를 가져올 수 있음

ㄴ 비밀번호 -> 비밀번호 입력하세요, 비밀번호가 틀립니다...등등 비밀번호 필드 하나에 에러메세지가 다양하게 나와야 하는 경우가 있음 -> Map, list형태로 할거



예시) 메세지 소스_내가정의한 에러 메세지 + 제이슨 형태로 에러메세지 응답하기

ㄴ 이부분 이러면 좀...

ㄴ 이거 때문에 그럼

ㄴ 내가 원하는 한글메세지 나오게끔함
ㄴ 에러코드 그자체가 아니라

ㄴ 제이슨 형태로 응답



예시) 회원가입을 rest방식으로

ㄴ 에러뜸

ㄴ 환경변수때문에 에러 남

ㄴ 이건 json방식이 아님

참고) MockMvc

ㄴ 요청바디
ㄴ void라 응답은 없음

ㄴ 요청데이터 들어온 모습



예시)

ㄴ 요즘 트렌드는 요청데이터가 보통 json형식으로 넘어오기 때문에 이렇게 해주어야 함

ㄴ 테스트 데이터가 db에 담긴 모습



예시) 응답코드 201 응답 바디x

ㄴ db저장은 응답코드201이니까 이렇게 바꿔줌




10. ResponseEntity

  • ResponseEntity로 객체 리턴하고 응답 코드 지정하기

1) ResponseEntity

  • ResponseEntity를 이용한 응답 데이터 처리
  • 응답 헤더, 바디쪽을 상세하게 설정하는 경우 사용

Class ResponseEntity<T>
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/ResponseEntity.html

ㄴ 생성자 매개변수 : 바디, 헤더, 응답코드

ㄴ status를 생성하지 않고 응답코드 400 내보냄

ㄴ created : 응답코드 201
ㄴ 매개변수 uri -> 이동 : 로케이션 헤더에 추가됨

ㄴ 매개변수❌ : 응답에 바디가 있는 경우
ㄴ 매개변수⭕ : 응답에 바디가 없는 경우



2) ResponseEntity.status(상태코드).body(객체)

  • 응답상태코드⭕ + 출력할 데이터⭕
    • status : 응답상태코드
    • body : 출력할 데이터

예시) 응답코드⭕ + 응답 데이터⭕

ㄴ 테스트 전에 환경변수 설정 해주기

예시)

ㄴ 응답헤더를 상세하게 설정하는 경우



3) ResponseEntity.status(상태코드).build();

  • 응답 상태 코드⭕ + 출력할 데이터❌


4) ReponseEntity.ok(member)

  • 200


예시) ReponseEntity.ok(member)



5) noContent() : 204



6) badRequest() : 400



7) notFound() : 404




11. JSON형식을 고정해서 응답

  • 다른서비스(API)를 이용하려고 주로 이용
    -> 개발하는 사람마다 필드명이 다름
    -> 같은 필드인데 어떤 사람은 MESSAGE 어떤 사람은 MSG 등등

예시) JSON형식 고정

ㄴ 이렇게 하면 안됨
ㄴ JSON형태로 응답할 때는 형식을 고정해주어야 함

ㄴ JSON형식고정

ㄴ 이렇게




12. @ExceptionHandler

  • @ExceptionHandler 적용 메서드에서 ResponseEntity로 응답하기

예외) 레스트 커먼 컨트롤러 어드바이스

ㄴ 이렇게 하면 범위가 중복되서 여기로 유입됨

ㄴ 유입 안되게끔 잠깐 주석처리

ㄴ 레스트 커먼 컨트롤러 어드바이스



예시) JSON형식 고정해서 응답 + @ExceptionHandler 적용 메서드에서 ResponseEntity로 응답하기

ㄴ 검증이 필요
ㄴ 빈값이 있는지 없는지...

ㄴ 초반에 구성할 때 익셉션핸들러 2개 만듬
-> 컨트롤러쪽 익셉션 핸들러
-> json쪽 익셉션 핸들러

ㄴ 이렇게

ㄴ 테스트 실행

ㄴ 테스트 결과
ㄴ 통일성 있게 예외를 만들기




13. @Valid 에러 결과를 JSON으로 응답하기

참고) swagger API
API만들어주는거??





UriComponentsBuilder

  • url을 쉽게 만드는 법

Class UriComponentsBuilder
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/UriComponentsBuilder.html

ㄴ 빌드 매개변수 쳌 : url밸리어블


예시1) url(매개변수⭕)

ㄴ uri 변수

ㄴ 애도 변수 : 교체가 가능하다
ㄴ 마지막에 빌드할때 순서대로 넣으면 됨

ㄴ 순서대로 교체가 됨
ㄴ 문자를 넣어도 똑같이 순서대로 넣어짐

ㄴ uri 변수에 대입된 모습
ㄴ 한글도 인코딩 되어있음



예시2) uri 생성

ㄴ url이 생성되어 있음
ㄴ 한글도 인코딩 되어있음

ㄴ 쿼리스트링 가져오기

ㄴ encode 주석 쳌





RestTemplate

  • Spring Framework에서 제공하는 클래스 중 하나로, RESTful 웹 서비스와의 상호작용을 단순화하기 위해 사용

  • JSON 또는 XML 형식의 응답을 Java 객체로 변환할 수 있음

  • 주로 서버 간 통신이나 외부 API 호출 시 사용

  • HTTP 메서드 지원: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS 등의 HTTP 메서드를 지원

  • 객체 직렬화/역직렬화: 요청 본문을 JSON이나 XML로 직렬화하고, 응답 본문을 Java 객체로 역직렬화할 수 있음

  • 예외 처리: HTTP 상태 코드에 따라 예외를 던져서 오류 상황을 쉽게 처리

  • 사용자 정의 요청/응답: 헤더, 쿼리 매개변수, 경로 매개변수 등을 자유롭게 설정할 수 있다

  • 주요 메서드

    • getForObject(String url, Class<T> responseType, Object... uriVariables)
      : 지정된 URL에서 데이터를 가져와 주어진 클래스 타입으로 변환
    • getForEntity(String url, Class<T> responseType, Object... uriVariables)
      : 지정된 URL에서 데이터를 가져와 ResponseEntity로 반환
    • postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
      : POST 요청을 보내고 응답 데이터를 주어진 클래스 타입으로 변환
    • postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
      : POST 요청을 보내고 응답을 ResponseEntity로 반환
    • exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
      : HTTP 메서드를 지정하여 요청을 보내고 응답을 주어진 클래스 타입으로 변환

Class RestTemplate
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

ㄴ 요청쪽 헤드 정보 가져오기

ㄴ 옵션즈 : 요청메서드가 뭔지 알아오는?

ㄴ 패치, 포스트...
ㄴ 요청방식에따른 메서드 존재



1. <T> ResponseEntity<T> getForEntity(...)

  • ResponseEntity : 응답쪽에 있는게 다 있음
  • 응답을 상세하게 조회할때 사용
  • 원격서버에서 응답을 상세하게 조회할 때 사용...?
    • 응답헤더
    • 응답바디
    • 응답쪽 상태코드

ㄴ 기준은 제이슨 형태...?

https://jsonplaceholder.typicode.com/




2. <T> T getForObject

  • 응답바디데이터를 가지고 변환만...?

예시)

ㄴ 다른 정보 없이 바디데이터만 나옴



예시)



예시) 단일데이터, 복합데이터 조회

ㄴ objectMapper : JSON 데이터를 Java 객체로 변환하거나 Java 객체를 JSON 데이터로 변환하는 데 사용




3. <T> ResponseEntity<T> postForEntity

  • POST 요청을 보내고 응답을 ResponseEntity로 반환
  • ResponseEntity : 응답쪽에 있는게 다 있음
  • 응답을 상세하게 조회할때 사용
  • 원격서버에서 응답을 상세하게 조회할 때 사용...?
    • 응답헤더
    • 응답바디
    • 응답쪽 상태코드

예시)

ㄴ 데이터를 제이슨 방식으로 보내야 함
ㄴ 제이슨 형식으로 바꿔주어야 함
ㄴ 리퀘스트 조인 커맨드객체 만들자

ㄴ 제이슨 문자열로 출력된 모습

ㄴ 뒤에 밸루⭕ : 반환값 스트링
ㄴ 뒤에 밸루❌ : 반환값 미디어타입



1) HttpEntity

  • 헤더, 바디 등 함께 전송 시 필요
  • 헤더와 바디 정보를 가지고 있다

Class HttpEntity<T>
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpEntity.html
<T> : 바디데이터의 종류

ㄴ 헤더만 있는 경우

ㄴ 헤더와 바디둘다 있는 경우

Class RestTemplate
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

ㄴ request 에 HttpEntity 넣어주기

ㄴ 메서드 상세히 설정?
ㄴ 겟, 풋, 포스트...

ㄴ 이거



예시)

ㄴ 한번 더 하면 201 안나옴
ㄴ 왜? 이메일이 중복되기 때문에



예시) POST/member/join : 이건 일반양식 형식으로 보내야함(제이슨이 아니라)

  • html이라 제이슨 형식 보다 요청헤더와 바디가 많이 나올거

ㄴ 실행함(1트)
ㄴ 출력 : 302 - 이동했다

ㄴ 한번더 실행함(2트)
ㄴ 이미 가입된 회원이라는 문구 나옴




4. <T> T postForObject

  • POST 요청을 보내고 응답 데이터를 주어진 클래스 타입으로 변환



5. <T> ResponseEntity<T> exchange(...)

  • HTTP 메서드를 지정하여 요청을 보내고 응답을 주어진 클래스 타입으로 변환
profile
귤귤

2개의 댓글

comment-user-thumbnail
2024년 7월 17일

"요즘 트렌드는 요청데이터가 보통 json형식으로 넘어오기 때문에 이렇게 해주어야 함" 트렌드를 따라가는 나 럭키비키🧚

답글 달기
comment-user-thumbnail
2024년 7월 18일

쳌쳌

답글 달기