Skip to content

Commit 4ee8cd8

Browse files
veloPierre de Soyres
andauthored
Headers overwrite (OpenFeign#1219)
* Add unit test illustrating OpenFeign#1217 * Make sure content-type is limited to a single value Co-authored-by: Pierre de Soyres <pierre.de-soyres@eptica.com>
1 parent c1b853c commit 4ee8cd8

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

core/src/main/java/feign/RequestTemplate.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ public RequestTemplate header(String name, String... values) {
696696

697697
/**
698698
* Add a header using the supplied Chunks.
699-
*
699+
*
700700
* @param name of the header.
701701
* @param chunks to add.
702702
* @return a RequestTemplate for chaining.
@@ -753,6 +753,14 @@ private RequestTemplate appendHeader(String name, Iterable<String> values) {
753753
this.headers.remove(name);
754754
return this;
755755
}
756+
if (name.equals("Content-Type")) {
757+
// a client can only produce content of one single type, so always override Content-Type and
758+
// only add a single type
759+
this.headers.remove(name);
760+
this.headers.put(name,
761+
HeaderTemplate.create(name, Collections.singletonList(values.iterator().next())));
762+
return this;
763+
}
756764
this.headers.compute(name, (headerName, headerTemplate) -> {
757765
if (headerTemplate == null) {
758766
return HeaderTemplate.create(headerName, values);

jaxrs/src/main/java/feign/jaxrs/JAXRSContract.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ public JAXRSContract() {
6666
super.registerClassAnnotation(Produces.class, this::handleProducesAnnotation);
6767

6868
registerMethodAnnotation(methodAnnotation -> {
69-
Class<? extends Annotation> annotationType = methodAnnotation.annotationType();
70-
HttpMethod http = annotationType.getAnnotation(HttpMethod.class);
69+
final Class<? extends Annotation> annotationType = methodAnnotation.annotationType();
70+
final HttpMethod http = annotationType.getAnnotation(HttpMethod.class);
7171
return http != null;
7272
}, (methodAnnotation, data) -> {
73-
Class<? extends Annotation> annotationType = methodAnnotation.annotationType();
74-
HttpMethod http = annotationType.getAnnotation(HttpMethod.class);
73+
final Class<? extends Annotation> annotationType = methodAnnotation.annotationType();
74+
final HttpMethod http = annotationType.getAnnotation(HttpMethod.class);
7575
checkState(data.template().method() == null,
7676
"Method %s contains multiple HTTP methods. Found: %s and %s", data.configKey(),
7777
data.template().method(), http.value());
@@ -103,18 +103,17 @@ public JAXRSContract() {
103103

104104
private void handleProducesAnnotation(Produces produces, MethodMetadata data) {
105105
final String[] serverProduces =
106-
removeValues(produces.value(), (mediaType) -> emptyToNull(mediaType) == null, String.class);
106+
removeValues(produces.value(), mediaType -> emptyToNull(mediaType) == null, String.class);
107107
checkState(serverProduces.length > 0, "Produces.value() was empty on %s", data.configKey());
108108
data.template().header(ACCEPT, Collections.emptyList()); // remove any previous produces
109109
data.template().header(ACCEPT, serverProduces);
110110
}
111111

112112
private void handleConsumesAnnotation(Consumes consumes, MethodMetadata data) {
113113
final String[] serverConsumes =
114-
removeValues(consumes.value(), (mediaType) -> emptyToNull(mediaType) == null, String.class);
114+
removeValues(consumes.value(), mediaType -> emptyToNull(mediaType) == null, String.class);
115115
checkState(serverConsumes.length > 0, "Consumes.value() was empty on %s", data.configKey());
116-
data.template().header(CONTENT_TYPE, Collections.emptyList()); // remove any previous consumes
117-
data.template().header(CONTENT_TYPE, serverConsumes[0]);
116+
data.template().header(CONTENT_TYPE, serverConsumes);
118117
}
119118

120119
protected void registerParamAnnotations() {

jaxrs2/src/test/java/feign/jaxrs2/JAXRSClientTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@
2828
import java.io.ByteArrayInputStream;
2929
import java.io.IOException;
3030
import java.util.Collections;
31+
import javax.ws.rs.Consumes;
32+
import javax.ws.rs.HeaderParam;
33+
import javax.ws.rs.POST;
34+
import javax.ws.rs.Path;
3135
import javax.ws.rs.ProcessingException;
36+
import feign.jaxrs.JAXRSContract;
3237
import okhttp3.mockwebserver.MockResponse;
3338
import org.assertj.core.data.MapEntry;
3439
import org.junit.Assume;
@@ -126,11 +131,36 @@ public void testContentTypeWithoutCharset2() throws Exception {
126131
.hasMethod("GET");
127132
}
128133

134+
@Test
135+
public void testConsumesMultipleWithContentTypeHeaderAndBody() throws Exception {
136+
server.enqueue(new MockResponse().setBody("AAAAAAAA"));
137+
final JaxRSClientTestInterfaceWithJaxRsContract api = newBuilder()
138+
.contract(new JAXRSContract()) // use JAXRSContract
139+
.target(JaxRSClientTestInterfaceWithJaxRsContract.class,
140+
"http://localhost:" + server.getPort());
141+
142+
final Response response =
143+
api.consumesMultipleWithContentTypeHeaderAndBody("application/json;charset=utf-8", "body");
144+
assertEquals("AAAAAAAA", Util.toString(response.body().asReader(UTF_8)));
145+
146+
MockWebServerAssertions.assertThat(server.takeRequest())
147+
.hasHeaders(MapEntry.entry("Content-Type",
148+
Collections.singletonList("application/json;charset=utf-8")))
149+
.hasMethod("POST");
150+
}
129151

130152
public interface JaxRSClientTestInterface {
131153

132154
@RequestLine("GET /")
133155
@Headers({"Accept: text/plain", "Content-Type: text/plain"})
134156
Response getWithContentType();
135157
}
158+
159+
public interface JaxRSClientTestInterfaceWithJaxRsContract {
160+
@Path("/")
161+
@POST
162+
@Consumes({"application/xml", "application/json"})
163+
Response consumesMultipleWithContentTypeHeaderAndBody(@HeaderParam("Content-Type") String contentType,
164+
String body);
165+
}
136166
}

0 commit comments

Comments
 (0)