computer_study

[Spring] 16. JSON 응답과 요청 처리 본문

스터디/스프링5 프로그래밍 입문

[Spring] 16. JSON 응답과 요청 처리

knowable 2022. 5. 29. 02:58

1. JSON 개요

  • JavaScript Object Notation
  • 간단한 형식을 갖는 문자열(데이터 교환에 주로 사용한다.)
  • 문자열, 숫자, boolean, null, 배열, 다른 객체가 값으로 올 수 있다.
  • IntelliJ 에서 CMD + OPT + L로 JSON파일 형식 변환 가능...?(확인 필요)

2. Jackson 의존 설정

스프링 MVC에서 Jackson 라이브러리를 이용해서 자바 객체를 JSON으로 변환할 수 있다.

public class Person{
    private String name;
    private int age;
    
    ...
    get/set 메서드
}
{
    "name":"이름",
    "age":10
}

프로퍼티 타입이 배열이나 List인 경우 JSON 배열로 변환된다.

3. @RestController로 JSON형식 응답

@Controller 애노테이션 대신 @RestController 애노테이션을 사용하면 데이터 응답을 JSON형식으로 하게된다.

//// @Controller 사용
@Controller
public class RestMemberController{
    private MemberDao memberDao;
    private MemberRegisterService registerService;
    
    @RequestMapping(path="/api/members", method = RequestMethod.GET) // 소나큐브는 얘로 안쓰는듯?
    @ResponseBody
    public List<Member> members(){
        return memberDao.selectAll();
    }
}

//// @RestController 사용
@RestController
public class RestMemberController{
    private MemberDao memberDao;
    private MemberRegisterService registerService;
    
    @GetMapping(path="/api/members") 
    public List<Member> members(){
        return memberDao.selectAll();
    }
    // @ResponseBody 애노테이션을 사용하지 않는다.
}

@JsonIgnore

password같이 암호에 민감한 데이터를 응답 결과에서 제외할 때 사용

import com.fasterxml.jackson.annotation.JsonIgnore;

public class Member{
    private Long id;
    @JsonIgnore
    private String password; // JSON 결과에서 제외된다.
    private String name;
}

@JsonFormat

Jackson에서 날짜나 시간 값을 특정한 형식으로 표현하는 방법

@JsonFormat(shape = Shape.STRING) // ISO-8601
private LocalDateTime registerDateTime;
// 응답결과
// "registerDateTime": "2022-05-30T14:00:00"

@JsonFormat(pattern = "yyyyMMddHHmmss")
private LocalDateTime registerDateTime;
// 응답결과
// "registerDateTime": "20220530140000"

모든 날짜 타입에 동일한 변환 규칙 적용

스프링 MVC설저을 변경해야 한다.

Jackson은 자바객체를 JSON으로 변환할 때 MappingJackson2HttpMessageConverter를 사용. 

MappingJackson2HttpMessageConverter를 새로 등록해서 날짜 형식을 원하는 형식으로 변환하도록 설정할 수 있다.

 

4. @RequestBody로 JSON 요청 처리

JSON 형식으로 전송된 요청 데이터를 커맨드 객체로 전달

@PostMapping("/api/members")
public void new Member(
        @RequestBody @Valid RegisterRequest regReq, // RegisterRequest 타입 객체로 변환 가능
        HttpServletResponse response) throws IOException{
    try{
       ....
    }        
    ...
}

날짜 형식

  • 별도 설정이 없을 시
    • yyyy-MM-ddTHH:mm:ss
  • pattern속성 사용 가능
@JsonFormat(pattern = "yyyyMMddHHmmss")
private LocalDateTime birthDateTime;

해당 타입을 모든 속성에 적용하고 싶다면 MVC설정에 추가.

 

요청 객체 검증

@Valid 애노테이션을 사용하여 Validator를 이용해 검증할 수 있다.

실패하면 400상태 코드로 응답하기에 상태코드를 직접 처리해주어야 한다.

 

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

정상인 경우, 비정상인 경우 모두 JSON으로 응답할 수 있도록 하기 위해 사용

(정상일 땐 JSON, 비정상일 땐 HTML로 응답한다면, 호출한 프로그램이 부담스럽기 때문에)

import org.springframework.http.ResponseEntity;

@RestController
public class RestMemberController{
    ...
    @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"));// ErrorResponse를 JSON으로 변환
        }
        return ResponseEntity.status(HttpStatus.OK).body(member)
        // member를 body로 지정했기에 member객체를 JSON으로 변환
    }
}

// 형식
// ResponseEntity.status(상태코드).body(객체)
// ResponseEntity.ok(body) -> 200 응답코드라면 다음이 가능
// ResponseEntity.status(상태코드).build()  -> 몸체 내용이 없을 때
// ResponseEntity.notFound().build()  -> 몸체 내용이 없을 땐 관련 메서드를 사용해도 된다
//     관련 메서드 -> noContent() - 204, badRequest() - 400, notFound() - 404

@ExceptionHandler

해당 애노테이션을 적용한 메서드에서 여러 에러 응답을 처리하도록 할 수있다.

@GetMapping("/api/members/{id}")
public Member member(...){
    ...
    if(member == null)
        throw new MemberNotFoundException(); //익셉션 발생 시
    return member;
}

@ExceptionHandler(MemberNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNoData(){// 얘가 에러를 처리
    return ResponseEntity.
       ...
}

@RestControllerAdvice

@ControllerAdvice 애노테이션과 동일하지만, 응답을 JSON이나 XML과 같은 형식으로 변환해준다.

 

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

  • @Valid 애노테이션을 붙인 커맨드 객체가 검증에 실패하면 400 코드를 응답
  • 이친구는 HTML 응답을 전송한다.
  • JSON으로 응답하기 위해선 Errors 타입 파라미터를 추가해서 직접 에러 응답을 생성해야 한다.
  • @RequestBody가 붙어있는 경우 Error파라미터가 존재하지 않으면 MethodArgumentNotValidException이 발생
  • @ExceptionHandler 애노테이션을 이요해서 에러 응답을 생성해도 된다.

 

 

Comments