Spring에서 HTTP Header 이용

귀찮Lee·2022년 8월 21일
8

Spring

목록 보기
17/30

HTTP

  • HTTP (HyperText Transfer Protocol)
    • HTML과 같은 문서를 전송하기 위한 Application Layer 프로토콜
    • Header와 본문 내용으로 구성
    • Annotation을 통해 값을 가져올 수 있다.

◎ HTTP 헤더(Header)

  • HTTP 헤더(Header)

    • 클라이언트의 요청이나 서버의 응답에 포함되어 부가적인 정보를 담고 있음
  • 대표적인 HTTP 헤더 예시

    • ‘Content-Type’

      • 서버가 주고 받는 HTTP 메시지 바디(body, 본문)의 데이터 형식이 무엇인지를 알려주는 역할
      • 화면 정보가 아닌 데이터를 주고 받을때는 주로 'application/json'을 사용
    • Authorization

      • 클라이언트가 적절한 자격 증명을 가지고 있는지를 확인하기 위한 정보를 담음
      • 일반적으로 REST API 기반 애플리케이션의 경우 클라이언트와 서버 간의 로그인 인증에 통과한 클라이언트들은 ‘Authorization’ 헤더 정보를 기준으로 인증에 통과한 클라이언트가 맞는지 확인하는 절차를 거친다.
    • User-Agent

      • 모바일 에이전트에서 들어오는 요청인지 모바일 이외에 다른 에이전트에서 들어오는 요청인지를 구분해서 처리 가능

◎ Spring, HTTP Header 정보 얻기

  • 개별 헤더 정보 받기

    @RestController
    @RequestMapping(path = "/coffees")
    public class CoffeeController {
        @PostMapping
        public ResponseEntity postCoffee(@RequestHeader("user-agent") String userAgent,
                                         @RequestParam("name") String name,
                                         @RequestParam("price") int price) {
    
            System.out.println("user-agent: " + userAgent);
            return new ResponseEntity<>(new Coffee(name, price), HttpStatus.CREATED);
        }
    }
  • 전체 헤더 정보 받기

    @RestController
    @RequestMapping(path = "/members")
    public class MemberController {
        @PostMapping
        public ResponseEntity postMember(@RequestHeader Map<String, String> headers,
                                         @RequestParam("email") String email,
                                         @RequestParam("name") String name,
                                         @RequestParam("phone") String phone) {
    
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                System.out.println("key: " + entry.getKey() +
                        ", value: " + entry.getValue());
            }
    
            return new ResponseEntity<>(new Member(email, name, phone),
                    HttpStatus.CREATED);
        }
    }
  • HttpServletRequest 이용

    • HttpServletRequest 이용시, Request 헤더 정보에 다양한 방법으로 접근 가능
    • HttpServletRequest는 다양한 API를 지원함
      • 단순히 특정 헤더 정보에 접근시에는 @RequestHeader를 사용하는 것을 추천
    • 저수준(Low Level)의 서블릿 API를 사용할 수 있기때문에 복잡한 HTTP Request/Response를 처리하는데 사용
    @RestController
    @RequestMapping(path = "/v1/orders")
    public class OrderController {
        @PostMapping
        public ResponseEntity postOrder(HttpServletRequest httpServletRequest,
                                        @RequestParam("memberId") long memberId,
                                        @RequestParam("coffeeId") long coffeeId) {
    
            String userAgent = httpServletRequest.getHeader("user-agent");
            System.out.println("user-agent: " + userAgent);
    
            return new ResponseEntity<>(new Order(memberId, coffeeId),
                    HttpStatus.CREATED);
        }
    }
  • HttpEntity 이용

    • Spring MVC에서는 HttpEntity 객체를 통해서도 헤더 정보를 읽을 수 있다.
    • HttpEntity는 Request 헤더와 바디 정보를 래핑하고 있음
    • 조금 더 쉽게 헤더와 바디에 접근할 수 있는 다양한 API를 지원
    @RestController
    @RequestMapping(path = "/v1/coffees")
    public class CoffeeController{
    
        @GetMapping
        public ResponseEntity getCoffees(HttpEntity httpEntity) {
    
            for(Map.Entry<String, List<String>> entry : httpEntity.getHeaders().entrySet()){
                System.out.println("key: " + entry.getKey()
                        + ", " + "value: " + entry.getValue());
            }
    
            // Host 정보도 가져올 수 있다.
            System.out.println("host: " + httpEntity.getHeaders().getHost());
            // host: localhost:8080
            return null;
        }
    }

◎ Spring, HTTP Header 정보 추가

  • 예시

    • ResponseEntity, HttpHeaders 이용
      • Spring에서 지원하는 고수준(High Level) API로써 간단한 HTTP Request/Response 처리를 빠르게 진행
    @RestController
    @RequestMapping(path = "/members")
    public class MemberController{
        @PostMapping
        public ResponseEntity postMember(@RequestParam("email") String email,
                                         @RequestParam("name") String name,
                                         @RequestParam("phone") String phone) {
            // (1) 위치 정보를 헤더에 추가
            HttpHeaders headers = new HttpHeaders();
            headers.set("Client-Geo-Location", "Korea,Seoul");
    
            return new ResponseEntity<>(new Member(email, name, phone), headers,
                    HttpStatus.CREATED);
        }
    }
    • HttpServletResponse 이용
      • 저수준(Low Level)의 서블릿 API를 사용할 수 있기때문에 복잡한 HTTP Request/Response를 처리하는데 사용
    @RestController
    @RequestMapping(path = "/members")
    public class MemberController{
        @GetMapping
        public ResponseEntity getMembers(HttpServletResponse response) {
            response.addHeader("Client-Geo-Location", "Korea,Seoul");
    
            return null;
        }
    }
  • 커스텀 헤더(Custom Header) 사용

    • 기본적으로 포함되어 있는 헤더 정보는 개발자가 컨트롤 해야 될 경우가 생각보다 많지 않음
    • 커스텀 헤더를 종종 추가해서 부가적인 정보를 전달하는 경우가 있다.
  • 커스텀 헤더 네이밍(Naming)

    • 2012년 이전에는 'X-'라는 접두사를 붙이는 것이 관례였으나, 문제점이 발생할 가능성이 높아서 더 이상 사용하지 않음
    • 헤더를 사용하는 측에서 헤더의 목적을 쉽게 이용할 수 있도록 대시(-)를 기준으로 의미가 명확한 용어를 사용
      • 대시(-)를 기준으로 각 단어의 첫 글자를 대문자로 작성하는 것이 관례
      • Spring에서 Request 헤더 정보를 확인할 때, 대/소문자를 구분하지 않음
profile
배운 것은 기록하자! / 오류 지적은 언제나 환영!

1개의 댓글

comment-user-thumbnail
2023년 8월 18일

정리가 깔끔하게 잘 되어있네요. 스프링 공부중에 큰 도움 받았습니다. 감사해요.

답글 달기