본문 바로가기

Programing/Framework

WebClient: 기본 헤더 설정을 Consumer 를 이용하기(Java/Kotlin)

Java

WebClient 에 공통적으로 사용하는 헤더가 있다면 defaultHeader 를 이용하여 설정해놓으면 매번 WebClient 사용할 때마다 설정할 필요가 없어진다.

WebClient webClient = WebClient.builder()
        .baseUrl("http://markbucciarelli.com")
        .defaultHeader("Authorization", "Bearer 7e0af818e0564a238bbcf6b9a0f7c176")
        .build();

Authorization 는 알려져 있는 헤더이므로 org.springframework.http 패키지의 HttpHeaders 클래스의 상수에 이미 정의되어 있다.

package org.springframework.http;

public class HttpHeaders implements MultiValueMap<String, String>, Serializable {
	// ..
	public static final String AUTHORIZATION = "Authorization";

아래와 같이 매직 문자(?)를 상수로 대체할 수 있다.

WebClient webClient = WebClient.builder()
        .baseUrl("http://markbucciarelli.com")
        .defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer 7e0af818e0564a238bbcf6b9a0f7c176")
        .build();

 

HttpHeaders 클래스에는 Bearer token을 설정할 수 있도록 setter가 이미 있다.

package org.springframework.http;

public class HttpHeaders implements MultiValueMap<String, String>, Serializable {
	// ..
	public void setBearerAuth(String token) {
		set(AUTHORIZATION, "Bearer " + token);
	}

 

defaultHeader를 설정하는 함수는 스프링 5.3.22 버전 기준 두 가지가 있다.

defaultHeader 에 -s 가 더 붙은 메서드이므로 주의한다. (삽질해본 사람은 안다)

 

아직 호출하는 쪽에서는 없는 HttpHeaders 객체를 조작할 수 있도록 Consumer 를 받을 수 있는 메서드가 더 있다.

WebClient webClient = WebClient.builder()
        .baseUrl("http://markbucciarelli.com")
        .defaultHeaders(headers -> headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176"))
        .build();

Kotlin

스프링을 Kotlin에서 사용할 경우 해당 Consumer 적용은 어떻게 할까?

아래와 같이 {  } 를 사용하면 된다. 즉,람다 표현식(Lambda expressions)을 이용하는 것이다.

val webClient = builder
    .baseUrl("http://markbucciarelli.com")
    .defaultHeaders({ headers: HttpHeaders ->
        headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176")
    })
    .build()

 

또한 타입에 대해서는 추론이 가능하므로 HttpHeaders는 생략이 가능하다.

val webClient = builder
    .baseUrl("http://markbucciarelli.com")
    .defaultHeaders({ headers ->
        headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176")
    })
    .build()

 

또한 Kotlin 은 마지막 람다 표현식의 경우 ( ) 괄호 밖으로 뺄 수 있다. Passing trailing lambdas 참고.

IntelliJ IDEA에서는 아래와 같은 Tip으로 알려준다.

Lambda argument should be moved out of parentheses

val webClient = builder
    .baseUrl("http://markbucciarelli.com")
    .defaultHeaders() { headers ->
        headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176")
    }
    .build()

 

defaultHeaders() 는 파라미터가 없으므로 괄호 ( )는 생략이 가능하다.

IntelliJ IDEA에서는 아래와 같은 Tip으로 알려준다.

Remove unnecessary parentheses from function call with lambda

val webClient = builder
    .baseUrl("http://markbucciarelli.com")
    .defaultHeaders { headers ->
        headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176")
    }
    .build()

또한 인자가 하나밖에 없는 경우에는 it 으로 대체할 수 있다. it: implicit name of a single parameter 참고

IntelliJ IDEA에서는 아래와 같은 Tip으로 알려준다.

Replace explicit parameter 'headers' with 'it'

val webClient = builder
    .baseUrl("http://markbucciarelli.com")
    .defaultHeaders{ it.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176") }
    .build()

정리

여러가지 구현을 한 곳에 정리해봅니다.

Java

  1. defaultHeader("Authorization", "Bearer 7e0af818e0564a238bbcf6b9a0f7c176")
  2. defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer 7e0af818e0564a238bbcf6b9a0f7c176")
  3. defaultHeaders(headers -> headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176"))

Kotlin

  1. defaultHeaders({ headers: HttpHeaders -> headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176") })
  2. defaultHeaders({ headers -> headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176") })
  3. defaultHeaders() { headers -> headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176") }
  4. defaultHeaders { headers -> headers.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176") }
  5. defaultHeaders{ it.setBearerAuth("7e0af818e0564a238bbcf6b9a0f7c176") }