Class Blob

  • All Implemented Interfaces:
    java.net.http.HttpRequest.BodyPublisher, java.util.concurrent.Flow.Publisher<java.nio.ByteBuffer>

    public class Blob
    extends java.lang.Object
    implements java.net.http.HttpRequest.BodyPublisher
    A utility class for creating data blobs from various input sources that implements HttpRequest.BodyPublisher.

    This class provides convenient factory methods to create blobs from:

    Each blob can be used directly as a HttpRequest.BodyPublisher since this class implements that interface.

    Additionally, this class provides consumption methods for reactive data processing:

    Single-use consumption: When using consumption methods (asPublisher(), toByteArray(), toFile()), each Blob instance can only be consumed once. After any consumption method is called, the instance is considered consumed and cannot be reused. Any further attempt to use a consumption method will result in an IllegalStateException.

    Retry compatibility: Most blob types support HTTP request retries effectively. However, InputStream-backed blobs (from(InputStream)) do not support retries as the stream gets consumed during the first attempt. For retry-compatible scenarios, prefer file-based (from(Path)) or in-memory (from(byte[])) alternatives.

    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.util.concurrent.Flow.Publisher<java.nio.ByteBuffer> asPublisher()
      Returns a Flow.Publisher<ByteBuffer> that emits individual ByteBuffer from the underlying stream.
      long contentLength()  
      static Blob from​(byte[] data)
      Creates a Blob from a byte array.
      static Blob from​(java.io.InputStream inputStream)
      Creates a Blob from an InputStream.
      static Blob from​(java.lang.String string)
      Creates a Blob from a String using UTF-8 encoding.
      static Blob from​(java.nio.ByteBuffer buffer)
      Creates a Blob from a single ByteBuffer.
      static Blob from​(java.nio.file.Path path)
      Creates a Blob from a file path.
      static Blob from​(java.util.concurrent.Flow.Publisher<java.util.List<java.nio.ByteBuffer>> sourcePublisher)
      Creates a Blob from a Flow.Publisher<List<ByteBuffer>>.
      static Blob from​(java.util.List<java.nio.ByteBuffer> buffers)
      Creates a Blob from a list of ByteBuffers.
      void subscribe​(java.util.concurrent.Flow.Subscriber<? super java.nio.ByteBuffer> subscriber)  
      java.util.concurrent.CompletableFuture<byte[]> toByteArray()
      Collects the entire stream into a single byte array.
      java.util.concurrent.CompletableFuture<java.nio.file.Path> toFile​(java.nio.file.Path destinationPath)
      Writes the entire stream to the specified file path.
      java.util.concurrent.CompletableFuture<java.io.InputStream> toInputStream()
      Converts the entire stream into an InputStream for traditional I/O operations.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • from

        public static Blob from​(java.nio.file.Path path)
                         throws java.io.FileNotFoundException
        Creates a Blob from a file path.

        This method uses the Java HTTP client's HttpRequest.BodyPublishers.ofFile() to create a reactive publisher from the file content.

        Parameters:
        path - the path to the file to read
        Returns:
        a new Blob instance
        Throws:
        java.io.FileNotFoundException - if the file does not exist or cannot be read
        java.lang.NullPointerException - if path is null
      • from

        public static Blob from​(java.io.InputStream inputStream)
        Creates a Blob from an InputStream.

        This method uses HttpRequest.BodyPublishers.ofInputStream() to create a reactive publisher that reads from the InputStream lazily, avoiding blocking I/O operations.

        Important: InputStream-backed blobs do not support retries effectively. If the HTTP request fails and is retried, the InputStream will have already been consumed during the first attempt, causing subsequent retry attempts to send empty request bodies. For retry-compatible scenarios, consider using from(Path) for file-based data or from(byte[]) for in-memory data.

        Parameters:
        inputStream - the InputStream to read from
        Returns:
        a new Blob instance
        Throws:
        java.lang.NullPointerException - if inputStream is null
      • from

        public static Blob from​(java.lang.String string)
        Creates a Blob from a String using UTF-8 encoding.
        Parameters:
        string - the string to convert to a Blob
        Returns:
        a new Blob instance
        Throws:
        java.lang.NullPointerException - if string is null
      • from

        public static Blob from​(byte[] data)
        Creates a Blob from a byte array.

        This method uses HttpRequest.BodyPublishers.ofByteArray().

        Parameters:
        data - the byte array to wrap as a Blob
        Returns:
        a new Blob instance
        Throws:
        java.lang.NullPointerException - if data is null
      • from

        public static Blob from​(java.nio.ByteBuffer buffer)
        Creates a Blob from a single ByteBuffer.
        Parameters:
        buffer - the ByteBuffer to wrap as a Blob
        Returns:
        a new Blob instance
        Throws:
        java.lang.NullPointerException - if buffer is null
      • from

        public static Blob from​(java.util.List<java.nio.ByteBuffer> buffers)
        Creates a Blob from a list of ByteBuffers.
        Parameters:
        buffers - the list of ByteBuffers to wrap as a Blob
        Returns:
        a new Blob instance
        Throws:
        java.lang.NullPointerException - if buffers is null
      • from

        public static Blob from​(java.util.concurrent.Flow.Publisher<java.util.List<java.nio.ByteBuffer>> sourcePublisher)
        Creates a Blob from a Flow.Publisher<List<ByteBuffer>>.

        This method uses ReactiveUtils.flatten() to convert the publisher of lists into a publisher of individual ByteBuffers.

        Parameters:
        sourcePublisher - the publisher that provides data as lists of ByteBuffers
        Returns:
        a new Blob instance
        Throws:
        java.lang.NullPointerException - if sourcePublisher is null
      • asPublisher

        public java.util.concurrent.Flow.Publisher<java.nio.ByteBuffer> asPublisher()
        Returns a Flow.Publisher<ByteBuffer> that emits individual ByteBuffer from the underlying stream.

        Consumes this instance: After calling this method, this Blob cannot be used again.

        Returns:
        a publisher of individual ByteBuffer items.
        Throws:
        java.lang.IllegalStateException - if this instance has already been consumed.
      • toByteArray

        public java.util.concurrent.CompletableFuture<byte[]> toByteArray()
        Collects the entire stream into a single byte array.

        Consumes this instance: After calling this method, this Blob cannot be used again.

        The returned CompletableFuture completes when all data has been received and assembled into the byte array, or completes exceptionally if an error occurs.

        Returns:
        a CompletableFuture containing the complete byte array.
        Throws:
        java.lang.IllegalStateException - if this instance has already been consumed.
      • toFile

        public java.util.concurrent.CompletableFuture<java.nio.file.Path> toFile​(java.nio.file.Path destinationPath)
        Writes the entire stream to the specified file path.

        Consumes this instance: After calling this method, this Blob cannot be used again.

        The returned CompletableFuture completes with the Path to the written file when all data has been successfully written, or completes exceptionally if an error occurs.

        Parameters:
        destinationPath - the path where the stream data will be written. If the file exists, it will be truncated.
        Returns:
        a CompletableFuture containing the Path to the written file.
        Throws:
        java.lang.NullPointerException - if destinationPath is null.
        java.lang.IllegalStateException - if this instance has already been consumed.
      • toInputStream

        public java.util.concurrent.CompletableFuture<java.io.InputStream> toInputStream()
        Converts the entire stream into an InputStream for traditional I/O operations.

        Consumes this instance: After calling this method, this Blob cannot be used again.

        The returned CompletableFuture completes with an InputStream containing all the data from the stream when ready, or completes exceptionally if an error occurs. The resulting InputStream can be used with traditional Java I/O APIs.

        Returns:
        a CompletableFuture containing an InputStream with the stream data.
        Throws:
        java.lang.IllegalStateException - if this instance has already been consumed.
      • contentLength

        public long contentLength()
        Specified by:
        contentLength in interface java.net.http.HttpRequest.BodyPublisher
      • subscribe

        public void subscribe​(java.util.concurrent.Flow.Subscriber<? super java.nio.ByteBuffer> subscriber)
        Specified by:
        subscribe in interface java.util.concurrent.Flow.Publisher<java.nio.ByteBuffer>