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

Seed an HttpRequest.Builder from an existing HttpRequest

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 16
    • core-libs
    • None
    • source
    • minimal
    • Java API
    • SE

      Summary

      Add a new factory method that creates an HttpRequest.Builder from an existing HttpRequest. Builders created from this new factory can be used to build an HttpRequest, equivalent to the original request, while allowing amendment and/or alteration of the state prior to construction. The factory method accepts an HttpRequest from which to seed the Builder, as well as a BiPredicate that allows header filtering.

      Problem

      An HttpRequest is immutable; once constructed its state cannot be altered (which is a fine property). While it is possible to recreate an equivalent HttpRequest using the existing API, it is a little cumbersome, error prone, and leads to code duplication. Requests used in a particular session tend to share many similarities, so it seems desirable to facilitate the creation of such request more easily.

      Solution

      HttpRequest already has two factory methods from which a Builder can be created; the first newBuilder()- creates an empty builder, the second newBuilder(URI) - creates a builder with an initial URI. This CSR adds a third way to create a Builder; newBuilder(HttpRequest, BiPredicate) - creates a builder whose initial internal state matches that of the given HttpRequest.

      HTTP headers are of particular interest when creating a related request, and are quite often the subject of scrutiny. A BiPredicate<String,String> may be passed to newBuilder to filter headers from the given request. This provides further control over the initial state of the resulting Builder.

      Specification

      src/java.net.http/share/classes/java/net/http/HttpRequest.java

       +     /**
       +      * Creates a {@code Builder} whose initial state is copied from an existing
       +      * {@code HttpRequest}.
       +      *
       +      * <p> This builder can be used to build an {@code HttpRequest}, equivalent 
       +      * to the original, while allowing amendment of the request state prior to
       +      * construction - for example, adding additional headers.
       +      *
       +      * <p> The {@code filter} is applied to each header name value pair as they
       +      * are copied from the given request. When completed, only headers that
       +      * satisfy the condition as laid out by the {@code filter} will be present
       +      * in the {@code Builder} returned from this method.
       +      *
       +      * @apiNote
       +      * The following scenarios demonstrate typical use-cases of the filter.
       +      * Given an {@code HttpRequest} <em>request</em>:
       +      * <br><br>
       +      * <ul>
       +      *  <li> Retain all headers:
       +      *  <pre>{@code HttpRequest.newBuilder(request, (n, v) -> true)}</pre>
       +      *
       +      *  <li> Remove all headers:
       +      *  <pre>{@code HttpRequest.newBuilder(request, (n, v) -> false)}</pre>
       +      *
       +      *  <li> Remove a particular header (e.g. Foo-Bar):
       +      *  <pre>{@code HttpRequest.newBuilder(request, (name, value) -> !name.equalsIgnoreCase("Foo-Bar"))}</pre>
       +      * </ul>
       +      *
       +      * @param request the original request
       +      * @param filter a header filter
       +      * @return a new request builder
       +      * @throws IllegalArgumentException if a new builder cannot be seeded from
       +      *         the given request (for instance, if the request contains illegal
       +      *         parameters)
       +      * @since 16
       +      */
       +     public static Builder newBuilder(HttpRequest request, BiPredicate<String, String> filter) {

            pconcannon Patrick Concannon (Inactive)
            chegar Chris Hegarty
            Chris Hegarty, Daniel Fuchs
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: