1
1
/*
2
- * Copyright 2002-2019 the original author or authors.
2
+ * Copyright 2002-2021 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
37
37
import org .springframework .core .io .buffer .DataBufferFactory ;
38
38
import org .springframework .http .HttpHeaders ;
39
39
import org .springframework .http .HttpMethod ;
40
+ import org .springframework .lang .Nullable ;
40
41
import org .springframework .util .Assert ;
41
42
42
43
/**
43
- * {@link ClientHttpRequest} implementation for the Java 11 HTTP client .
44
+ * {@link ClientHttpRequest} implementation for Java's {@link HttpClient} .
44
45
*
45
46
* @author Julien Eyraud
46
- * @since 5.2
47
- * @see <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html">Java HttpClient</a>
47
+ * @since 6.0
48
48
*/
49
49
class JdkClientHttpRequest extends AbstractClientHttpRequest {
50
50
51
- private static final Set <String > DISALLOWED_HEADERS = Set .of ("connection" , "content-length" , "date" , "expect" , "from" , "host" , "upgrade" , "via" , "warning" );
51
+ private static final Set <String > DISALLOWED_HEADERS =
52
+ Set .of ("connection" , "content-length" , "date" , "expect" , "from" , "host" , "upgrade" , "via" , "warning" );
53
+
52
54
53
55
private final HttpClient httpClient ;
54
56
@@ -60,41 +62,25 @@ class JdkClientHttpRequest extends AbstractClientHttpRequest {
60
62
61
63
private final DataBufferFactory bufferFactory ;
62
64
65
+ @ Nullable
63
66
private Mono <ClientHttpResponse > response ;
64
67
65
68
66
- public JdkClientHttpRequest (final HttpClient httpClient , final HttpMethod httpMethod , final URI uri , final DataBufferFactory bufferFactory ) {
69
+ public JdkClientHttpRequest (
70
+ HttpClient httpClient , HttpMethod httpMethod , URI uri , DataBufferFactory bufferFactory ) {
71
+
67
72
Assert .notNull (httpClient , "HttpClient should not be null" );
68
73
Assert .notNull (httpMethod , "HttpMethod should not be null" );
69
74
Assert .notNull (uri , "URI should not be null" );
70
75
Assert .notNull (bufferFactory , "DataBufferFactory should not be null" );
76
+
71
77
this .httpClient = httpClient ;
72
78
this .method = httpMethod ;
73
79
this .uri = uri ;
74
80
this .builder = HttpRequest .newBuilder (uri );
75
81
this .bufferFactory = bufferFactory ;
76
82
}
77
83
78
- @ Override
79
- protected void applyHeaders () {
80
- HttpHeaders headers = getHeaders ();
81
- for (Map .Entry <String , List <String >> header : getHeaders ().entrySet ()) {
82
- if (!DISALLOWED_HEADERS .contains (header .getKey ().toLowerCase ())) {
83
- for (String value : header .getValue ()) {
84
- this .builder .header (header .getKey (), value );
85
- }
86
- }
87
- }
88
- if (!headers .containsKey (HttpHeaders .ACCEPT )) {
89
- this .builder .header (HttpHeaders .ACCEPT , "*/*" );
90
- }
91
- }
92
-
93
- @ Override
94
- protected void applyCookies () {
95
- final String cookies = getCookies ().values ().stream ().flatMap (List ::stream ).map (c -> c .getName () + "=" + c .getValue ()).collect (Collectors .joining ("; " ));
96
- this .builder .header (HttpHeaders .COOKIE , cookies );
97
- }
98
84
99
85
@ Override
100
86
public HttpMethod getMethod () {
@@ -117,16 +103,52 @@ public <T> T getNativeRequest() {
117
103
return (T ) this .builder .build ();
118
104
}
119
105
106
+ Mono <ClientHttpResponse > getResponse () {
107
+ Assert .notNull (this .response , "Response is not set" );
108
+ return this .response ;
109
+ }
110
+
111
+
112
+ @ Override
113
+ protected void applyHeaders () {
114
+ for (Map .Entry <String , List <String >> header : getHeaders ().entrySet ()) {
115
+ if (DISALLOWED_HEADERS .contains (header .getKey ().toLowerCase ())) {
116
+ continue ;
117
+ }
118
+ for (String value : header .getValue ()) {
119
+ this .builder .header (header .getKey (), value );
120
+ }
121
+ }
122
+ if (!getHeaders ().containsKey (HttpHeaders .ACCEPT )) {
123
+ this .builder .header (HttpHeaders .ACCEPT , "*/*" );
124
+ }
125
+ }
126
+
127
+ @ Override
128
+ protected void applyCookies () {
129
+ this .builder .header (HttpHeaders .COOKIE ,
130
+ getCookies ().values ().stream ()
131
+ .flatMap (List ::stream )
132
+ .map (cookie -> cookie .getName () + "=" + cookie .getValue ())
133
+ .collect (Collectors .joining ("; " )));
134
+ }
135
+
120
136
@ Override
121
- public Mono <Void > writeWith (final Publisher <? extends DataBuffer > body ) {
137
+ public Mono <Void > writeWith (Publisher <? extends DataBuffer > body ) {
122
138
return doCommit (() -> {
123
- final Flow .Publisher <ByteBuffer > flowAdapter = JdkFlowAdapter .publisherToFlowPublisher (Flux .from (body ).map (DataBuffer ::asByteBuffer ));
124
- final long contentLength = getHeaders ().getContentLength ();
125
- final HttpRequest .BodyPublisher bodyPublisher = contentLength >= 0 ? HttpRequest .BodyPublishers .fromPublisher (flowAdapter , contentLength )
126
- : HttpRequest .BodyPublishers .fromPublisher (flowAdapter );
127
- this .response = Mono
128
- .fromCompletionStage (() -> this .httpClient .sendAsync (this .builder .method (this .method .name (), bodyPublisher ).build (), HttpResponse .BodyHandlers .ofPublisher ()))
129
- .map (r -> new JdkClientHttpResponse (r , this .bufferFactory ));
139
+ Flow .Publisher <ByteBuffer > flow =
140
+ JdkFlowAdapter .publisherToFlowPublisher (Flux .from (body ).map (DataBuffer ::asByteBuffer ));
141
+
142
+ HttpRequest .BodyPublisher bodyPublisher = (getHeaders ().getContentLength () >= 0 ?
143
+ HttpRequest .BodyPublishers .fromPublisher (flow , getHeaders ().getContentLength ()) :
144
+ HttpRequest .BodyPublishers .fromPublisher (flow ));
145
+
146
+ this .response = Mono .fromCompletionStage (() -> {
147
+ HttpRequest request = this .builder .method (this .method .name (), bodyPublisher ).build ();
148
+ return this .httpClient .sendAsync (request , HttpResponse .BodyHandlers .ofPublisher ());
149
+ })
150
+ .map (response -> new JdkClientHttpResponse (response , this .bufferFactory ));
151
+
130
152
return Mono .empty ();
131
153
});
132
154
}
@@ -141,17 +163,17 @@ public Mono<Void> setComplete() {
141
163
if (isCommitted ()) {
142
164
return Mono .empty ();
143
165
}
144
- else {
145
- return doCommit (() -> {
146
- this .response = Mono
147
- .fromCompletionStage (() -> this .httpClient .sendAsync (this .builder .method (this .method .name (), HttpRequest .BodyPublishers .noBody ()).build (), HttpResponse .BodyHandlers .ofPublisher ()))
148
- .map (r -> new JdkClientHttpResponse (r , this .bufferFactory ));
149
- return Mono .empty ();
150
- });
151
- }
152
- }
153
166
154
- public Mono <ClientHttpResponse > getResponse () {
155
- return this .response ;
167
+ return doCommit (() -> {
168
+ this .response = Mono .fromCompletionStage (() -> {
169
+ HttpRequest .BodyPublisher bodyPublisher = HttpRequest .BodyPublishers .noBody ();
170
+ HttpRequest request = this .builder .method (this .method .name (), bodyPublisher ).build ();
171
+ return this .httpClient .sendAsync (request , HttpResponse .BodyHandlers .ofPublisher ());
172
+ })
173
+ .map (response -> new JdkClientHttpResponse (response , this .bufferFactory ));
174
+
175
+ return Mono .empty ();
176
+ });
156
177
}
178
+
157
179
}
0 commit comments