Added ResponseHeadersViewer and minor UI tweaks
This commit is contained in:
parent
6d06518693
commit
861b5deab1
8 changed files with 118 additions and 27 deletions
|
@ -76,15 +76,13 @@ public class DashboardController implements Initializable {
|
||||||
private Label statusCode, statusCodeDescription, responseTime,
|
private Label statusCode, statusCodeDescription, responseTime,
|
||||||
responseSize, errorTitle, errorDetails, responseType;
|
responseSize, errorTitle, errorDetails, responseType;
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton cancelButton;
|
private JFXButton cancelButton, copyBodyButton;
|
||||||
@FXML
|
@FXML
|
||||||
TabPane requestOptionsTab;
|
TabPane requestOptionsTab;
|
||||||
@FXML
|
@FXML
|
||||||
Tab paramsTab, authTab, headersTab, bodyTab;
|
Tab paramsTab, authTab, headersTab, bodyTab;
|
||||||
@FXML
|
@FXML
|
||||||
private Tab visualizerTab;
|
private Tab visualizerTab, responseHeadersTab;
|
||||||
@FXML
|
|
||||||
private ScrollPane scrollPane;
|
|
||||||
|
|
||||||
private JFXSnackbar snackbar;
|
private JFXSnackbar snackbar;
|
||||||
private final String[] httpMethods = {"GET", "POST", "PUT", "DELETE", "PATCH"};
|
private final String[] httpMethods = {"GET", "POST", "PUT", "DELETE", "PATCH"};
|
||||||
|
@ -95,6 +93,7 @@ public class DashboardController implements Initializable {
|
||||||
private BodyTabController bodyTabController;
|
private BodyTabController bodyTabController;
|
||||||
private IntegerProperty paramsCountProperty;
|
private IntegerProperty paramsCountProperty;
|
||||||
private Visualizer visualizer;
|
private Visualizer visualizer;
|
||||||
|
private ResponseHeadersViewer responseHeadersViewer;
|
||||||
|
|
||||||
private GETRequest getRequest;
|
private GETRequest getRequest;
|
||||||
private DataDispatchRequest dataRequest;
|
private DataDispatchRequest dataRequest;
|
||||||
|
@ -148,11 +147,21 @@ public class DashboardController implements Initializable {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
copyBodyButton.setOnAction(e -> {
|
||||||
|
responseArea.selectAll();
|
||||||
|
responseArea.copy();
|
||||||
|
responseArea.deselect();
|
||||||
|
snackbar.show("Request body copied to clipboard.", 5000);
|
||||||
|
});
|
||||||
|
|
||||||
errorTitle.setText("Oops... That's embarrassing!");
|
errorTitle.setText("Oops... That's embarrassing!");
|
||||||
errorDetails.setText("Something went wrong. Try to make another getRequest.\nRestart Everest if that doesn't work.");
|
errorDetails.setText("Something went wrong. Try to make another getRequest.\nRestart Everest if that doesn't work.");
|
||||||
|
|
||||||
visualizer = new Visualizer();
|
visualizer = new Visualizer();
|
||||||
scrollPane.setContent(visualizer);
|
visualizerTab.setContent(visualizer);
|
||||||
|
|
||||||
|
responseHeadersViewer = new ResponseHeadersViewer();
|
||||||
|
responseHeadersTab.setContent(responseHeadersViewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -321,7 +330,7 @@ public class DashboardController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSucceeded() {
|
private void onSucceeded() {
|
||||||
updateDashboard(requestManager.getValue());
|
displayResponse(requestManager.getValue());
|
||||||
errorLayer.setVisible(false);
|
errorLayer.setVisible(false);
|
||||||
loadingLayer.setVisible(false);
|
loadingLayer.setVisible(false);
|
||||||
requestManager.reset();
|
requestManager.reset();
|
||||||
|
@ -333,13 +342,14 @@ public class DashboardController implements Initializable {
|
||||||
loadingLayer.setVisible(true);
|
loadingLayer.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDashboard(EverestResponse response) {
|
private void displayResponse(EverestResponse response) {
|
||||||
prettifyResponseBody(response);
|
prettifyResponseBody(response);
|
||||||
responseBox.getChildren().add(0, responseDetails);
|
responseBox.getChildren().add(0, responseDetails);
|
||||||
statusCode.setText(Integer.toString(response.getStatusCode()));
|
statusCode.setText(Integer.toString(response.getStatusCode()));
|
||||||
statusCodeDescription.setText(Response.Status.fromStatusCode(response.getStatusCode()).getReasonPhrase());
|
statusCodeDescription.setText(Response.Status.fromStatusCode(response.getStatusCode()).getReasonPhrase());
|
||||||
responseTime.setText(Long.toString(response.getTime()) + " ms");
|
responseTime.setText(Long.toString(response.getTime()) + " ms");
|
||||||
responseSize.setText(Integer.toString(response.getSize()) + " B");
|
responseSize.setText(Integer.toString(response.getSize()) + " B");
|
||||||
|
responseHeadersViewer.populate(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prettifyResponseBody(EverestResponse response) {
|
private void prettifyResponseBody(EverestResponse response) {
|
||||||
|
@ -364,9 +374,7 @@ public class DashboardController implements Initializable {
|
||||||
JsonNode node = EverestUtilities.mapper.readTree(responseBody);
|
JsonNode node = EverestUtilities.mapper.readTree(responseBody);
|
||||||
responseArea.setText(EverestUtilities.mapper.writeValueAsString(node));
|
responseArea.setText(EverestUtilities.mapper.writeValueAsString(node));
|
||||||
visualizerTab.setDisable(false);
|
visualizerTab.setDisable(false);
|
||||||
TreeItem<HBox> root = new TreeItem<>();
|
visualizer.populate(node);
|
||||||
visualizer.setRoot(root);
|
|
||||||
visualizer.populate(root, "root", node);
|
|
||||||
break;
|
break;
|
||||||
case "application/xml":
|
case "application/xml":
|
||||||
responseType.setText("XML");
|
responseType.setText("XML");
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Rohit Awate.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.rohitawate.everest.controllers;
|
||||||
|
|
||||||
|
import com.rohitawate.everest.models.responses.EverestResponse;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.ScrollPane;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
class ResponseHeadersViewer extends ScrollPane {
|
||||||
|
private VBox container;
|
||||||
|
|
||||||
|
ResponseHeadersViewer() {
|
||||||
|
this.container = new VBox();
|
||||||
|
container.setPadding(new Insets(10, 20, 10, 20));
|
||||||
|
this.setContent(container);
|
||||||
|
|
||||||
|
this.setFitToHeight(true);
|
||||||
|
this.setFitToWidth(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void populate(EverestResponse response) {
|
||||||
|
container.getChildren().clear();
|
||||||
|
|
||||||
|
response.getHeaders().forEach((key, value) -> {
|
||||||
|
Label keyLabel = new Label(key + ": ");
|
||||||
|
keyLabel.getStyleClass().addAll("visualizerKeyLabel", "visualizerLabel");
|
||||||
|
|
||||||
|
Label valueLabel = new Label(value.get(0));
|
||||||
|
valueLabel.getStyleClass().addAll("visualizerValueLabel", "visualizerLabel");
|
||||||
|
|
||||||
|
container.getChildren().add(new HBox(keyLabel, valueLabel));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,10 +17,7 @@
|
||||||
package com.rohitawate.everest.controllers;
|
package com.rohitawate.everest.controllers;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.Tooltip;
|
|
||||||
import javafx.scene.control.TreeItem;
|
|
||||||
import javafx.scene.control.TreeView;
|
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -28,12 +25,27 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
class Visualizer extends TreeView<HBox> {
|
class Visualizer extends ScrollPane {
|
||||||
|
private TreeView<HBox> visualizer;
|
||||||
|
|
||||||
Visualizer() {
|
Visualizer() {
|
||||||
this.setShowRoot(false);
|
this.visualizer = new TreeView<>();
|
||||||
|
this.visualizer.setShowRoot(false);
|
||||||
|
this.setContent(this.visualizer);
|
||||||
|
|
||||||
|
this.setFitToHeight(true);
|
||||||
|
this.setFitToWidth(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void populate(TreeItem<HBox> rootItem, String rootName, JsonNode root) {
|
void populate(JsonNode node) {
|
||||||
|
this.populate(new TreeItem<>(), "root", node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populate(TreeItem<HBox> rootItem, String rootName, JsonNode root) {
|
||||||
|
if (rootName.equals("root")) {
|
||||||
|
this.visualizer.setRoot(rootItem);
|
||||||
|
}
|
||||||
|
|
||||||
Label rootLabel = new Label(rootName);
|
Label rootLabel = new Label(rootName);
|
||||||
rootLabel.getStyleClass().addAll("visualizerRootLabel", "visualizerLabel");
|
rootLabel.getStyleClass().addAll("visualizerRootLabel", "visualizerLabel");
|
||||||
rootItem.setValue(new HBox(rootLabel));
|
rootItem.setValue(new HBox(rootLabel));
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package com.rohitawate.everest.models.responses;
|
package com.rohitawate.everest.models.responses;
|
||||||
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
|
|
||||||
public class EverestResponse {
|
public class EverestResponse {
|
||||||
private String body;
|
private String body;
|
||||||
|
@ -24,6 +25,7 @@ public class EverestResponse {
|
||||||
private long time;
|
private long time;
|
||||||
private int size;
|
private int size;
|
||||||
private MediaType mediaType;
|
private MediaType mediaType;
|
||||||
|
private MultivaluedMap<String, String> headers;
|
||||||
|
|
||||||
public String getBody() {
|
public String getBody() {
|
||||||
return body;
|
return body;
|
||||||
|
@ -64,4 +66,12 @@ public class EverestResponse {
|
||||||
public void setStatusCode(int statusCode) {
|
public void setStatusCode(int statusCode) {
|
||||||
this.statusCode = statusCode;
|
this.statusCode = statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MultivaluedMap<String, String> getHeaders() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeaders(MultivaluedMap<String, String> headers) {
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ public abstract class RequestManager extends Service<EverestResponse> {
|
||||||
String responseBody = serverResponse.readEntity(String.class);
|
String responseBody = serverResponse.readEntity(String.class);
|
||||||
response = new EverestResponse();
|
response = new EverestResponse();
|
||||||
|
|
||||||
|
response.setHeaders(serverResponse.getStringHeaders());
|
||||||
response.setTime(initialTime, finalTime);
|
response.setTime(initialTime, finalTime);
|
||||||
response.setBody(responseBody);
|
response.setBody(responseBody);
|
||||||
response.setMediaType(serverResponse.getMediaType());
|
response.setMediaType(serverResponse.getMediaType());
|
||||||
|
|
BIN
src/main/resources/assets/Copy.png
Normal file
BIN
src/main/resources/assets/Copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 203 B |
|
@ -71,6 +71,10 @@
|
||||||
-fx-background-color: #1b1b1b;
|
-fx-background-color: #1b1b1b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#copyBodyButton {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
#clearResponseAreaButton {
|
#clearResponseAreaButton {
|
||||||
-fx-background-color: #822f2f;
|
-fx-background-color: #822f2f;
|
||||||
}
|
}
|
||||||
|
@ -317,19 +321,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.visualizerRootLabel {
|
.visualizerRootLabel {
|
||||||
-fx-font-size: 18px;
|
-fx-font-size: 17px;
|
||||||
-fx-text-fill: #dedede;
|
-fx-text-fill: #dedede;
|
||||||
-fx-font-weight: bold;
|
-fx-font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.visualizerKeyLabel {
|
.visualizerKeyLabel {
|
||||||
-fx-font-size: 18px;
|
-fx-font-size: 17px;
|
||||||
-fx-text-fill: #bababa;
|
-fx-text-fill: #bababa;
|
||||||
-fx-font-weight: bold;
|
-fx-font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.visualizerValueLabel {
|
.visualizerValueLabel {
|
||||||
-fx-font-size: 18px;
|
-fx-font-size: 16px;
|
||||||
-fx-text-fill: #959595;
|
-fx-text-fill: #959595;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,16 @@
|
||||||
<Insets/>
|
<Insets/>
|
||||||
</HBox.margin>
|
</HBox.margin>
|
||||||
</Label>
|
</Label>
|
||||||
|
<JFXButton fx:id="copyBodyButton" textFill="WHITE">
|
||||||
|
<graphic>
|
||||||
|
<ImageView fitHeight="20.0" fitWidth="20.0" pickOnBounds="true"
|
||||||
|
preserveRatio="true">
|
||||||
|
<image>
|
||||||
|
<Image url="@../../assets/Copy.png"/>
|
||||||
|
</image>
|
||||||
|
</ImageView>
|
||||||
|
</graphic>
|
||||||
|
</JFXButton>
|
||||||
<JFXButton fx:id="clearResponseAreaButton" buttonType="RAISED" onAction="#clearResponseArea" ripplerFill="WHITE" text=" CLEAR" textFill="WHITE" HBox.hgrow="ALWAYS">
|
<JFXButton fx:id="clearResponseAreaButton" buttonType="RAISED" onAction="#clearResponseArea" ripplerFill="WHITE" text=" CLEAR" textFill="WHITE" HBox.hgrow="ALWAYS">
|
||||||
<graphic>
|
<graphic>
|
||||||
<ImageView fitHeight="15.0" fitWidth="15.0" pickOnBounds="true" preserveRatio="true">
|
<ImageView fitHeight="15.0" fitWidth="15.0" pickOnBounds="true" preserveRatio="true">
|
||||||
|
@ -208,13 +218,8 @@
|
||||||
wrapText="true"/>
|
wrapText="true"/>
|
||||||
</content>
|
</content>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab fx:id="visualizerTab" closable="false" text="VISUALIZER">
|
<Tab fx:id="visualizerTab" closable="false" text="VISUALIZER"/>
|
||||||
<content>
|
<Tab fx:id="responseHeadersTab" closable="false" text="HEADERS"/>
|
||||||
<ScrollPane fx:id="scrollPane" fitToHeight="true"
|
|
||||||
fitToWidth="true" hbarPolicy="NEVER"/>
|
|
||||||
</content>
|
|
||||||
</Tab>
|
|
||||||
<Tab closable="false" text="HEADERS"/>
|
|
||||||
</tabs>
|
</tabs>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<VBox fx:id="loadingLayer" alignment="CENTER" visible="false">
|
<VBox fx:id="loadingLayer" alignment="CENTER" visible="false">
|
||||||
|
|
Loading…
Reference in a new issue