/**
  * 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 = ((SseEventBuilderImpl) builder).build();
   synchronized (this) {
     for (DataWithMediaType entry : dataToSend) {
       super.send(entry.getData(), entry.getMediaType());
     }
   }
 }
  @Override
  public void handleReturnValue(
      Object returnValue,
      MethodParameter returnType,
      ModelAndViewContainer mavContainer,
      NativeWebRequest webRequest)
      throws Exception {

    if (returnValue == null) {
      mavContainer.setRequestHandled(true);
      return;
    }

    HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
    ServerHttpResponse outputMessage = new ServletServerHttpResponse(response);

    if (ResponseEntity.class.isAssignableFrom(returnValue.getClass())) {
      ResponseEntity<?> responseEntity = (ResponseEntity<?>) returnValue;
      outputMessage.setStatusCode(responseEntity.getStatusCode());
      outputMessage.getHeaders().putAll(responseEntity.getHeaders());
      returnValue = responseEntity.getBody();
      if (returnValue == null) {
        mavContainer.setRequestHandled(true);
        return;
      }
    }

    ServletRequest request = webRequest.getNativeRequest(ServletRequest.class);
    ShallowEtagHeaderFilter.disableContentCaching(request);

    Assert.isInstanceOf(ResponseBodyEmitter.class, returnValue);
    ResponseBodyEmitter emitter = (ResponseBodyEmitter) returnValue;
    emitter.extendResponse(outputMessage);

    // Commit the response and wrap to ignore further header changes
    outputMessage.getBody();
    outputMessage = new StreamingServletServerHttpResponse(outputMessage);

    DeferredResult<?> deferredResult = new DeferredResult<Object>(emitter.getTimeout());
    WebAsyncUtils.getAsyncManager(webRequest)
        .startDeferredResultProcessing(deferredResult, mavContainer);

    HttpMessageConvertingHandler handler =
        new HttpMessageConvertingHandler(outputMessage, deferredResult);
    emitter.initialize(handler);
  }
  @Override
  protected void extendResponse(ServerHttpResponse outputMessage) {
    super.extendResponse(outputMessage);

    HttpHeaders headers = outputMessage.getHeaders();
    if (headers.getContentType() == null) {
      headers.setContentType(new MediaType("text", "event-stream"));
    }
  }