001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.http.client.support; 018 019import java.util.ArrayList; 020import java.util.List; 021 022import org.springframework.core.annotation.AnnotationAwareOrderComparator; 023import org.springframework.http.client.ClientHttpRequestFactory; 024import org.springframework.http.client.ClientHttpRequestInterceptor; 025import org.springframework.http.client.InterceptingClientHttpRequestFactory; 026import org.springframework.lang.Nullable; 027import org.springframework.util.Assert; 028import org.springframework.util.CollectionUtils; 029 030/** 031 * Base class for {@link org.springframework.web.client.RestTemplate} 032 * and other HTTP accessing gateway helpers, adding interceptor-related 033 * properties to {@link HttpAccessor}'s common properties. 034 * 035 * <p>Not intended to be used directly. 036 * See {@link org.springframework.web.client.RestTemplate} for an entry point. 037 * 038 * @author Arjen Poutsma 039 * @author Juergen Hoeller 040 * @since 3.0 041 * @see ClientHttpRequestInterceptor 042 * @see InterceptingClientHttpRequestFactory 043 * @see org.springframework.web.client.RestTemplate 044 */ 045public abstract class InterceptingHttpAccessor extends HttpAccessor { 046 047 private final List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(); 048 049 @Nullable 050 private volatile ClientHttpRequestFactory interceptingRequestFactory; 051 052 053 /** 054 * Set the request interceptors that this accessor should use. 055 * <p>The interceptors will get immediately sorted according to their 056 * {@linkplain AnnotationAwareOrderComparator#sort(List) order}. 057 * @see #getRequestFactory() 058 * @see AnnotationAwareOrderComparator 059 */ 060 public void setInterceptors(List<ClientHttpRequestInterceptor> interceptors) { 061 Assert.noNullElements(interceptors, "'interceptors' must not contain null elements"); 062 // Take getInterceptors() List as-is when passed in here 063 if (this.interceptors != interceptors) { 064 this.interceptors.clear(); 065 this.interceptors.addAll(interceptors); 066 AnnotationAwareOrderComparator.sort(this.interceptors); 067 } 068 } 069 070 /** 071 * Get the request interceptors that this accessor uses. 072 * <p>The returned {@link List} is active and may be modified. Note, 073 * however, that the interceptors will not be resorted according to their 074 * {@linkplain AnnotationAwareOrderComparator#sort(List) order} before the 075 * {@link ClientHttpRequestFactory} is built. 076 */ 077 public List<ClientHttpRequestInterceptor> getInterceptors() { 078 return this.interceptors; 079 } 080 081 /** 082 * {@inheritDoc} 083 */ 084 @Override 085 public void setRequestFactory(ClientHttpRequestFactory requestFactory) { 086 super.setRequestFactory(requestFactory); 087 this.interceptingRequestFactory = null; 088 } 089 090 /** 091 * Overridden to expose an {@link InterceptingClientHttpRequestFactory} 092 * if necessary. 093 * @see #getInterceptors() 094 */ 095 @Override 096 public ClientHttpRequestFactory getRequestFactory() { 097 List<ClientHttpRequestInterceptor> interceptors = getInterceptors(); 098 if (!CollectionUtils.isEmpty(interceptors)) { 099 ClientHttpRequestFactory factory = this.interceptingRequestFactory; 100 if (factory == null) { 101 factory = new InterceptingClientHttpRequestFactory(super.getRequestFactory(), interceptors); 102 this.interceptingRequestFactory = factory; 103 } 104 return factory; 105 } 106 else { 107 return super.getRequestFactory(); 108 } 109 } 110 111}