@@ -91,8 +91,19 @@ public static class Config {
91
91
92
92
private String newContentType ;
93
93
94
+ /**
95
+ * Deprecated in favour of {@link FluxRewriteFunction} &
96
+ * {@link MonoRewriteFunction} Use {@link MonoRewriteFunction} for modifying
97
+ * non-streaming response body Use {@link FluxRewriteFunction} for modifying
98
+ * streaming response body
99
+ */
100
+ @ Deprecated
94
101
private RewriteFunction rewriteFunction ;
95
102
103
+ private FluxRewriteFunction fluxRewriteFunction ;
104
+
105
+ private MonoRewriteFunction monoRewriteFunction ;
106
+
96
107
public Class getInClass () {
97
108
return inClass ;
98
109
}
@@ -138,15 +149,42 @@ public Config setNewContentType(String newContentType) {
138
149
return this ;
139
150
}
140
151
152
+ @ Deprecated
141
153
public RewriteFunction getRewriteFunction () {
142
154
return rewriteFunction ;
143
155
}
144
156
157
+ public <T , R > MonoRewriteFunction <Mono <T >, Mono <R >> getMonoRewriteFunction () {
158
+ return monoRewriteFunction ;
159
+ }
160
+
161
+ public <T , R > FluxRewriteFunction <Flux <T >, Flux <R >> getFluxRewriteFunction () {
162
+ return fluxRewriteFunction ;
163
+ }
164
+
165
+ /**
166
+ * Deprecated in favour of {@link Config#setMonoRewriteFunction} &
167
+ * {@link Config#setFluxRewriteFunction} Use {@link Config#setMonoRewriteFunction}
168
+ * for modifying non-streaming response body Use
169
+ * {@link Config#setFluxRewriteFunction} for modifying streaming response body
170
+ */
171
+ @ Deprecated
145
172
public Config setRewriteFunction (RewriteFunction rewriteFunction ) {
146
173
this .rewriteFunction = rewriteFunction ;
147
174
return this ;
148
175
}
149
176
177
+ public Config setMonoRewriteFunction (MonoRewriteFunction monoRewriteFunction ) {
178
+ this .monoRewriteFunction = monoRewriteFunction ;
179
+ return this ;
180
+ }
181
+
182
+ public Config setFluxRewriteFunction (FluxRewriteFunction fluxRewriteFunction ) {
183
+ this .fluxRewriteFunction = fluxRewriteFunction ;
184
+ return this ;
185
+ }
186
+
187
+ @ Deprecated
150
188
public <T , R > Config setRewriteFunction (Class <T > inClass , Class <R > outClass ,
151
189
RewriteFunction <T , R > rewriteFunction ) {
152
190
setInClass (inClass );
@@ -155,6 +193,21 @@ public <T, R> Config setRewriteFunction(Class<T> inClass, Class<R> outClass,
155
193
return this ;
156
194
}
157
195
196
+ public <T , R > Config setFluxRewriteFunction (Class <T > inClass , Class <R > outClass ,
197
+ FluxRewriteFunction <T , R > fluxRewriteFunction ) {
198
+ setInClass (inClass );
199
+ setOutClass (outClass );
200
+ setFluxRewriteFunction (fluxRewriteFunction );
201
+ return this ;
202
+ }
203
+
204
+ public <T , R > Config setMonoRewriteFunction (Class <T > inClass , Class <R > outClass ,
205
+ MonoRewriteFunction <T , R > monoRewriteFunction ) {
206
+ setInClass (inClass );
207
+ setOutClass (outClass );
208
+ setMonoRewriteFunction (monoRewriteFunction );
209
+ return this ;
210
+ }
158
211
}
159
212
160
213
public class ModifyResponseGatewayFilter implements GatewayFilter , Ordered {
@@ -204,51 +257,101 @@ public ModifiedServerHttpResponse(ServerWebExchange exchange, Config config) {
204
257
this .config = config ;
205
258
}
206
259
207
- @ SuppressWarnings ("unchecked" )
208
260
@ Override
261
+ @ SuppressWarnings ({ "unchecked" , "rawtypes" })
209
262
public Mono <Void > writeWith (Publisher <? extends DataBuffer > body ) {
210
263
211
264
Class inClass = config .getInClass ();
212
265
Class outClass = config .getOutClass ();
213
266
214
- String originalResponseContentType = exchange .getAttribute (ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR );
215
- HttpHeaders httpHeaders = new HttpHeaders ();
216
- // explicitly add it in this way instead of
217
- // 'httpHeaders.setContentType(originalResponseContentType)'
218
- // this will prevent exception in case of using non-standard media
219
- // types like "Content-Type: image"
220
- httpHeaders .add (HttpHeaders .CONTENT_TYPE , originalResponseContentType );
221
-
267
+ HttpHeaders httpHeaders = prepareHttpHeaders ();
222
268
ClientResponse clientResponse = prepareClientResponse (body , httpHeaders );
223
269
224
- // TODO: flux or mono
225
- Mono modifiedBody = extractBody (exchange , clientResponse , inClass )
226
- .flatMap (originalBody -> config .getRewriteFunction ().apply (exchange , originalBody ))
227
- .switchIfEmpty (Mono .defer (() -> (Mono ) config .getRewriteFunction ().apply (exchange , null )));
270
+ var modifiedBody = extractBody (exchange , clientResponse , inClass );
271
+ if (config .getRewriteFunction () != null ) {
272
+ // TODO: to be removed with removal of rewriteFunction
273
+ modifiedBody = modifiedBody
274
+ .flatMap (originalBody -> config .getRewriteFunction ()
275
+ .apply (exchange , originalBody ))
276
+ .switchIfEmpty (Mono .defer (() -> (Mono ) config .getRewriteFunction ()
277
+ .apply (exchange , null )));
278
+ }
279
+ if (config .getMonoRewriteFunction () != null ) {
280
+ modifiedBody = config .getMonoRewriteFunction ().apply (exchange ,
281
+ modifiedBody );
282
+ }
228
283
229
- BodyInserter bodyInserter = BodyInserters .fromPublisher (modifiedBody , outClass );
284
+ BodyInserter bodyInserter = BodyInserters .fromPublisher (modifiedBody ,
285
+ outClass );
230
286
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage (exchange ,
231
287
exchange .getResponse ().getHeaders ());
232
- return bodyInserter .insert (outputMessage , new BodyInserterContext ()).then (Mono .defer (() -> {
233
- Mono <DataBuffer > messageBody = writeBody (getDelegate (), outputMessage , outClass );
234
- HttpHeaders headers = getDelegate ().getHeaders ();
235
- if (!headers .containsKey (HttpHeaders .TRANSFER_ENCODING )
236
- || headers .containsKey (HttpHeaders .CONTENT_LENGTH )) {
237
- messageBody = messageBody .doOnNext (data -> headers .setContentLength (data .readableByteCount ()));
238
- }
288
+ return bodyInserter .insert (outputMessage , new BodyInserterContext ())
289
+ .then (Mono .defer (() -> {
290
+ Mono <DataBuffer > messageBody = writeBody (getDelegate (),
291
+ outputMessage , outClass );
292
+ HttpHeaders headers = getDelegate ().getHeaders ();
293
+ if (!headers .containsKey (HttpHeaders .TRANSFER_ENCODING )
294
+ || headers .containsKey (HttpHeaders .CONTENT_LENGTH )) {
295
+ messageBody = messageBody .doOnNext (data -> headers
296
+ .setContentLength (data .readableByteCount ()));
297
+ }
298
+
299
+ if (StringUtils .hasText (config .newContentType )) {
300
+ headers .set (HttpHeaders .CONTENT_TYPE , config .newContentType );
301
+ }
302
+
303
+ // TODO: fail if isStreamingMediaType?
304
+ return getDelegate ().writeWith (messageBody );
305
+ }));
306
+ }
239
307
240
- if (StringUtils .hasText (config .newContentType )) {
241
- headers .set (HttpHeaders .CONTENT_TYPE , config .newContentType );
242
- }
308
+ @ Override
309
+ @ SuppressWarnings ({ "unchecked" , "rawtypes" })
310
+ public Mono <Void > writeAndFlushWith (
311
+ Publisher <? extends Publisher <? extends DataBuffer >> body ) {
312
+ final var httpHeaders = prepareHttpHeaders ();
313
+ final var fluxRewriteConfig = config .getFluxRewriteFunction ();
314
+ final var publisher = Flux .from (body ).flatMapSequential (r -> r );
315
+ final var clientResponse = prepareClientResponse (publisher , httpHeaders );
316
+ var modifiedBody = clientResponse .bodyToFlux (config .inClass );
317
+ if (config .getRewriteFunction () != null ) {
318
+ // TODO: to be removed with removal of rewriteFunction
319
+ modifiedBody = modifiedBody
320
+ .flatMap (originalBody -> config .getRewriteFunction ()
321
+ .apply (exchange , originalBody ))
322
+ .switchIfEmpty (Flux .defer (() -> (Flux ) config .getRewriteFunction ()
323
+ .apply (exchange , null )));
324
+ }
325
+ if (config .getFluxRewriteFunction () != null ) {
326
+ modifiedBody = fluxRewriteConfig .apply (exchange , modifiedBody );
327
+ }
328
+ final var bodyInserter = BodyInserters .fromPublisher (modifiedBody ,
329
+ config .outClass );
330
+ final var outputMessage = new CachedBodyOutputMessage (exchange ,
331
+ exchange .getResponse ().getHeaders ());
243
332
244
- // TODO: fail if isStreamingMediaType?
245
- return getDelegate ().writeWith (messageBody );
246
- }));
333
+ return bodyInserter .insert (outputMessage , new BodyInserterContext ())
334
+ .then (Mono .defer (() -> {
335
+ final var messageBody = outputMessage .getBody ();
336
+ HttpHeaders headers = getDelegate ().getHeaders ();
337
+ if (StringUtils .hasText (config .newContentType )) {
338
+ headers .set (HttpHeaders .CONTENT_TYPE , config .newContentType );
339
+ }
340
+ return getDelegate ()
341
+ .writeAndFlushWith (messageBody .map (Flux ::just ));
342
+ }));
247
343
}
248
344
249
- @ Override
250
- public Mono <Void > writeAndFlushWith (Publisher <? extends Publisher <? extends DataBuffer >> body ) {
251
- return writeWith (Flux .from (body ).flatMapSequential (p -> p ));
345
+ private HttpHeaders prepareHttpHeaders () {
346
+ String originalResponseContentType = exchange
347
+ .getAttribute (ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR );
348
+ HttpHeaders httpHeaders = new HttpHeaders ();
349
+ // explicitly add it in this way instead of
350
+ // 'httpHeaders.setContentType(originalResponseContentType)'
351
+ // this will prevent exception in case of using non-standard media
352
+ // types like "Content-Type: image"
353
+ httpHeaders .add (HttpHeaders .CONTENT_TYPE , originalResponseContentType );
354
+ return httpHeaders ;
252
355
}
253
356
254
357
private ClientResponse prepareClientResponse (Publisher <? extends DataBuffer > body , HttpHeaders httpHeaders ) {
0 commit comments