HTTP

2024. 1. 16. 15:45
728x90

1. Serialization

- 직렬화 : 메모리 상에 저장된 데이터를 전송 가능한 형태로 바꾸는 작업.

Heap 메모리 내에 표현되어 있는 데이터는 읽을 수 없는 형태로 저장되어 있다.. >> 읽을 수 있는 글귀로 형식에 맞춰 표현하는 것을 직렬화라고 한다.

 

- JSON (JavaScript Object Notation)

: Lightweight data-interchange format. 데이터를 주고받는데 활용할 수 있는 데이터 표현 방식.

- JavaScript 객체를 표현하는 방식에서 그 문법을 차용.

- 중괄호 내부에 Key-Value쌍을 콜론으로 구분. 

- 사람이 읽고 쓰기 쉬움 / 기계가 파싱(해석)하고 만들기 편함

- 거의 대부분의 API 통신에서 사용.

 

 

 

2. @RequestMapping

- 클라이언트의 요청이 들어왔을 때 @RequestMapping에 전달한 설정에 일치할 경우 실행할 메서드를 설정한다.

@Slf4j
@Controller
public class MappingController {

    // @RequestMapping에 전달된 파라미터를 바탕으로
    // 어떤 http 요청에 대해 메서드가 실행되는지
    @RequestMapping(
            value = "/example/{pathVar}",
            method = {RequestMethod.GET, RequestMethod.POST},
            // 요청의 Content-Type 헤더
            consumes = MediaType.APPLICATION_JSON_VALUE,
            // headers : 어떤 headers가 포함되어야 실행이 되는지
            headers = "x-headers-example=hello",
            // params : 어떤 Query 파라미터가 있어야하는지
            params = "param-example=hello"
    )
    @ResponseBody
    public String example(@PathVariable String pathVar) {
        return "done";
    }
}

- value : 요청 url의 path

- method : 요청의 HTTP Method. 복수로 설정도 가능함. (Get요청, Post요청 둘다 이 메서드로 들어오게 된다)

- headers : 요청 헤더

- params : 요청 쿼리 파라미터 

- produces/ consumes : 요청/응답으로 주고받는 데이터 형식(Content-Type)을 전하는 용도

 

3. HTTP 메시지 다루기

1) @RequestHeader

: 사용자 요청의 헤더를 가지고 오고 싶을 때 활용.

- 개별 헤더를 가져와 메서드의 인자로 할당하는 방식. >> 인자로 확인하고 싶은 헤더를 전달.

  • 해당하는 헤더가 요청에 포함되어 있지 않으면 > 400 응답이 나오는데, 선택적으로 포함해야 되는 헤더라면 required=false를 추가.
  • 반드시 인자의 자료형이 문자열일 필요는 없음. > 헤더가 어떤 자료형인지 안다면 해당 타입으로 선언 가능. >> 타입이 일치하지 않으면 400이 반환됨.
  • defaultValue로 기본값을 설정할 수도 있다. 
    @PostMapping("/option-header")
    @ResponseBody
    public String optionHeader(
            @RequestHeader(
                    value = "x-example",
                    // required: 포함을 반드시 해야하는지
                    required = false
            )
            String example, // Integer example로도 가능
            @RequestHeader(
                    value = "x-example-default",
                    required = false,
                    // defaultValue: 포함안되었을때 기본값
                    defaultValue = "hello"
            )
            String exampleDefaultHeader
    ) {
        log.info(examplenHeader);
        log.info(exampleDefaultHeader);
        return exampleDefaultHeader;
    }

 

- 전송된 모든 헤더를 하나의 인자로 할당하는 방식.

: HttpHeaders / Map<String, String> / MultiValueMap<String, String> 로 담을 수 있다. 

@PostMapping(
        "/headers"
)
public String getHeaders(
        @RequestHeader HttpHeaders headers,
        @RequestHeader Map<String, String> headerMap,
        @RequestHeader MultiValueMap<String, String> headerMvMap
) {
    headers.forEach((key, value) -> log.warn(String.format("%s: %s, %s", key, value, value.getClass())));
    headerMap.forEach((key, value) -> log.warn(String.format("%s: %s, %s", key, value, value.getClass())));
    headerMvMap.forEach((key, value) -> log.warn(String.format("%s: %s, %s", key, value, value.getClass())));
    log.info("POST /headers");
    return "index";
}

 

 

2) @RequestBody / @ResponseBody

: 요청과 응답의 Body 형태를 결정하는 어노테이션

- 클라이언트가 보낸 데이터의 필드가 지정된 객체와 동일할 경우 그 데이터를 할당해서 객체를 만들어줌.

- @RequestBody : 클라이언트가 보낸 HTTP Body의 데이터가 지정된 객체(ArticleDto)의 필드와 일치할 때 해당 데이터를 객체화하여 메서드의 인자로 할당.

- @ResponseBody : 메서드 자체에 지정하여 반환값에 대하여 작동. View가 아니라 지정된 객체를 JSON을 비롯한 데이터로 변환하여 응답.

- ** @RestController를 사용하면 > 모든 메서드에 @ResponseBody가 추가된다.

@RestController
public class ArticleController {

@PostMapping("/dto")
@ResponseBody
// 메서드의 반환값을 View로 취급하지 않고, 순수한 전달될 HTTP Response로 취급하는 어노테이션
public ArticleDto body(@RequestBody ArticleDto dto) {
    log.info("POST /dto, body: " + dto.toString());
    LocalDateTime now = LocalDateTime.now();
    dto.setCreatedAt(now);
    dto.setUpdatedAt(now);
    return dto;
}

 

3) ResponseEntity

: 좀더 세밀한 응답 조절이 필요할 때 반환형으로 ResponseEntity를 사용. (@ResponseBody 생략)

- ResponseEntity는 제네릭 타입으로 응답 타입을 그대로 활용하는데 도움.

- 응답 상태 코드를 지정하거나,,,

    @PostMapping("student/entity")
    public ResponseEntity<MessageDto> postEntity(
            @RequestBody
            StudentDto studentDto
    ) {
        log.info(studentDto.toString());
        MessageDto messageDto = new MessageDto();
        messageDto.setMessage("등록 완료");
        return new ResponseEntity<>(messageDto, HttpStatus.CREATED);
    }
    // 결과 Status 201 Created

 

- 응답에 추가하고 싶은 Header를 포함시키는 등... 세밀하게 응답 조정이 가능!

    @PostMapping("student/entity")
    public ResponseEntity<MessageDto> postEntity(
            @RequestBody
            StudentDto studentDto
    ) {
        log.info(studentDto.toString());
        MessageDto messageDto = new MessageDto();
        messageDto.setMessage("등록 완료");

// headers 설정
        HttpHeaders headers = new HttpHeaders();
        headers.add("x-example-response", "okay");
        headers.add("x-example-name", "hehesim");

        return new ResponseEntity<>(messageDto, headers, HttpStatus.ACCEPTED);
    }

 

+ status빌더와 함께 빌더 메서드로도 표현이 가능.

    @GetMapping("student/bad-request")
    public ResponseEntity<MessageDto> badRequest(
            @RequestBody
            StudentDto studentDto
    ) {
        log.info(studentDto.toString());

        MessageDto messageDto = new MessageDto();
        if (studentDto.getAge() < 10) {
            messageDto.setMessage("너무 어려요");
//            return new ResponseEntity<>(messageDto, HttpStatus.BAD_REQUEST);
            return ResponseEntity.badRequest()
                    .header("x-example-response", "bad request")
                    .body(messageDto);
        } else {
            messageDto.setMessage("ok");
//            return new ResponseEntity<>(messageDto, HttpStatus.OK);
            return ResponseEntity.badRequest()
                    .header("x-example-response", "ok")
                    .body(messageDto);
        }

 

 

** Handler Method

Method Arguments :: Spring Framework

 

Method Arguments :: Spring Framework

JDK 8’s java.util.Optional is supported as a method argument in combination with annotations that have a required attribute (for example, @RequestParam, @RequestHeader, and others) and is equivalent to required=false.

docs.spring.io

 

728x90

'Programming > Network' 카테고리의 다른 글

HTTP  (2) 2024.11.29
URI와 웹 브라우저 요청 흐름  (0) 2024.11.26
인터넷 네트워크  (4) 2024.11.23
Web  (0) 2024.01.16
인터넷 네트워크 정리  (0) 2023.09.14

BELATED ARTICLES

more