@@ -547,6 +547,87 @@ interface BodyBuilder extends HeadersBuilder<BodyBuilder> {
547
547
* @return the built response
548
548
*/
549
549
ServerResponse render (String name , Map <String , ?> model );
550
+
551
+ /**
552
+ * Create a low-level streaming response; for SSE support, see {@link #sse(Consumer)}.
553
+ * <p>The {@link StreamBuilder} provided to the {@code streamConsumer} can
554
+ * be used to write to the response in a streaming fashion. Note, the builder is
555
+ * responsible for flushing the buffered content to the network.
556
+ * <p>For example:
557
+ * <pre class="code">
558
+ * public ServerResponse handleStream(ServerRequest request) {
559
+ * return ServerResponse.ok()
560
+ * .contentType(MediaType.APPLICATION_ND_JSON)
561
+ * .stream(stream -> {
562
+ * try {
563
+ * // Write and flush a first item
564
+ * stream.write(new Person("John", 51), MediaType.APPLICATION_JSON)
565
+ * .write(new byte[]{'\n'})
566
+ * .flush();
567
+ * // Write and complete with the last item
568
+ * stream.write(new Person("Jane", 42), MediaType.APPLICATION_JSON)
569
+ * .write(new byte[]{'\n'})
570
+ * .complete();
571
+ * }
572
+ * catch (IOException ex) {
573
+ * throw new UncheckedIOException(ex);
574
+ * }
575
+ * });
576
+ * }
577
+ * </pre>
578
+ * @param streamConsumer consumer that will be provided with a stream builder
579
+ * @return the server-side streaming response
580
+ * @since 6.2
581
+ */
582
+ ServerResponse stream (Consumer <StreamBuilder > streamConsumer );
583
+
584
+ }
585
+
586
+ /**
587
+ * Defines a builder for async response bodies.
588
+ * @since 6.2
589
+ * @param <B> the builder subclass
590
+ */
591
+ interface AsyncBuilder <B extends AsyncBuilder <B >> {
592
+
593
+ /**
594
+ * Completes the stream with the given error.
595
+ *
596
+ * <p>The throwable is dispatched back into Spring MVC, and passed to
597
+ * its exception handling mechanism. Since the response has
598
+ * been committed by this point, the response status can not change.
599
+ * @param t the throwable to dispatch
600
+ */
601
+ void error (Throwable t );
602
+
603
+ /**
604
+ * Completes the stream.
605
+ */
606
+ void complete ();
607
+
608
+ /**
609
+ * Register a callback to be invoked when a request times
610
+ * out.
611
+ * @param onTimeout the callback to invoke on timeout
612
+ * @return this builder
613
+ */
614
+ B onTimeout (Runnable onTimeout );
615
+
616
+ /**
617
+ * Register a callback to be invoked when an error occurs during
618
+ * processing.
619
+ * @param onError the callback to invoke on error
620
+ * @return this builder
621
+ */
622
+ B onError (Consumer <Throwable > onError );
623
+
624
+ /**
625
+ * Register a callback to be invoked when the request completes.
626
+ * @param onCompletion the callback to invoked on completion
627
+ * @return this builder
628
+ */
629
+ B onComplete (Runnable onCompletion );
630
+
550
631
}
551
632
552
633
@@ -555,7 +636,7 @@ interface BodyBuilder extends HeadersBuilder<BodyBuilder> {
555
636
*
556
637
* @since 5.3.2
557
638
*/
558
- interface SseBuilder {
639
+ interface SseBuilder extends AsyncBuilder < SseBuilder > {
559
640
560
641
/**
561
642
* Sends the given object as a server-sent event.
@@ -618,45 +699,45 @@ interface SseBuilder {
618
699
*/
619
700
void data (Object object ) throws IOException ;
620
701
621
- /**
622
- * Completes the event stream with the given error.
623
- *
624
- * <p>The throwable is dispatched back into Spring MVC, and passed to
625
- * its exception handling mechanism. Since the response has
626
- * been committed by this point, the response status can not change.
627
- * @param t the throwable to dispatch
628
- */
629
- void error (Throwable t );
702
+ }
630
703
631
- /**
632
- * Completes the event stream.
633
- */
634
- void complete ();
704
+ /**
705
+ * Defines a builder for a streaming response body.
706
+ *
707
+ * @since 6.2
708
+ */
709
+ interface StreamBuilder extends AsyncBuilder <StreamBuilder > {
635
710
636
711
/**
637
- * Register a callback to be invoked when an SSE request times
638
- * out.
639
- * @param onTimeout the callback to invoke on timeout
712
+ * Write the given object to the response stream, without flushing.
713
+ * Strings will be sent as UTF-8 encoded bytes, byte arrays will be sent as-is,
714
+ * and other objects will be converted into JSON using
715
+ * {@linkplain HttpMessageConverter message converters}.
716
+ * @param object the object to send as data
640
717
* @return this builder
718
+ * @throws IOException in case of I/O errors
641
719
*/
642
- SseBuilder onTimeout ( Runnable onTimeout ) ;
720
+ StreamBuilder write ( Object object ) throws IOException ;
643
721
644
722
/**
645
- * Register a callback to be invoked when an error occurs during SSE
646
- * processing.
647
- * @param onError the callback to invoke on error
723
+ * Write the given object to the response stream, without flushing.
724
+ * Strings will be sent as UTF-8 encoded bytes, byte arrays will be sent as-is,
725
+ * and other objects will be converted into JSON using
726
+ * {@linkplain HttpMessageConverter message converters}.
727
+ * @param object the object to send as data
728
+ * @param mediaType the media type to use for encoding the provided data
648
729
* @return this builder
730
+ * @throws IOException in case of I/O errors
649
731
*/
650
- SseBuilder onError ( Consumer < Throwable > onError ) ;
732
+ StreamBuilder write ( Object object , @ Nullable MediaType mediaType ) throws IOException ;
651
733
652
734
/**
653
- * Register a callback to be invoked when the SSE request completes.
654
- * @param onCompletion the callback to invoked on completion
655
- * @return this builder
735
+ * Flush the buffered response stream content to the network.
736
+ * @throws IOException in case of I/O errors
656
737
*/
657
- SseBuilder onComplete (Runnable onCompletion );
658
- }
738
+ void flush () throws IOException ;
659
739
740
+ }
660
741
661
742
/**
662
743
* Defines the context used during the {@link #writeTo(HttpServletRequest, HttpServletResponse, Context)}.
0 commit comments