Sometimes it can be useful to use some UI to perform HTTP requests and not just CLI tools. Od course, there are tools like Postamn or Insomnia and they are great, but it can be good to have some very simple own UI to do this and test some simple thinsgs :)
Code on Github: https://github.com/ahndmal/http-client-ktl-jfx.
We will use Kotlin (https://kotlinlang.org) and OpenJFX (https://openjfx.io) and Gradle to build the app (though javac / kotlinc can be enough).
We add "org.openjfx.javafxplugin" Gradle plugin to build.gradle.kts and add basic configuration:
plugins {
kotlin("jvm") version "1.9.0"
application
**id("org.openjfx.javafxplugin") version "0.0.13"**
}
javafx {
setVersion("20")
setModules(listOf("javafx.controls"))
}
group = "com.andmal"
version = "0.0.2"
repositories {
mavenCentral()
}
kotlin {
jvmToolchain(20)
}
application {
mainClass.set("Main")
}
Also, we create Main.kt file to add the basic logic to initiate UI with JavaFX library.
class Main : Application() {
override fun start(primaryStage: Stage?) {
val scene = Scene(createContent(), 1200.0, 900.0)
primaryStage?.title = "HTTP Client"
primaryStage?.scene = scene
primaryStage?.show()
}
}
The Main class extends the javafx.application.Application and implements the start method to initiate the UI. We add the createContent() method as the parameter to start method and add the basic logic to it:
private fun createContent(): Parent {
// todo
}
To combine the UI we can use basic VBox / HBox classes for vertical and horizonal alignment of elemtns and also GridPane to map the items by rows and columns.
We add basic UI elements:
val mainBox = VBox()
val requestBox = VBox()
val reqPane = GridPane()
val reqBody = TextArea()
// response
val responsePane = GridPane()
val responseBox = VBox()
val urlLabel = Label("URL")
urlField = TextField()
Add some padding and background:
mainBox.padding = Insets(10.0)
requestBox.border = Border.stroke(Paint.valueOf("orange"))
HBox.setMargin(requestBox, Insets(10.0))
reqBody.minWidth = 500.0
reqBody.minHeight = 200.0
Then we add buttons, headers to the core elements:
reqPane.add(methodType, 0, 2)
reqPane.add(urlField, 1, 2)
reqPane.add(reqButton, 2, 2)
reqPane.add(reqHeaderButton, 2, 3)
requestBox.children.add(reqPane)
responseBox.children.add(responsePane)
mainBox.children.addAll(
requestBox, responseBox
)
Add listeners to buttons to react to clicking on it:
reqButton.setOnMouseClicked { event ->
if (urlField.length == 0) {
infoHeader.text = "Error: please fill in URL"
infoHeader.background = Background.fill(Paint.valueOf("red"))
infoHeader.textFill = Paint.valueOf("white")
infoHeader.font = Font.font(17.0)
responsePane.add(infoHeader, 0, 0)
} else {
// correct request data
responseBox.children.removeAll()
}
}
Also, we add "Save file" button to save the response as a file:
saveAsFileBtn.setOnMouseClicked {
val file =
Files.createFile(Path.of("./response_${Instant.now().epochSecond}"))
file.writeBytes(httpResponse.body().toByteArray())
}
We use java.net.http.CLient (available since Java v.11) as simple and basic HTTP client:
// HTTP client
val client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1).build()
// request
val req = HttpRequest.newBuilder()
.uri(URI.create(urlField.text))
We want to have some text field for body when using POST or PUT methods:
methodType.setOnAction {
when (methodType.value.first) {
"GET" -> reqPane.children.remove(reqBody)
"POST" -> reqPane.add(reqBody, 1, 3)
"PUT" -> reqPane.add(reqBody, 1, 3)
}
}
Complete building HTTP request depending on what HTTP method we select:
when(methodType.value.second) {
"GET" -> req.GET()
"POST" -> req.POST(BodyPublishers.ofString(reqBody.text))
"PUT" -> req.PUT(BodyPublishers.ofString(reqBody.text))
"DELETE" -> req.DELETE()
}
So we have request section with:
- Select of reqest type
- URL field
- Send button to send request
Response:
- Text area to show response body
- Headers and Status buttons to show additional data when clicking them
Run the app:
Top comments (1)
Good job.