需要使用restTemplate做一些對網絡的操作,在springboot項目中,配置了一下
@Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { builder.additionalInterceptors(requestInterceptor()); return builder.build(); } @Bean public ClientHttpRequestInterceptor requestInterceptor() { return (request, body, execution) -> { // 測試代碼
request.getHeaders().forEach((k, v) -> {
System.out.println("Header: " + k + " : " + v);
});
return execution.execute(request, body);
};
}
運行后,但是配置的攔截器始終沒有生效。沒有頭信息的輸出。
於是找原因,在RestTemplateBuilder中看到源碼是這樣的:
/** * Add additional {@link ClientHttpRequestInterceptor ClientHttpRequestInterceptors} * that should be used with the {@link RestTemplate}. * @param interceptors the interceptors to add * @return a new builder instance * @since 1.4.1 * @see #interceptors(ClientHttpRequestInterceptor...) */ public RestTemplateBuilder additionalInterceptors(Collection<? extends ClientHttpRequestInterceptor> interceptors) { Assert.notNull(interceptors, "interceptors must not be null"); return new RestTemplateBuilder(this.requestFactoryCustomizer, this.detectRequestFactory, this.rootUri, this.messageConverters, append(this.interceptors, interceptors), this.requestFactory, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers); }
原來是這里的問題:
return new RestTemplateBuilder...
spring注入的builder示例為A:
public RestTemplate restTemplate(RestTemplateBuilder builder) {
返回的是一個新示例,那么攔截器添加到的是到新實例B(
return new RestTemplateBuilder..
),在方法注釋上有寫:return a new builder instance。
往下走繼續builder.build()就是使用A在build,而不是B去build。
不細看,不鏈式操作的情況下~真的有點容易出錯。