@@ -241,11 +241,11 @@ public void setAsyncWebRequest(StandardServletAsyncWebRequest asyncWebRequest) {
241
241
}
242
242
243
243
@ Override
244
- public ServletOutputStream getOutputStream () {
244
+ public ServletOutputStream getOutputStream () throws IOException {
245
245
if (this .outputStream == null ) {
246
246
Assert .notNull (this .asyncWebRequest , "Not initialized" );
247
- this . outputStream = new LifecycleServletOutputStream (
248
- ( HttpServletResponse ) getResponse () , this . asyncWebRequest );
247
+ ServletOutputStream delegate = getResponse (). getOutputStream ();
248
+ this . outputStream = new LifecycleServletOutputStream ( delegate , this );
249
249
}
250
250
return this .outputStream ;
251
251
}
@@ -258,6 +258,46 @@ public PrintWriter getWriter() throws IOException {
258
258
}
259
259
return this .writer ;
260
260
}
261
+
262
+ @ Override
263
+ public void flushBuffer () throws IOException {
264
+ obtainLockAndCheckState ();
265
+ try {
266
+ getResponse ().flushBuffer ();
267
+ }
268
+ catch (IOException ex ) {
269
+ handleIOException (ex , "ServletResponse failed to flushBuffer" );
270
+ }
271
+ finally {
272
+ releaseLock ();
273
+ }
274
+ }
275
+
276
+ private void obtainLockAndCheckState () throws AsyncRequestNotUsableException {
277
+ Assert .notNull (this .asyncWebRequest , "Not initialized" );
278
+ if (this .asyncWebRequest .state != State .NEW ) {
279
+ this .asyncWebRequest .stateLock .lock ();
280
+ if (this .asyncWebRequest .state != State .ASYNC ) {
281
+ this .asyncWebRequest .stateLock .unlock ();
282
+ throw new AsyncRequestNotUsableException ("Response not usable after " +
283
+ (this .asyncWebRequest .state == State .COMPLETED ?
284
+ "async request completion" : "onError notification" ) + "." );
285
+ }
286
+ }
287
+ }
288
+
289
+ void handleIOException (IOException ex , String msg ) throws AsyncRequestNotUsableException {
290
+ Assert .notNull (this .asyncWebRequest , "Not initialized" );
291
+ this .asyncWebRequest .transitionToErrorState ();
292
+ throw new AsyncRequestNotUsableException (msg , ex );
293
+ }
294
+
295
+ void releaseLock () {
296
+ Assert .notNull (this .asyncWebRequest , "Not initialized" );
297
+ if (this .asyncWebRequest .state != State .NEW ) {
298
+ this .asyncWebRequest .stateLock .unlock ();
299
+ }
300
+ }
261
301
}
262
302
263
303
@@ -267,113 +307,80 @@ public PrintWriter getWriter() throws IOException {
267
307
*/
268
308
private static final class LifecycleServletOutputStream extends ServletOutputStream {
269
309
270
- private final HttpServletResponse delegate ;
271
-
272
- private final StandardServletAsyncWebRequest asyncWebRequest ;
310
+ private final ServletOutputStream delegate ;
273
311
274
- private LifecycleServletOutputStream (
275
- HttpServletResponse delegate , StandardServletAsyncWebRequest asyncWebRequest ) {
312
+ private final LifecycleHttpServletResponse response ;
276
313
314
+ private LifecycleServletOutputStream (ServletOutputStream delegate , LifecycleHttpServletResponse response ) {
277
315
this .delegate = delegate ;
278
- this .asyncWebRequest = asyncWebRequest ;
316
+ this .response = response ;
279
317
}
280
318
281
319
@ Override
282
320
public boolean isReady () {
283
- return false ;
321
+ return this . delegate . isReady () ;
284
322
}
285
323
286
324
@ Override
287
325
public void setWriteListener (WriteListener writeListener ) {
288
- throw new UnsupportedOperationException ( );
326
+ this . delegate . setWriteListener ( writeListener );
289
327
}
290
328
291
329
@ Override
292
330
public void write (int b ) throws IOException {
293
- obtainLockAndCheckState ();
331
+ this . response . obtainLockAndCheckState ();
294
332
try {
295
- this .delegate .getOutputStream (). write (b );
333
+ this .delegate .write (b );
296
334
}
297
335
catch (IOException ex ) {
298
- handleIOException (ex , "ServletOutputStream failed to write" );
336
+ this . response . handleIOException (ex , "ServletOutputStream failed to write" );
299
337
}
300
338
finally {
301
- releaseLock ();
339
+ this . response . releaseLock ();
302
340
}
303
341
}
304
342
305
343
public void write (byte [] buf , int offset , int len ) throws IOException {
306
- obtainLockAndCheckState ();
344
+ this . response . obtainLockAndCheckState ();
307
345
try {
308
- this .delegate .getOutputStream (). write (buf , offset , len );
346
+ this .delegate .write (buf , offset , len );
309
347
}
310
348
catch (IOException ex ) {
311
- handleIOException (ex , "ServletOutputStream failed to write" );
349
+ this . response . handleIOException (ex , "ServletOutputStream failed to write" );
312
350
}
313
351
finally {
314
- releaseLock ();
352
+ this . response . releaseLock ();
315
353
}
316
354
}
317
355
318
356
@ Override
319
357
public void flush () throws IOException {
320
- obtainLockAndCheckState ();
358
+ this . response . obtainLockAndCheckState ();
321
359
try {
322
- this .delegate .getOutputStream (). flush ();
360
+ this .delegate .flush ();
323
361
}
324
362
catch (IOException ex ) {
325
- handleIOException (ex , "ServletOutputStream failed to flush" );
363
+ this . response . handleIOException (ex , "ServletOutputStream failed to flush" );
326
364
}
327
365
finally {
328
- releaseLock ();
366
+ this . response . releaseLock ();
329
367
}
330
368
}
331
369
332
370
@ Override
333
371
public void close () throws IOException {
334
- obtainLockAndCheckState ();
372
+ this . response . obtainLockAndCheckState ();
335
373
try {
336
- this .delegate .getOutputStream (). close ();
374
+ this .delegate .close ();
337
375
}
338
376
catch (IOException ex ) {
339
- handleIOException (ex , "ServletOutputStream failed to close" );
377
+ this . response . handleIOException (ex , "ServletOutputStream failed to close" );
340
378
}
341
379
finally {
342
- releaseLock ();
343
- }
344
- }
345
-
346
- private void obtainLockAndCheckState () throws AsyncRequestNotUsableException {
347
- if (state () != State .NEW ) {
348
- stateLock ().lock ();
349
- if (state () != State .ASYNC ) {
350
- stateLock ().unlock ();
351
- throw new AsyncRequestNotUsableException ("Response not usable after " +
352
- (state () == State .COMPLETED ?
353
- "async request completion" : "onError notification" ) + "." );
354
- }
380
+ this .response .releaseLock ();
355
381
}
356
382
}
357
383
358
- private void handleIOException (IOException ex , String msg ) throws AsyncRequestNotUsableException {
359
- this .asyncWebRequest .transitionToErrorState ();
360
- throw new AsyncRequestNotUsableException (msg , ex );
361
- }
362
-
363
- private void releaseLock () {
364
- if (state () != State .NEW ) {
365
- stateLock ().unlock ();
366
- }
367
- }
368
-
369
- private State state () {
370
- return this .asyncWebRequest .state ;
371
- }
372
-
373
- private Lock stateLock () {
374
- return this .asyncWebRequest .stateLock ;
375
- }
376
-
377
384
}
378
385
379
386
0 commit comments