Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8252382

Add a new factory method to concatenate a sequence of BodyPublisher instances into a single publisher.

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 16
    • core-libs
    • None
    • source
    • minimal
    • Adding a new static method (no overload) in a non instantiable static class.
    • Java API
    • SE

      Summary

      Add a static factory method to create a BodyPubisher that publishes a request body consisting of the concatenation of the bytes published by a sequence of BodyPublisher instances.

      Problem

      The HttpRequest.BodyPublishers class provide static methods to create or combine body publishers. Writing a BodyPublisher from scratch is hard, but using ready-made publishers is easy. Providing more ways to combine existing BodyPublisher implementations would help as a building block to compose a request body built from heterogeneous sources. A method that concatenates several publishers into a single one would be a useful addition. It could be used for instance, to aggregate dynamic content provided by the application, with static content, read, for instance, from a file.

      Solution

      Add a new static method to HttpRequest.BodyPublishers:

      public static BodyPublisher concat(BodyPublisher... publishers) {...}

      Specification

      Note: null handling is already covered by the existing blanket statement in the java.net.http package description:

      Unless otherwise stated, null parameter values will cause methods of all classes in this package to throw NullPointerException.

      In class HttpRequest.RequestPublishers (HttpRequest,java):

      +        /**
      +         * Returns a {@code BodyPublisher} that publishes a request
      +         * body consisting of the concatenation of the request bodies
      +         * published by a sequence of publishers.
      +         *
      +         * <p> If the sequence is empty an {@linkplain #noBody() empty} publisher
      +         * is returned. Otherwise, if the sequence contains a single element,
      +         * that publisher is returned. Otherwise a <em>concatenation publisher</em>
      +         * is returned.
      +         *
      +         * <p> The request body published by a <em>concatenation publisher</em>
      +         * is logically equivalent to the request body that would have
      +         * been published by concatenating all the bytes of each publisher
      +         * in sequence.
      +         *
      +         * <p> Each publisher is lazily subscribed to in turn,
      +         * until all the body bytes are published, an error occurs, or the
      +         * concatenation publisher's subscription is cancelled.
      +         * The concatenation publisher may be subscribed to more than once,
      +         * which in turn may result in the publishers in the sequence being
      +         * subscribed to more than once.
      +         *
      +         * <p> The concatenation publisher has a known content
      +         * length only if all publishers in the sequence have a known content
      +         * length. The {@link BodyPublisher#contentLength() contentLength}
      +         * reported by the concatenation publisher is computed as follows:
      +         * <ul>
      +         *     <li> If any of the publishers reports an <em>{@linkplain
      +         *         BodyPublisher#contentLength() unknown}</em> content length,
      +         *         or if the sum of the known content lengths would exceed
      +         *         {@link Long#MAX_VALUE}, the resulting
      +         *         content length is <em>unknown</em>.</li>
      +         *     <li> Otherwise, the resulting content length is the sum of the
      +         *         known content lengths, a number between
      +         *         {@code 0} and {@link Long#MAX_VALUE}, inclusive.</li>
      +         * </ul>
      +         *
      +         * @implNote If the concatenation publisher's subscription is
      +         * {@linkplain Flow.Subscription#cancel() cancelled}, or an error occurs
      +         * while publishing the bytes, not all publishers in the sequence may
      +         * be subscribed to.
      +         *
      +         * @param publishers a sequence of publishers.
      +         * @return An aggregate publisher that publishes a request body
      +         * logically equivalent to the concatenation of all bytes published
      +         * by each publisher in the sequence.
      +         */
      +        public static BodyPublisher concat(BodyPublisher... publishers) {

            dfuchs Daniel Fuchs
            dfuchs Daniel Fuchs
            Chris Hegarty
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: