/** * Write the given object to the response. * <p>If any exception occurs a dispatch is made back to the app server where * Spring MVC will pass the exception through its exception handling mechanism. * <p><strong>Note:</strong> if the send fails with an IOException, you do * not need to call {@link #completeWithError(Throwable)} in order to clean * up. Instead the Servlet container creates a notification that results in a * dispatch where Spring MVC invokes exception resolvers and completes * processing. * @param object the object to write * @throws IOException raised when an I/O error occurs * @throws java.lang.IllegalStateException wraps any other errors */ public void send(Object object) throws IOException { send(object, null); }
/** * Write the given object to the response. * <p>If any exception occurs a dispatch is made back to the app server where * Spring MVC will pass the exception through its exception handling mechanism. * <p><strong>Note:</strong> if the send fails with an IOException, you do * not need to call {@link #completeWithError(Throwable)} in order to clean * up. Instead the Servlet container creates a notification that results in a * dispatch where Spring MVC invokes exception resolvers and completes * processing. * @param object the object to write * @throws IOException raised when an I/O error occurs * @throws java.lang.IllegalStateException wraps any other errors */ public void send(Object object) throws IOException { send(object, null); }
@Override protected void send(Object element) throws IOException { getEmitter().send(element, MediaType.TEXT_PLAIN); } }
@Override protected void send(Object element) throws IOException { getEmitter().send(element, MediaType.TEXT_PLAIN); } }
/** * Send an SSE event prepared with the given builder. For example: * <pre> * // static import of SseEmitter * SseEmitter emitter = new SseEmitter(); * emitter.send(event().name("update").id("1").data(myObject)); * </pre> * @param builder a builder for an SSE formatted event. * @throws IOException raised when an I/O error occurs */ public void send(SseEventBuilder builder) throws IOException { Set<DataWithMediaType> dataToSend = builder.build(); synchronized (this) { for (DataWithMediaType entry : dataToSend) { super.send(entry.getData(), entry.getMediaType()); } } }
@Override protected void send(Object element) throws IOException { if (element instanceof ServerSentEvent) { ServerSentEvent<?> event = (ServerSentEvent<?>) element; ((SseEmitter) getEmitter()).send(adapt(event)); } else { getEmitter().send(element, MediaType.APPLICATION_JSON); } }
@Test public void sendDuplicateBeforeHandlerInitialized() throws Exception { this.emitter.send("foo", MediaType.TEXT_PLAIN); this.emitter.send("foo", MediaType.TEXT_PLAIN); this.emitter.complete(); verifyNoMoreInteractions(this.handler); this.emitter.initialize(this.handler); verify(this.handler, times(2)).send("foo", MediaType.TEXT_PLAIN); verify(this.handler).complete(); verifyNoMoreInteractions(this.handler); }
@Test public void sendBeforeHandlerInitialized() throws Exception { this.emitter.send("foo", MediaType.TEXT_PLAIN); this.emitter.send("bar", MediaType.TEXT_PLAIN); this.emitter.complete(); verifyNoMoreInteractions(this.handler); this.emitter.initialize(this.handler); verify(this.handler).send("foo", MediaType.TEXT_PLAIN); verify(this.handler).send("bar", MediaType.TEXT_PLAIN); verify(this.handler).complete(); verifyNoMoreInteractions(this.handler); }
@Test public void sendBeforeHandlerInitializedWithError() throws Exception { IllegalStateException ex = new IllegalStateException(); this.emitter.send("foo", MediaType.TEXT_PLAIN); this.emitter.send("bar", MediaType.TEXT_PLAIN); this.emitter.completeWithError(ex); verifyNoMoreInteractions(this.handler); this.emitter.initialize(this.handler); verify(this.handler).send("foo", MediaType.TEXT_PLAIN); verify(this.handler).send("bar", MediaType.TEXT_PLAIN); verify(this.handler).completeWithError(ex); verifyNoMoreInteractions(this.handler); }
@Test(expected = IllegalStateException.class) public void sendFailsAfterComplete() throws Exception { this.emitter.complete(); this.emitter.send("foo"); }
@Test public void sendAfterHandlerInitializedWithError() throws Exception { this.emitter.initialize(this.handler); verify(this.handler).onTimeout(any()); verify(this.handler).onError(any()); verify(this.handler).onCompletion(any()); verifyNoMoreInteractions(this.handler); IllegalStateException ex = new IllegalStateException(); this.emitter.send("foo", MediaType.TEXT_PLAIN); this.emitter.send("bar", MediaType.TEXT_PLAIN); this.emitter.completeWithError(ex); verify(this.handler).send("foo", MediaType.TEXT_PLAIN); verify(this.handler).send("bar", MediaType.TEXT_PLAIN); verify(this.handler).completeWithError(ex); verifyNoMoreInteractions(this.handler); }
@Test public void sendAfterHandlerInitialized() throws Exception { this.emitter.initialize(this.handler); verify(this.handler).onTimeout(any()); verify(this.handler).onError(any()); verify(this.handler).onCompletion(any()); verifyNoMoreInteractions(this.handler); this.emitter.send("foo", MediaType.TEXT_PLAIN); this.emitter.send("bar", MediaType.TEXT_PLAIN); this.emitter.complete(); verify(this.handler).send("foo", MediaType.TEXT_PLAIN); verify(this.handler).send("bar", MediaType.TEXT_PLAIN); verify(this.handler).complete(); verifyNoMoreInteractions(this.handler); }
@Test public void sendWithError() throws Exception { this.emitter.initialize(this.handler); verify(this.handler).onTimeout(any()); verify(this.handler).onError(any()); verify(this.handler).onCompletion(any()); verifyNoMoreInteractions(this.handler); IOException failure = new IOException(); doThrow(failure).when(this.handler).send("foo", MediaType.TEXT_PLAIN); try { this.emitter.send("foo", MediaType.TEXT_PLAIN); fail("Expected exception"); } catch (IOException ex) { // expected } verify(this.handler).send("foo", MediaType.TEXT_PLAIN); verifyNoMoreInteractions(this.handler); }
/** * Send an SSE event prepared with the given builder. For example: * <pre> * // static import of SseEmitter * SseEmitter emitter = new SseEmitter(); * emitter.send(event().name("update").id("1").data(myObject)); * </pre> * @param builder a builder for an SSE formatted event. * @throws IOException raised when an I/O error occurs */ public void send(SseEventBuilder builder) throws IOException { Set<DataWithMediaType> dataToSend = builder.build(); synchronized (this) { for (DataWithMediaType entry : dataToSend) { super.send(entry.getData(), entry.getMediaType()); } } }
@Override protected void send(Object element) throws IOException { if (element instanceof ServerSentEvent) { ServerSentEvent<?> event = (ServerSentEvent<?>) element; ((SseEmitter) getEmitter()).send(adapt(event)); } else { getEmitter().send(element, MediaType.APPLICATION_JSON); } }
@Test public void responseBodyEmitter() throws Exception { MethodParameter type = on(TestController.class).resolveReturnType(ResponseBodyEmitter.class); ResponseBodyEmitter emitter = new ResponseBodyEmitter(); this.handler.handleReturnValue(emitter, type, this.mavContainer, this.webRequest); assertTrue(this.request.isAsyncStarted()); assertEquals("", this.response.getContentAsString()); SimpleBean bean = new SimpleBean(); bean.setId(1L); bean.setName("Joe"); emitter.send(bean); emitter.send("\n"); bean.setId(2L); bean.setName("John"); emitter.send(bean); emitter.send("\n"); bean.setId(3L); bean.setName("Jason"); emitter.send(bean); assertEquals("{\"id\":1,\"name\":\"Joe\"}\n" + "{\"id\":2,\"name\":\"John\"}\n" + "{\"id\":3,\"name\":\"Jason\"}", this.response.getContentAsString()); MockAsyncContext asyncContext = (MockAsyncContext) this.request.getAsyncContext(); assertNull(asyncContext.getDispatchedPath()); emitter.complete(); assertNotNull(asyncContext.getDispatchedPath()); }
@Override public void onNext(T value) { try { if(!completed) { responseBodyEmitter.send(value, mediaType); } } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } }
@Override protected void send(Object element) throws IOException { if (element instanceof ServerSentEvent) { ServerSentEvent<?> event = (ServerSentEvent<?>) element; ((SseEmitter) getEmitter()).send(adapt(event)); } else { getEmitter().send(element, MediaType.APPLICATION_JSON); } }