下面列出了org.springframework.http.client.AbstractClientHttpRequestFactoryWrapper#org.springframework.http.client.ClientHttpRequest 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
ClientHttpRequest req = super.createRequest(url, method);
AuthenticatedUser loginUser = AuthenticationContextHolder.getCurrentUser();
if(loginUser != null && StringUtils.isNotBlank(loginUser.getToken())){
if (log.isDebugEnabled()) {
log.debug("request {} with access token:{}", url.toString(), loginUser.getToken());
}
req.getHeaders().add(HttpHeaders.AUTHORIZATION,
loginUser.getToken());
}
return req;
}
@SuppressWarnings("deprecation")
@Override
public ClientHttpResponse validateRequest(ClientHttpRequest request) throws IOException {
RequestExpectation expectation = null;
synchronized (this.requests) {
if (this.requests.isEmpty()) {
afterExpectationsDeclared();
}
try {
// Try this first for backwards compatibility
ClientHttpResponse response = validateRequestInternal(request);
if (response != null) {
return response;
}
else {
expectation = matchRequest(request);
}
}
finally {
this.requests.add(request);
}
}
return expectation.createResponse(request);
}
/**
* Create the {@link RestTemplate} to use.
* @return the {@link RestTemplate} to use.
*/
protected RestTemplate createTemplate() {
ClientHttpRequestFactory requestFactory = this.requestFactory.get();
LinkedHashMap<String, String> defaultHeaders = new LinkedHashMap<>(this.defaultHeaders);
LinkedHashSet<RestTemplateRequestCustomizer<ClientHttpRequest>> requestCustomizers = new LinkedHashSet<>(
this.requestCustomizers);
RestTemplate restTemplate = VaultClients.createRestTemplate(this.endpointProvider,
new RestTemplateBuilderClientHttpRequestFactoryWrapper(requestFactory, requestCustomizers));
restTemplate.getInterceptors().add((httpRequest, bytes, clientHttpRequestExecution) -> {
HttpHeaders headers = httpRequest.getHeaders();
defaultHeaders.forEach((key, value) -> {
if (!headers.containsKey(key)) {
headers.add(key, value);
}
});
return clientHttpRequestExecution.execute(httpRequest, bytes);
});
return restTemplate;
}
@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
ClientHttpRequest request = delegate.createRequest(uri, httpMethod);
String authorizationHeader = oAuthClient.getAuthorizationHeader();
if (authorizationHeader != null) {
request.getHeaders()
.add(AUTHORIZATION_HEADER_KEY, authorizationHeader);
}
if (credentials != null && credentials.getProxyUser() != null) {
request.getHeaders()
.add(PROXY_USER_HEADER_KEY, credentials.getProxyUser());
}
return request;
}
@Override
public void doWithRequest(ClientHttpRequest request) throws IOException {
request.getHeaders().putAll(this.headers);
if (this.body != null) {
StreamUtils.copy(this.body, SockJsFrame.CHARSET, request.getBody());
}
}
/**
* Execute the given method on the provided URI.
* <p>The {@link ClientHttpRequest} is processed using the {@link RequestCallback};
* the response with the {@link ResponseExtractor}.
* @param url the fully-expanded URL to connect to
* @param method the HTTP method to execute (GET, POST, etc.)
* @param requestCallback object that prepares the request (can be {@code null})
* @param responseExtractor object that extracts the return value from the response (can be {@code null})
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
*/
@Nullable
protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback,
@Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "URI is required");
Assert.notNull(method, "HttpMethod is required");
ClientHttpResponse response = null;
try {
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
handleResponse(url, method, response);
return (responseExtractor != null ? responseExtractor.extractData(response) : null);
}
catch (IOException ex) {
String resource = url.toString();
String query = url.getRawQuery();
resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
throw new ResourceAccessException("I/O error on " + method.name() +
" request for \"" + resource + "\": " + ex.getMessage(), ex);
}
finally {
if (response != null) {
response.close();
}
}
}
@Override
public void doWithRequest(ClientHttpRequest request) throws IOException {
if (this.responseType != null) {
List<MediaType> allSupportedMediaTypes = getMessageConverters().stream()
.filter(converter -> canReadResponse(this.responseType, converter))
.flatMap(this::getSupportedMediaTypes)
.distinct()
.sorted(MediaType.SPECIFICITY_COMPARATOR)
.collect(Collectors.toList());
if (logger.isDebugEnabled()) {
logger.debug("Accept=" + allSupportedMediaTypes);
}
request.getHeaders().setAccept(allSupportedMediaTypes);
}
}
/**
* Execute the given method on the provided URI.
* <p>The {@link ClientHttpRequest} is processed using the {@link RequestCallback};
* the response with the {@link ResponseExtractor}.
* @param url the fully-expanded URL to connect to
* @param method the HTTP method to execute (GET, POST, etc.)
* @param requestCallback object that prepares the request (can be {@code null})
* @param responseExtractor object that extracts the return value from the response (can be {@code null})
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
*/
protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "'url' must not be null");
Assert.notNull(method, "'method' must not be null");
ClientHttpResponse response = null;
try {
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
handleResponse(url, method, response);
if (responseExtractor != null) {
return responseExtractor.extractData(response);
}
else {
return null;
}
}
catch (IOException ex) {
throw new ResourceAccessException("I/O error on " + method.name() +
" request for \"" + url + "\": " + ex.getMessage(), ex);
}
finally {
if (response != null) {
response.close();
}
}
}
public ClientHttpResponse execute() throws IOException {
ClientHttpResponse response = delegate.execute();
if (response.getStatusCode() == HttpStatus.UNAUTHORIZED) {
logger.info("Token is invalid (got 401 response). Trying get a new token using the refresh token");
String newToken = callback.refreshToken();
if (newToken == null) {
return response;
} else {
logger.info("New token obtained, retrying the request with it");
// reflectively set the new token at the oauth2 interceptor (no nicer way, alas)
for (ClientHttpRequestInterceptor interceptor: requestInterceptors) {
if (interceptor.getClass().getName().equals("org.springframework.social.oauth2.OAuth2RequestInterceptor")) {
Field field = ReflectionUtils.findField(interceptor.getClass(), "accessToken");
field.setAccessible(true);
ReflectionUtils.setField(field, interceptor, newToken);
}
}
// create a new request, using the new token, but don't go through the refreshing factory again
// because it may cause an endless loop if all tokens are invalid
ClientHttpRequest newRequest = TokenRefreshingClientHttpRequestFactory.this.delegate.createRequest(delegate.getURI(), delegate.getMethod());
return newRequest.execute();
}
}
return response;
}
@Test
public void interceptShouldAddHeader() throws Exception {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
ClientHttpRequest request = requestFactory.createRequest(new URI("https://example.com"), HttpMethod.GET);
ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class);
byte[] body = new byte[] {};
new BasicAuthorizationInterceptor("spring", "boot").intercept(request, body,
execution);
verify(execution).execute(request, body);
assertEquals("Basic c3ByaW5nOmJvb3Q=", request.getHeaders().getFirst("Authorization"));
}
@Override
public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) {
return new MockClientHttpRequest(httpMethod, uri) {
@Override
public ClientHttpResponse executeInternal() throws IOException {
return getClientHttpResponse(httpMethod, uri, getHeaders(), getBodyAsBytes());
}
};
}
@Override
public final void match(ClientHttpRequest request) throws IOException, AssertionError {
try {
MockClientHttpRequest mockRequest = (MockClientHttpRequest) request;
matchInternal(mockRequest);
}
catch (Exception ex) {
throw new AssertionError("Failed to parse XML request content", ex);
}
}
@Override
public final void match(ClientHttpRequest request) throws IOException, AssertionError {
try {
MockClientHttpRequest mockRequest = (MockClientHttpRequest) request;
matchInternal(mockRequest);
}
catch (ParseException ex) {
throw new AssertionError("Failed to parse JSON request content", ex);
}
}
@Test
public void createRequest() throws Exception {
URI uri = new URI("/foo");
ClientHttpRequest expected = (ClientHttpRequest) this.server.expect(anything());
ClientHttpRequest actual = this.factory.createRequest(uri, HttpMethod.GET);
assertSame(expected, actual);
assertEquals(uri, actual.getURI());
assertEquals(HttpMethod.GET, actual.getMethod());
}
/**
* Return details of executed requests.
*/
protected String getRequestDetails() {
StringBuilder sb = new StringBuilder();
sb.append(this.requests.size()).append(" request(s) executed");
if (!this.requests.isEmpty()) {
sb.append(":\n");
for (ClientHttpRequest request : this.requests) {
sb.append(request.toString()).append("\n");
}
}
else {
sb.append(".\n");
}
return sb.toString();
}
/**
* Return an {@code AssertionError} that a sub-class can raise for an
* unexpected request.
*/
protected AssertionError createUnexpectedRequestError(ClientHttpRequest request) {
HttpMethod method = request.getMethod();
URI uri = request.getURI();
String message = "No further requests expected: HTTP " + method + " " + uri + "\n";
return new AssertionError(message + getRequestDetails());
}
/**
* Return a matching expectation, or {@code null} if none match.
*/
@Nullable
public RequestExpectation findExpectation(ClientHttpRequest request) throws IOException {
for (RequestExpectation expectation : this.expectations) {
try {
expectation.match(request);
return expectation;
}
catch (AssertionError error) {
// We're looking to find a match or return null..
}
}
return null;
}
@Override
protected RequestExpectation matchRequest(ClientHttpRequest request) throws IOException {
RequestExpectation expectation = this.repeatExpectations.findExpectation(request);
if (expectation == null) {
if (this.expectationIterator == null || !this.expectationIterator.hasNext()) {
throw createUnexpectedRequestError(request);
}
expectation = this.expectationIterator.next();
expectation.match(request);
}
this.repeatExpectations.update(expectation);
return expectation;
}
@Override
public RequestExpectation matchRequest(ClientHttpRequest request) throws IOException {
RequestExpectation expectation = this.remainingExpectations.findExpectation(request);
if (expectation == null) {
throw createUnexpectedRequestError(request);
}
this.remainingExpectations.update(expectation);
return expectation;
}
/**
* Get the body of the request as a UTF-8 string and compare it to the given String.
*/
public RequestMatcher string(final String expectedContent) {
return new RequestMatcher() {
@Override
public void match(ClientHttpRequest request) throws IOException, AssertionError {
MockClientHttpRequest mockRequest = (MockClientHttpRequest) request;
assertEquals("Request content", expectedContent, mockRequest.getBodyAsString());
}
};
}
/**
* Note that as of 5.0.3, the creation of the response, which may block
* intentionally, is separated from request count tracking, and this
* method no longer increments the count transparently. Instead
* {@link #incrementAndValidate()} must be invoked independently.
*/
@Override
public ClientHttpResponse createResponse(@Nullable ClientHttpRequest request) throws IOException {
ResponseCreator responseCreator = getResponseCreator();
Assert.state(responseCreator != null, "createResponse() called before ResponseCreator was set");
return responseCreator.createResponse(request);
}
@SuppressWarnings("deprecation")
private ClientHttpRequest createRequest(HttpMethod method, String url) {
try {
return new org.springframework.mock.http.client.MockAsyncClientHttpRequest(method, new URI(url));
}
catch (URISyntaxException ex) {
throw new IllegalStateException(ex);
}
}
@SuppressWarnings("deprecation")
private ClientHttpRequest createRequest(HttpMethod method, String url) {
try {
return new org.springframework.mock.http.client.MockAsyncClientHttpRequest(method, new URI(url));
}
catch (URISyntaxException ex) {
throw new IllegalStateException(ex);
}
}
@Override
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
ClientHttpRequest req = super.createRequest(url, method);
JwtSsoAccessToken at = jwtSsoClientContext.getAccessToken();
if (log.isDebugEnabled()) {
log.debug("request {} with access token:{}", url.toString(), at.getToken());
}
req.getHeaders().add(JwtSsoClientContext.HEADER_AUTHORIZATION,
JwtSsoClientContext.PREFIX_BEARER_TOKEN + at.getToken());
return req;
}
@Override
public void doWithRequest(ClientHttpRequest request) throws IOException {
request.getHeaders().putAll(this.headers);
if (this.body != null) {
StreamUtils.copy(this.body, SockJsFrame.CHARSET, request.getBody());
}
}
/**
* Execute the given method on the provided URI.
* <p>The {@link ClientHttpRequest} is processed using the {@link RequestCallback};
* the response with the {@link ResponseExtractor}.
* @param url the fully-expanded URL to connect to
* @param method the HTTP method to execute (GET, POST, etc.)
* @param requestCallback object that prepares the request (can be {@code null})
* @param responseExtractor object that extracts the return value from the response (can be {@code null})
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
*/
@Nullable
protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback,
@Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "URI is required");
Assert.notNull(method, "HttpMethod is required");
ClientHttpResponse response = null;
try {
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
handleResponse(url, method, response);
return (responseExtractor != null ? responseExtractor.extractData(response) : null);
}
catch (IOException ex) {
String resource = url.toString();
String query = url.getRawQuery();
resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
throw new ResourceAccessException("I/O error on " + method.name() +
" request for \"" + resource + "\": " + ex.getMessage(), ex);
}
finally {
if (response != null) {
response.close();
}
}
}
@Test
public void failFast() throws Exception {
ClientHttpRequestFactory requestFactory = Mockito
.mock(ClientHttpRequestFactory.class);
ClientHttpRequest request = Mockito.mock(ClientHttpRequest.class);
ClientHttpResponse response = Mockito.mock(ClientHttpResponse.class);
Mockito.when(requestFactory.createRequest(Mockito.any(URI.class),
Mockito.any(HttpMethod.class))).thenReturn(request);
RestTemplate restTemplate = new RestTemplate(requestFactory);
ConfigClientProperties defaults = new ConfigClientProperties(this.environment);
defaults.setFailFast(true);
this.locator = new ConfigServicePropertySourceLocator(defaults);
Mockito.when(request.getHeaders()).thenReturn(new HttpHeaders());
Mockito.when(request.execute()).thenReturn(response);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
Mockito.when(response.getHeaders()).thenReturn(headers);
Mockito.when(response.getStatusCode())
.thenReturn(HttpStatus.INTERNAL_SERVER_ERROR);
Mockito.when(response.getBody())
.thenReturn(new ByteArrayInputStream("{}".getBytes()));
this.locator.setRestTemplate(restTemplate);
this.expected
.expectCause(IsInstanceOf.instanceOf(IllegalArgumentException.class));
this.expected.expectMessage("fail fast property is set");
this.locator.locateCollection(this.environment);
}
@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
ClientHttpRequest request = super.createRequest(uri, httpMethod);
HttpHeaders headers = request.getHeaders();
headers.add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0");
headers.add("Connection", "keep-alive");
return request;
}
@Before
public void setup() {
requestFactory = mock(ClientHttpRequestFactory.class);
request = mock(ClientHttpRequest.class);
response = mock(ClientHttpResponse.class);
errorHandler = mock(ResponseErrorHandler.class);
converter = mock(HttpMessageConverter.class);
template = new RestTemplate(Collections.singletonList(converter));
template.setRequestFactory(requestFactory);
template.setErrorHandler(errorHandler);
}
@Test
public void interceptShouldAddHeader() throws Exception {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
ClientHttpRequest request = requestFactory.createRequest(new URI("http://example.com"), HttpMethod.GET);
ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class);
byte[] body = new byte[] {};
new BasicAuthorizationInterceptor("spring", "boot").intercept(request, body,
execution);
verify(execution).execute(request, body);
assertEquals("Basic c3ByaW5nOmJvb3Q=", request.getHeaders().getFirst("Authorization"));
}