From f93cb2f539e9fa7b371dfec05a45c91b423d6a96 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Thu, 25 Aug 2016 17:14:09 +0200 Subject: [PATCH] Support ordered interceptors in RestTemplate This commit sorts `ClientHttpRequestInterceptor`s when those are set in `InterceptingHttpAccessor` (which `RestTemplate` extends from). Interceptors can now be annotated with `@Order` or implements `Ordered` to reflect their order of execution for each request. Issue: SPR-13971 --- .../support/InterceptingHttpAccessor.java | 2 + .../InterceptingHttpAccessorTests.java | 91 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 spring-web/src/test/java/org/springframework/http/client/support/InterceptingHttpAccessorTests.java diff --git a/spring-web/src/main/java/org/springframework/http/client/support/InterceptingHttpAccessor.java b/spring-web/src/main/java/org/springframework/http/client/support/InterceptingHttpAccessor.java index 704b421bd2e..ecb28598a3b 100644 --- a/spring-web/src/main/java/org/springframework/http/client/support/InterceptingHttpAccessor.java +++ b/spring-web/src/main/java/org/springframework/http/client/support/InterceptingHttpAccessor.java @@ -19,6 +19,7 @@ package org.springframework.http.client.support; import java.util.ArrayList; import java.util.List; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.InterceptingClientHttpRequestFactory; @@ -40,6 +41,7 @@ public abstract class InterceptingHttpAccessor extends HttpAccessor { * Sets the request interceptors that this accessor should use. */ public void setInterceptors(List interceptors) { + AnnotationAwareOrderComparator.sort(interceptors); this.interceptors = interceptors; } diff --git a/spring-web/src/test/java/org/springframework/http/client/support/InterceptingHttpAccessorTests.java b/spring-web/src/test/java/org/springframework/http/client/support/InterceptingHttpAccessorTests.java new file mode 100644 index 00000000000..0e515883a31 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/http/client/support/InterceptingHttpAccessorTests.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.http.client.support; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.hamcrest.Matchers; +import org.junit.Test; + +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; + +/** + * Tests for {@link InterceptingHttpAccessor}. + * + * @author Brian Clozel + */ +public class InterceptingHttpAccessorTests { + + @Test + public void getInterceptors() throws Exception { + TestInterceptingHttpAccessor accessor = new TestInterceptingHttpAccessor(); + List interceptors = Arrays.asList( + new SecondClientHttpRequestInterceptor(), + new ThirdClientHttpRequestInterceptor(), + new FirstClientHttpRequestInterceptor() + + ); + accessor.setInterceptors(interceptors); + + assertThat(accessor.getInterceptors().get(0), Matchers.instanceOf(FirstClientHttpRequestInterceptor.class)); + assertThat(accessor.getInterceptors().get(1), Matchers.instanceOf(SecondClientHttpRequestInterceptor.class)); + assertThat(accessor.getInterceptors().get(2), Matchers.instanceOf(ThirdClientHttpRequestInterceptor.class)); + } + + private class TestInterceptingHttpAccessor extends InterceptingHttpAccessor { + } + + @Order(1) + private class FirstClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, + ClientHttpRequestExecution execution) throws IOException { + return null; + } + } + + private class SecondClientHttpRequestInterceptor implements ClientHttpRequestInterceptor, Ordered { + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, + ClientHttpRequestExecution execution) throws IOException { + return null; + } + + @Override + public int getOrder() { + return 2; + } + } + + private class ThirdClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, + ClientHttpRequestExecution execution) throws IOException { + return null; + } + } + +} \ No newline at end of file