下面列出了怎么用javax.servlet.WriteListener的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public final void setWriteListener(WriteListener listener) {
if (listener == null) {
throw new IllegalArgumentException(
sm.getString("upgrade.sos.writeListener.null"));
}
if (this.listener != null) {
throw new IllegalArgumentException(
sm.getString("upgrade.sos.writeListener.set"));
}
if (closed) {
throw new IllegalStateException(sm.getString("upgrade.sos.write.closed"));
}
this.listener = listener;
// Container is responsible for first call to onWritePossible().
synchronized (registeredLock) {
registered = true;
// Container is responsible for first call to onDataAvailable().
if (ContainerThreadMarker.isContainerThread()) {
processor.addDispatch(DispatchType.NON_BLOCKING_WRITE);
} else {
socketWrapper.registerWriteInterest();
}
}
}
void emit() throws IOException {
ctx.getResponse().getOutputStream().setWriteListener(new WriteListener() {
private boolean written = false;
@Override
public void onWritePossible() throws IOException {
ServletOutputStream out = ctx.getResponse().getOutputStream();
if (out.isReady() && !written) {
out.println("OK");
written = true;
}
if (out.isReady() && written) {
out.flush();
if (out.isReady()) {
ctx.complete();
}
}
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
});
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.startAsync();
resp.getOutputStream().print("hi");
resp.getOutputStream().setWriteListener(new WriteListener() {
@Override
public void onWritePossible() throws IOException {
}
@Override
public void onError(Throwable t) {
}
});
HttpServerExchange exchange = ServletRequestContext.current().getExchange();
try {
exchange.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new ServletOutputStream() {
private TeeOutputStream tee = new TeeOutputStream(ResponseWrapper.super.getOutputStream(), bos);
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
@Override
public void write(int b) throws IOException {
tee.write(b);
}
};
}
@Override
public void setWriteListener(final WriteListener writeListener) {
if (writeListener == null) {
throw UndertowServletMessages.MESSAGES.paramCannotBeNull("writeListener");
}
if (listener != null) {
throw UndertowServletMessages.MESSAGES.listenerAlreadySet();
}
listener = writeListener;
channel.getWriteSetter().set(new WriteChannelListener());
state |= FLAG_READY;
ioExecutor.execute(new Runnable() {
@Override
public void run() {
channel.resumeWrites();
}
});
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new ServletOutputStream() {
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
private TeeOutputStream tee = new TeeOutputStream(ResponseWrapper.super.getOutputStream(), bos);
@Override
public void write(int b) throws IOException {
tee.write(b);
}
};
}
/**
* Getter for output stream.
*
* @return ServletOutputStream
*/
@Override
public ServletOutputStream getOutputStream() throws IOException {
// This is the magic to prevent closing stream, create a "virtual" stream that
// does nothing..
return new ServletOutputStream() {
@Override
public void write(int b) throws IOException {
output.write(b);
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
@Override
public boolean isReady() {
return true;
}
};
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
final ServletOutputStream outputStream = d.getOutputStream();
return new ServletOutputStream() {
@Override
public void write(int b) throws IOException {
respBody.write(b);
outputStream.write(b);
}
@Override
public void setWriteListener(WriteListener writeListener) {
outputStream.setWriteListener(writeListener);
}
@Override
public boolean isReady() {
return outputStream.isReady();
}
};
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new ServletOutputStream() {
@Override
public void write(int b) throws IOException {
builder.append(new Character((char) b));
}
@Override
public void setWriteListener(WriteListener listener) {
}
@Override
public boolean isReady() {
return true;
}
};
}
@BeforeEach
void setUp() throws IOException {
mock = mock(HttpServletResponse.class);
when(mock.getOutputStream()).thenReturn(new ServletOutputStream() {
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(final WriteListener listener) {
// nothing to do here
}
@Override
public void write(final int b) {
// serves as a null or no-op output stream
}
});
unit = new LocalResponse(mock, "1");
}
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
throws IOException {
final AsyncContext asyncContext = request.startAsync();
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/binary");
final ServletOutputStream output = response.getOutputStream();
output.setWriteListener(new WriteListener() {
int blockCount;
byte[] bytes = new byte[BLOCK_SIZE];
@Override
public void onWritePossible() throws IOException {
while (output.isReady()) {
blockCount++;
output.write(bytes);
if (blockCount % 5 == 0) {
response.flushBuffer();
}
if (blockCount == blockLimit) {
asyncContext.complete();
return;
}
}
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
});
}
void invokeOnWritePossible(HttpServerExchange exchange, WriteListener listener) {
try {
this.onWritePossibleTask.call(exchange, listener);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void setWriteListener(WriteListener writeListener) {
if (writeListener == null) {
throw UndertowServletMessages.MESSAGES.listenerCannotBeNull();
}
if (listener != null) {
throw UndertowServletMessages.MESSAGES.listenerAlreadySet();
}
final ServletRequest servletRequest = servletRequestContext.getOriginalRequest();
if (!servletRequest.isAsyncStarted()) {
throw UndertowServletMessages.MESSAGES.asyncNotStarted();
}
listener = writeListener;
listenerCallback = new ListenerCallback();
servletRequestContext.getOriginalRequest().getAsyncContext().addAsyncTask(new Runnable() {
@Override
public void run() {
//TODO: hack to make sure the invocation happens in the callback loop, to prevent recursive callbacks
exchange.getIoThread().execute(new Runnable() {
@Override
public void run() {
listenerCallback.onComplete(null, null);
}
});
}
});
}
@Override
public void setWriteListener(WriteListener w) {
writeListener = w;
try {
w.onWritePossible();
} catch (IOException e) {
writeListener.onError(e);
}
}
@Override
public void setWriteListener(WriteListener writeListener) {
checkNotNull(writeListener);
if(this.writeListener != null){
return; //只能设置一次
}
this.writeListener = writeListener;
// TODO ISE when called more than once
// TODO ISE when associated request is not async
}
@Test
public void flushBuffer() throws IOException {
Buffer buffer = Buffer.buffer();
ServletOutputStream output = new ServletOutputStream() {
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
@Override
public void write(int b) throws IOException {
buffer.appendByte((byte) b);
}
};
response = new MockUp<HttpServletResponse>() {
@Mock
ServletOutputStream getOutputStream() {
return output;
}
}.getMockInstance();
responseEx = new StandardHttpServletResponseEx(response);
// no body
responseEx.flushBuffer();
Assert.assertEquals(0, buffer.length());
Buffer body = Buffer.buffer().appendString("body");
responseEx.setBodyBuffer(body);
responseEx.flushBuffer();
Assert.assertEquals("body", buffer.toString());
}
void invokeOnWritePossible(HttpServerExchange exchange, WriteListener listener) {
try {
this.onWritePossibleTask.call(exchange, listener);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void setWriteListener(final WriteListener writeListener) {
if (writeListener == null) {
throw UndertowServletMessages.MESSAGES.listenerCannotBeNull();
}
if (listener != null) {
throw UndertowServletMessages.MESSAGES.listenerAlreadySet();
}
final ServletRequest servletRequest = servletRequestContext.getOriginalRequest();
if (!servletRequest.isAsyncStarted()) {
throw UndertowServletMessages.MESSAGES.asyncNotStarted();
}
asyncContext = (AsyncContextImpl) servletRequest.getAsyncContext();
listener = writeListener;
//we register the write listener on the underlying connection
//so we don't have to force the creation of the response channel
//under normal circumstances this will break write listener delegation
this.internalListener = new WriteChannelListener();
if (this.channel != null) {
this.channel.getWriteSetter().set(internalListener);
}
//we resume from an async task, after the request has been dispatched
asyncContext.addAsyncTask(new Runnable() {
@Override
public void run() {
if (channel == null) {
servletRequestContext.getExchange().getIoThread().execute(new Runnable() {
@Override
public void run() {
internalListener.handleEvent(null);
}
});
} else {
channel.resumeWrites();
}
}
});
}
@Before
public void setupWrapper() throws IOException {
requestWrapper = mock(HttpRequestWrapper.class);
response = mock(HttpServletResponse.class);
manager = mock(SessionManager.class);
configuration = new SessionConfiguration();
when(manager.getConfiguration()).thenReturn(configuration);
when(requestWrapper.getManager()).thenReturn(manager );
responseWrapper = new HttpResponseWrapper31(requestWrapper, response);
outputStream = new ByteArrayOutputStream();
outputWriter = new StringWriter();
when(response.getOutputStream()).thenReturn(new ServletOutputStream() {
@Override
public void write(int b) throws IOException {
outputStream.write(b);
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
@Override
public boolean isReady() {
return false;
}
});
when(response.getWriter()).thenReturn(new PrintWriter(outputWriter));
}
private void asyncGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String str = body.concat("<h3>async</h3>");
ByteBuffer content = ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8));
AsyncContext async = request.startAsync();
response.setContentType("text/html");
try {
Thread.sleep(100);
} catch (Exception e) {
logger.info("Error sleeping");
}
ServletOutputStream out = response.getOutputStream();
out.setWriteListener(
new WriteListener() {
@Override
public void onWritePossible() throws IOException {
while (out.isReady()) {
if (!content.hasRemaining()) {
response.setStatus(200);
async.complete();
return;
}
out.write(content.get());
}
}
@Override
public void onError(Throwable t) {
logger.info("Server onError callled");
getServletContext().log("Async Error", t);
async.complete();
}
});
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new ServletOutputStream() {
@Override
public boolean isReady() {
return os.isReady();
}
@Override
public void setWriteListener(WriteListener writeListener) {
os.setWriteListener(writeListener);
}
@Override
public void write(int b) throws IOException {
baos.write(b);
os.write(b);
}
@Override
public void flush() throws IOException {
os.flush();
}
@Override
public void close() throws IOException {
os.close();
}
};
}
/**
* TODO SERVLET 3.1
*/
@Override
public void setWriteListener(WriteListener listener) {
// TODO Auto-generated method stub
}
@Override
public void setWriteListener(WriteListener listener) {
ob.setWriteListener(listener);
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
/**
* TODO SERVLET 3.1
*/
@Override
public void setWriteListener(WriteListener listener) {
// TODO Auto-generated method stub
}
/**
* TODO SERVLET 3.1
*/
@Override
public void setWriteListener(WriteListener listener) {
}
public WriteListener getWriteListener() {
return listener;
}
public void setWriteListener(WriteListener listener) {
if (listener == null) {
throw new NullPointerException(
sm.getString("response.nullWriteListener"));
}
if (getWriteListener() != null) {
throw new IllegalStateException(
sm.getString("response.writeListenerSet"));
}
// Note: This class is not used for HTTP upgrade so only need to test
// for async
AtomicBoolean result = new AtomicBoolean(false);
action(ActionCode.ASYNC_IS_ASYNC, result);
if (!result.get()) {
throw new IllegalStateException(
sm.getString("response.notAsync"));
}
this.listener = listener;
// The container is responsible for the first call to
// listener.onWritePossible(). If isReady() returns true, the container
// needs to call listener.onWritePossible() from a new thread. If
// isReady() returns false, the socket will be registered for write and
// the container will call listener.onWritePossible() once data can be
// written.
if (isReady()) {
synchronized (nonBlockingStateLock) {
// Ensure we don't get multiple write registrations if
// ServletOutputStream.isReady() returns false during a call to
// onDataAvailable()
registeredForWrite = true;
// Need to set the fireListener flag otherwise when the
// container tries to trigger onWritePossible, nothing will
// happen
fireListener = true;
}
action(ActionCode.DISPATCH_WRITE, null);
if (!ContainerThreadMarker.isContainerThread()) {
// Not on a container thread so need to execute the dispatch
action(ActionCode.DISPATCH_EXECUTE, null);
}
}
}
@Override
public void setWriteListener(WriteListener listener) {
// Non-blocking IO not supported
throw new UnsupportedOperationException();
}
@Override
public void setWriteListener(WriteListener writeListener) {
if (servletOutputStream != null) {
servletOutputStream.setWriteListener(writeListener);
}
}