|
|
|
@ -22,13 +22,13 @@ import java.io.UncheckedIOException; |
|
|
|
import java.nio.charset.Charset; |
|
|
|
import java.nio.charset.Charset; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.concurrent.atomic.AtomicBoolean; |
|
|
|
|
|
|
|
import javax.servlet.ServletOutputStream; |
|
|
|
import javax.servlet.ServletOutputStream; |
|
|
|
import javax.servlet.WriteListener; |
|
|
|
import javax.servlet.WriteListener; |
|
|
|
import javax.servlet.http.Cookie; |
|
|
|
import javax.servlet.http.Cookie; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
|
|
|
|
|
|
|
|
import org.reactivestreams.Processor; |
|
|
|
import org.reactivestreams.Processor; |
|
|
|
|
|
|
|
import org.reactivestreams.Publisher; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.io.buffer.DataBuffer; |
|
|
|
import org.springframework.core.io.buffer.DataBuffer; |
|
|
|
import org.springframework.core.io.buffer.DataBufferFactory; |
|
|
|
import org.springframework.core.io.buffer.DataBufferFactory; |
|
|
|
@ -44,7 +44,7 @@ import org.springframework.util.Assert; |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class ServletServerHttpResponse extends AbstractListenerServerHttpResponse { |
|
|
|
public class ServletServerHttpResponse extends AbstractListenerServerHttpResponse { |
|
|
|
|
|
|
|
|
|
|
|
private final AtomicBoolean listenerRegistered = new AtomicBoolean(); |
|
|
|
private final ResponseBodyWriteListener writeListener = new ResponseBodyWriteListener(); |
|
|
|
|
|
|
|
|
|
|
|
private volatile ResponseBodyProcessor bodyProcessor; |
|
|
|
private volatile ResponseBodyProcessor bodyProcessor; |
|
|
|
|
|
|
|
|
|
|
|
@ -112,15 +112,17 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void registerListener() throws IOException { |
|
|
|
private void registerListener() { |
|
|
|
if (this.listenerRegistered.compareAndSet(false, true)) { |
|
|
|
try { |
|
|
|
ResponseBodyWriteListener writeListener = new ResponseBodyWriteListener(); |
|
|
|
outputStream().setWriteListener(writeListener); |
|
|
|
this.response.getOutputStream().setWriteListener(writeListener); |
|
|
|
} |
|
|
|
|
|
|
|
catch (IOException e) { |
|
|
|
|
|
|
|
throw new UncheckedIOException(e); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void flush() throws IOException { |
|
|
|
private void flush() throws IOException { |
|
|
|
ServletOutputStream outputStream = this.response.getOutputStream(); |
|
|
|
ServletOutputStream outputStream = outputStream(); |
|
|
|
if (outputStream.isReady()) { |
|
|
|
if (outputStream.isReady()) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
outputStream.flush(); |
|
|
|
outputStream.flush(); |
|
|
|
@ -136,22 +138,15 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
private ServletOutputStream outputStream() throws IOException { |
|
|
|
protected ResponseBodyProcessor createBodyProcessor() { |
|
|
|
return this.response.getOutputStream(); |
|
|
|
try { |
|
|
|
|
|
|
|
registerListener(); |
|
|
|
|
|
|
|
this.bodyProcessor = new ResponseBodyProcessor(this.response.getOutputStream(), |
|
|
|
|
|
|
|
this.bufferSize); |
|
|
|
|
|
|
|
return this.bodyProcessor; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (IOException ex) { |
|
|
|
|
|
|
|
throw new UncheckedIOException(ex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected AbstractResponseBodyFlushProcessor createBodyFlushProcessor() { |
|
|
|
protected Processor<Publisher<DataBuffer>, Void> createBodyFlushProcessor() { |
|
|
|
return new ResponseBodyFlushProcessor(); |
|
|
|
Processor<Publisher<DataBuffer>, Void> processor = new ResponseBodyFlushProcessor(); |
|
|
|
|
|
|
|
registerListener(); |
|
|
|
|
|
|
|
return processor; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private class ResponseBodyProcessor extends AbstractResponseBodyProcessor { |
|
|
|
private class ResponseBodyProcessor extends AbstractResponseBodyProcessor { |
|
|
|
@ -238,7 +233,13 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected Processor<DataBuffer, Void> createBodyProcessor() { |
|
|
|
protected Processor<DataBuffer, Void> createBodyProcessor() { |
|
|
|
return ServletServerHttpResponse.this.createBodyProcessor(); |
|
|
|
try { |
|
|
|
|
|
|
|
bodyProcessor = new ResponseBodyProcessor(outputStream(), bufferSize); |
|
|
|
|
|
|
|
return bodyProcessor; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (IOException ex) { |
|
|
|
|
|
|
|
throw new UncheckedIOException(ex); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
|