@@ -241,11 +241,11 @@ public void setAsyncWebRequest(StandardServletAsyncWebRequest asyncWebRequest) {
241241 }
242242
243243 @ Override
244- public ServletOutputStream getOutputStream () {
244+ public ServletOutputStream getOutputStream () throws IOException {
245245 if (this .outputStream == null ) {
246246 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 );
249249 }
250250 return this .outputStream ;
251251 }
@@ -258,6 +258,46 @@ public PrintWriter getWriter() throws IOException {
258258 }
259259 return this .writer ;
260260 }
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+ }
261301 }
262302
263303
@@ -267,113 +307,80 @@ public PrintWriter getWriter() throws IOException {
267307 */
268308 private static final class LifecycleServletOutputStream extends ServletOutputStream {
269309
270- private final HttpServletResponse delegate ;
271-
272- private final StandardServletAsyncWebRequest asyncWebRequest ;
310+ private final ServletOutputStream delegate ;
273311
274- private LifecycleServletOutputStream (
275- HttpServletResponse delegate , StandardServletAsyncWebRequest asyncWebRequest ) {
312+ private final LifecycleHttpServletResponse response ;
276313
314+ private LifecycleServletOutputStream (ServletOutputStream delegate , LifecycleHttpServletResponse response ) {
277315 this .delegate = delegate ;
278- this .asyncWebRequest = asyncWebRequest ;
316+ this .response = response ;
279317 }
280318
281319 @ Override
282320 public boolean isReady () {
283- return false ;
321+ return this . delegate . isReady () ;
284322 }
285323
286324 @ Override
287325 public void setWriteListener (WriteListener writeListener ) {
288- throw new UnsupportedOperationException ( );
326+ this . delegate . setWriteListener ( writeListener );
289327 }
290328
291329 @ Override
292330 public void write (int b ) throws IOException {
293- obtainLockAndCheckState ();
331+ this . response . obtainLockAndCheckState ();
294332 try {
295- this .delegate .getOutputStream (). write (b );
333+ this .delegate .write (b );
296334 }
297335 catch (IOException ex ) {
298- handleIOException (ex , "ServletOutputStream failed to write" );
336+ this . response . handleIOException (ex , "ServletOutputStream failed to write" );
299337 }
300338 finally {
301- releaseLock ();
339+ this . response . releaseLock ();
302340 }
303341 }
304342
305343 public void write (byte [] buf , int offset , int len ) throws IOException {
306- obtainLockAndCheckState ();
344+ this . response . obtainLockAndCheckState ();
307345 try {
308- this .delegate .getOutputStream (). write (buf , offset , len );
346+ this .delegate .write (buf , offset , len );
309347 }
310348 catch (IOException ex ) {
311- handleIOException (ex , "ServletOutputStream failed to write" );
349+ this . response . handleIOException (ex , "ServletOutputStream failed to write" );
312350 }
313351 finally {
314- releaseLock ();
352+ this . response . releaseLock ();
315353 }
316354 }
317355
318356 @ Override
319357 public void flush () throws IOException {
320- obtainLockAndCheckState ();
358+ this . response . obtainLockAndCheckState ();
321359 try {
322- this .delegate .getOutputStream (). flush ();
360+ this .delegate .flush ();
323361 }
324362 catch (IOException ex ) {
325- handleIOException (ex , "ServletOutputStream failed to flush" );
363+ this . response . handleIOException (ex , "ServletOutputStream failed to flush" );
326364 }
327365 finally {
328- releaseLock ();
366+ this . response . releaseLock ();
329367 }
330368 }
331369
332370 @ Override
333371 public void close () throws IOException {
334- obtainLockAndCheckState ();
372+ this . response . obtainLockAndCheckState ();
335373 try {
336- this .delegate .getOutputStream (). close ();
374+ this .delegate .close ();
337375 }
338376 catch (IOException ex ) {
339- handleIOException (ex , "ServletOutputStream failed to close" );
377+ this . response . handleIOException (ex , "ServletOutputStream failed to close" );
340378 }
341379 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 ();
355381 }
356382 }
357383
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-
377384 }
378385
379386
0 commit comments