ch16. JSON 응답과 요청 처리

728x90

📌 참고 도서 : 스프링5 프로그래밍 입문 - 최범균 저

ch16. JSON 응답과 요청 처리

1. [JSON 개요]

▶[JSON (Java Script Object Notation) ]

  • 간단한 형식 문자열
  • 데이터 교환 시 사용

▶[JSON 규칙]

  • 객체 표현 : { }중괄호 사용
  • 개별 객체 : (이름 : 값) 쌍
  • 배열 표현 : [ ]대괄호 사용, 콤마로 값 목록 구분하여 전달
  • 특수문자 표현 : (역슬랙시) 이용 | \“, \n, \r, \t
<JSON 예시>
{ 
	"name" : "유관순" ,
 	"age": "17" ,
	"related":["남동순", "류예도"] //배열 
}

2. [JSON 의존 설정]

-스프링 MVC에서 Jackson 라이브러리 이용
            -> 자바 객체를 JSON으로 변환하려면

                             : 클래스 패스에 Jackson 라이브러리를 추가하면 된다.
                             : pom.xml 파일에 Jackson 관련 의존 추가

▶[Jackson]

  • 자바 객체와 JSON 문자열 간 변환 처리 라이브러리
  • Jackson은 자바 객체의 필드/메소드 프로퍼티의 이름과 값 -> JSON 객체의 (이름,값) 쌍으로 사용

<의존 모듈 추가>

...
// Jackson core/Jackson Annotaion 의존 추가 
<dependency> 
	<grounpId>com.fasterxml.jackson.core</groupId>'
	<artifactId>jackson-datebind<artifactId>
	<version>2.9.4</version>
</dependency>
// java8 date/time  지원 위한 Jackson 모듈 추가 
<dependency> 
	<grounpId>com.fasterxml.jackson.datatype</groupId>'
	<artifactId>jackson-datatype-jsr310 <artifactId>
	<version>2.9.4</version>
</dependency>
...

3. [자바 객체 -> JSON 형식으로 변환]

▶[@RestController 로 JSON 형식 응답]

  • 이 응답 컨트롤러는 다시 컨트롤러 설정 클래스에서 빈으로 추가 필요
  • 실행 결과를 보면 JSON 데이터 표시해줌.
@RestController //JSON 형식으로 데이터 응답 컨트롤러 
public class RestMemberController {
         //필드
	private MemberDao memberDao;
	private MemberRegisterService registerService;
         //메소드
	@GetMapping("/api/members") 
	public List<Member> members() {
		return memberDao.selectAll();
	}                                 //요청 매핑 적용 메소드의 리턴 타입 = 일반 객체 
	@GetMapping("/api/members/{id}")
	public ResponseEntity<Object> member(@PathVariable Long id) {
		Member member = memberDao.selectById(id);
		if (member == null) {
			return ResponseEntity
					.status(HttpStatus.NOT_FOUND)
					.body(new ErrorResponse("no member"));
			// return ResponseEntity.notFound().build();
		}
		return ResponseEntity.ok(member);
                                        //요청 매핑 적용 메소드의 리턴 타입 = 일반 객체 
	} 
	...
}

▶[@JsonIgnore를 이용한 일부 데이터 제외 처리]

-민감한 데이터(ex. 비번)는 응답 결과에서 제외시켜야 한다.

-@JsonIgnore를 응답 제외 대상에 붙이면 된다.

-붙인 대상은 JSON 응답 결과에서 제외

public class Member {
     private Long id;
     private String email;
     @JsonIgnore
     private String password; //적용 데이터는 응답 결과에서 제외됨 
     private LocalDateTime registerDateTime;
...

▶[날짜 형식 변환 처리]

  • 기본적으로 자바 객체의 날짜 형식은 JSON 변환 시,
(LocalDateTime 타입 )-> JSON의 배열 값으로 표현


(java.util.Date 타입) -> 유닉스 타임 스탬프로 표현
                                 (*197011일 이후 흘러간 시간)
 

➀ [특정 형식 표현] : @JsonFormat | 변환 대상 각각에 적용

(shape 속성값 = Shape.STRING) : ISO-8601 형식 변환

@JsonFormat(shape = Shape.STRING) //ISO-8601 형식으로 변환  
private LocalDateTime registerDateTime;

(pattern 속성값 = ”원하는 패턴형식“) : 원하는 형식 변환

@JsonFormat(pattern = “yyyyMMddHHmmss” // 지정한 형식으로 변환 
private LocalDateTime registerDateTime;

 

➁ [기본 적용 설정] : 스프링 MVC 설정 변경 | 모든 대상에 동일하게 적용

-날짜 타입에 해당하는 모든 대상 각각에 @JsonFormat 붙이기 번거로움

-모든 대상에 동일한 변환 규칙 적용 : 스프링 MVC 설정을 변경

*스프링 MVC는 기본적으로 자바 객체를 HTTP 응답으로 변환 시 HttpMessageConverter 사용

 

▶[모든 날짜 타입 값 -> ISO-8601 형식]

@Configuration
@EnableWebMvc //스프링 MVC는 여러 형식으로 변환 가능한 HttpMessageConverter 미리 등록함 
public class MvcConfig implements WebMvcConfigurer { //스프링 MVC 설정 클래스 
	...
	@Override //HTTPMessageConverter 추가 설정 시 사용 메소드
	public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
				//등록된 HttpMessageConverter 목록을 파라미터로 받음

		ObjectMapper objectMapper = Jackson2ObjectMapperBuilder
		.json()
				.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) 
		//기본 날짜 형식 출력 시-> 유닉스 타임 스탬프 출력 기능 (비활성화)
		.build();
		converters.add(0, new MappingJackson2HttpMessageConverter(objectMapper));
			//HttpMesssageConverter 등록 시, 목록의 제일 앞 0번에 추가시킴
 			//그래야 가장 먼저 적용된다.
	}
}

▶[모든 java.util.Date 타입 값 -> 원하는 형식으로 출력]

-, 이 경우 LocalDateTime 타입 변환에는 해당 패턴이 적용X

simpleDateFormat() 메소드 이용해서 원하는 형식 지정

 

▶[모든 LocalDateTime 타입 값 -> 원하는 형식으로 출력]

  - serializeByType() 메소드 이용해서 원하는 형식 직접 설정

▶[응답 데이터 Content-Type] : application/json


4. [JSON 요청 데이터 -> 자바 객체로 변환]

  • JSON 형식으로 전송된 요청 데이터를 자바의 커맨드 객체로 전달받는 방법

▶[@RequestBody를 커맨드 객체에 붙이기]

  • JSON 형식의 문자열을 해당 자바 커맨드 객체 타입으로 변환한다.
@RestController
public class RestMemberController { 
          //필드
	private MemberDao memberDao;
	private MemberRegisterService registerService;
		...
	@PostMapping("/api/members")
	public ResponseEntity<Object> newMember(
			@RequestBody @Valid RegisterRequest regReq ){
                                             //이 커맨드 객체 앞에 붙임
	     ...

▶[JSON 데이터 날짜 형식 다루기]

  • JSON 형식의 데이터 -> 자바 객체 날짜 형식 변환하는 방법

➀ 기본적으로 적용

yyyy-MM-ddTHH:mm:ss

➁ 특정 속성에 특정 패턴 적용 : @JsonFormat의 pattern 속성으로 패턴 지정

@JsonFormat(pattern = “yyyyMMddHHmmss”)
private LocalDateTime birthDateTime;

➂ 모든 속성에 특정 패턴 적용 : MVC 설정 추가

deserializerByType() 메소드 : JSON 데이터 ->LocalDateTime 타입 변환 패턴 지정

simpleDateFormat() 메소드 : JSON 데이터 ->Date 타입 변환 시 패턴 지정

▶[요청 객체 검증] : @Valid / Validator

JSON 데이터를 변환한 객체도 @Valid 또는 별도의 Validator 이용하여 검증 가능

➀ [ResponseEntity 사용 응답 데이터 처리]

  • 일관된 응답 데이터 처리
  • 정상/비정상인 경우 모두 JSON 응답 일관되게 전송하기

          <ReponseEntity 생성 기본 방법>

-.body() 로 지정한 객체를 JSON으로 변환한다.

-.status()로 지정한 응답 상태 코드로 응답한다.

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

➁ [@ExceptionHandler 적용 메소드]

  • 한 메소드 안에서 정상응답/에러응답 모두 ReponseBody로 생성 시 코드 중복 문제 O

            ⓐ [다른 메소드에 따로 에러 응답 처리]

  • @ExceptionHandler 적용 메소드에서 에러 응답 따로 처리

             ⓑ [별도 클래스에 따로 에러 응답 처리]

  • @RestControllerAdvice 클래스에 에러 처리 코드 묶어서 한 곳에서 관리/처리

▶[@Valid 에러 결과를 JSON으로 응답]

  • Error 타입 파라미터 추가한 뒤 직접 에러 응답 작성

728x90