3

I'm learning the java.net.http api, trying to download a file given a range of bytes already downloaded. For this the range header can be used (supposing the server supports such feature).

Using org.apache.http.client.methods.HttpGet I can do this:

HttpGet httpGet= new HttpGet("http://exampleURL.com/aFile");
if (myFile.length() > 0) {
            httpGet.addHeader("Range", "bytes=" + myFile.length() + "-"+totalBytes));
}
httpGet.addHeader("xxxx", "yyyy");//ok

Now with HttpRequest I can't add new headers dynamically, I have to create a new whole HttpRequest:

HttpRequest request = null;
if (myFile.length() > 0) {
  request = HttpRequest.newBuilder()
      .uri(URI.create("http://exampleURL.com/aFile"))
      .header("Range","bytes="+myFile.length() +"-"+ totalBytes)
      .build();
}else{
  request = HttpRequest.newBuilder()
      .uri(URI.create("http://exampleURL.com/aFile"))
      .build();
}
request.header("xxxx","yyyyy")//Can't do this anymore

I there a way add them dynamically?

I see that the docs say:

Once built an HttpRequest is immutable, and can be sent multiple times.

But what's the point to be immutable? What if I need for any reason to modify the headers?

Reference:

https://openjdk.java.net/groups/net/httpclient/intro.html

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
tec
  • 999
  • 3
  • 18
  • 40
  • 4
    Instead of chaining methods, you can store the `HttpRequest.Builder` instance and call the various methods separately. Only call `build` right before you send the request. – Albjenow Oct 11 '19 at 10:18
  • @Albjenow Oh... :/ didn't realize that. Thx – tec Oct 11 '19 at 10:21

2 Answers2

6

As Albjenow suggested you can create the builder with common fields first and then build the final request after applying your logic. It would look like :

HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
                .uri(URI.create("http://exampleURL.com/aFile"));

if (myFile.length() > 0) {
    requestBuilder.header("Range","bytes="+myFile.length() +"-"+ totalBytes);
}

requestBuilder.header("xxxx","yyyyy");

HttpRequest request = requestBuilder.build();
Michał Krzywański
  • 15,659
  • 4
  • 36
  • 63
2

An alternate way could be determining all the possible headers before completing the build chain for the HttpRequest and using them with HttpRequest.Builder#headers as:

List<String> headers = new ArrayList<>();
if (myFile.length() > 0) {
    headers.add("Range");
    headers.add("bytes=" + myFile.length() + "-" + totalBytes);
}

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("http://exampleURL.com/aFile"))
        .headers(headers.toArray(String[]::new))
        .build();
Naman
  • 27,789
  • 26
  • 218
  • 353