001/* 002 * Copyright 2002-2019 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.io.IOException; 020import java.net.URI; 021import java.util.ArrayList; 022import java.util.List; 023 024import org.apache.commons.logging.Log; 025 026import org.springframework.core.annotation.AnnotationAwareOrderComparator; 027import org.springframework.http.HttpLogging; 028import org.springframework.http.HttpMethod; 029import org.springframework.http.client.ClientHttpRequest; 030import org.springframework.http.client.ClientHttpRequestFactory; 031import org.springframework.http.client.ClientHttpRequestInitializer; 032import org.springframework.http.client.SimpleClientHttpRequestFactory; 033import org.springframework.util.Assert; 034 035/** 036 * Base class for {@link org.springframework.web.client.RestTemplate} 037 * and other HTTP accessing gateway helpers, defining common properties 038 * such as the {@link ClientHttpRequestFactory} to operate on. 039 * 040 * <p>Not intended to be used directly. 041 * 042 * <p>See {@link org.springframework.web.client.RestTemplate} for an entry point. 043 * 044 * @author Arjen Poutsma 045 * @author Juergen Hoeller 046 * @author Phillip Webb 047 * @since 3.0 048 * @see ClientHttpRequestFactory 049 * @see org.springframework.web.client.RestTemplate 050 */ 051public abstract class HttpAccessor { 052 053 /** Logger available to subclasses. */ 054 protected final Log logger = HttpLogging.forLogName(getClass()); 055 056 private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); 057 058 private final List<ClientHttpRequestInitializer> clientHttpRequestInitializers = new ArrayList<>(); 059 060 061 /** 062 * Set the request factory that this accessor uses for obtaining client request handles. 063 * <p>The default is a {@link SimpleClientHttpRequestFactory} based on the JDK's own 064 * HTTP libraries ({@link java.net.HttpURLConnection}). 065 * <p><b>Note that the standard JDK HTTP library does not support the HTTP PATCH method. 066 * Configure the Apache HttpComponents or OkHttp request factory to enable PATCH.</b> 067 * @see #createRequest(URI, HttpMethod) 068 * @see SimpleClientHttpRequestFactory 069 * @see org.springframework.http.client.HttpComponentsAsyncClientHttpRequestFactory 070 * @see org.springframework.http.client.OkHttp3ClientHttpRequestFactory 071 */ 072 public void setRequestFactory(ClientHttpRequestFactory requestFactory) { 073 Assert.notNull(requestFactory, "ClientHttpRequestFactory must not be null"); 074 this.requestFactory = requestFactory; 075 } 076 077 /** 078 * Return the request factory that this accessor uses for obtaining client request handles. 079 */ 080 public ClientHttpRequestFactory getRequestFactory() { 081 return this.requestFactory; 082 } 083 084 085 /** 086 * Set the request initializers that this accessor should use. 087 * <p>The initializers will get immediately sorted according to their 088 * {@linkplain AnnotationAwareOrderComparator#sort(List) order}. 089 * @since 5.2 090 */ 091 public void setClientHttpRequestInitializers( 092 List<ClientHttpRequestInitializer> clientHttpRequestInitializers) { 093 094 if (this.clientHttpRequestInitializers != clientHttpRequestInitializers) { 095 this.clientHttpRequestInitializers.clear(); 096 this.clientHttpRequestInitializers.addAll(clientHttpRequestInitializers); 097 AnnotationAwareOrderComparator.sort(this.clientHttpRequestInitializers); 098 } 099 } 100 101 /** 102 * Get the request initializers that this accessor uses. 103 * <p>The returned {@link List} is active and may be modified. Note, 104 * however, that the initializers will not be resorted according to their 105 * {@linkplain AnnotationAwareOrderComparator#sort(List) order} before the 106 * {@link ClientHttpRequest} is initialized. 107 * @since 5.2 108 * @see #setClientHttpRequestInitializers(List) 109 */ 110 public List<ClientHttpRequestInitializer> getClientHttpRequestInitializers() { 111 return this.clientHttpRequestInitializers; 112 } 113 114 /** 115 * Create a new {@link ClientHttpRequest} via this template's {@link ClientHttpRequestFactory}. 116 * @param url the URL to connect to 117 * @param method the HTTP method to execute (GET, POST, etc) 118 * @return the created request 119 * @throws IOException in case of I/O errors 120 * @see #getRequestFactory() 121 * @see ClientHttpRequestFactory#createRequest(URI, HttpMethod) 122 */ 123 protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException { 124 ClientHttpRequest request = getRequestFactory().createRequest(url, method); 125 initialize(request); 126 if (logger.isDebugEnabled()) { 127 logger.debug("HTTP " + method.name() + " " + url); 128 } 129 return request; 130 } 131 132 private void initialize(ClientHttpRequest request) { 133 this.clientHttpRequestInitializers.forEach(initializer -> initializer.initialize(request)); 134 } 135 136}