Java 11 comes with a nice HttpClient API/Implementation so that we no longer need to rely on external libraries like Apache HttpClient execute http requests.
It has the following simple classes(namely HttpClient, HttpRequest, HttpResponse, BodyPublisher, BodyHandler) and they all follow builder pattern to create objects.
Creating HttpClient:
HttpClient client = HttpClient.newBuilder().build();
Creating request:
HttpRequest request = HttpRequest.newBuilder()
.header("key1", "value1")
.header("key2", "value2")
.uri(URI.create("http://localhost:8080/hello"))
.POST(HttpRequest.BodyPublishers.ofString("Request Body"))
.build();
Sending request:
client.send(request, HttpResponse.BodyHandlers.APPROPRIATE_HANDLER);
Here, BodyPublisher and BodyHandler can be used to create request body and process returned response respectively. They both support string, byte, file, input stream etc
Upload file using BodyPublishers.ofFile
Normally file upload using a web page are implemented using multi-part(file data with additional properties). But in this example we are going to upload file's byte array in request body and file name in request param.
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class HttpTest {
public static void main(String[] args) throws Exception {
uploadFile(Path.of("testFile.txt"));
}
public static void uploadFile(Path file) throws IOException, InterruptedException {
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/uploadFile?uploader=HttpTestApp&fileName="
+ file.getFileName()))
.POST(HttpRequest.BodyPublishers.ofFile(file))
.build();
client.send(request, HttpResponse.BodyHandlers.ofString());
}
}
To make the example complete, let's assume we have a following simple Spring Boot app that receives the file byte array as request body:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.*;
@SpringBootApplication
public class FileUploadApp {
public static void main(String[] args) {
SpringApplication.run(FileUploadApp.class, args);
}
}
@Controller
class FileUplCtrl {
@PostMapping(path = "/uploadFile")
public void addPhoto(@RequestBody byte[] barr,
@RequestParam(name = "uploader") String uploader,
@RequestParam(name = "fileName") String fileName) throws Exception {
System.out.println("Received file " + fileName + " , uploaded by " + uploader + " Size: " + barr.length);
//write to disk
try (OutputStream os = new FileOutputStream(new File("UPL" + fileName))) {
os.write(barr);
}
}
}
Required Dependency on Spring Boot app:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Enjoy coding!