优化代码结构
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -21,3 +21,5 @@
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
*.idea
|
||||
|
||||
logs
|
||||
|
||||
@@ -1,40 +1,8 @@
|
||||
{
|
||||
"projectName" : "HTTP SERVER 模拟器",
|
||||
"projectName" : "HTTP SERVER 模拟器 V1.4",
|
||||
"width" : 1200,
|
||||
"height" : 800,
|
||||
"stringLen" : 8,
|
||||
"intLen" : 8,
|
||||
"serverConfigs" : [ {
|
||||
"serverName" : "天津众华WMS",
|
||||
"port" : 8099,
|
||||
"serverUrls" : [ {
|
||||
"urlName" : "入库任务完成上报",
|
||||
"url" : "/wz/accept/report",
|
||||
"serverName" : "天津众华WMS",
|
||||
"requestType" : "POST",
|
||||
"responseBody" : "{\n\t\"code\": 0,\n\t\"message\": \"success\"\n}",
|
||||
"headerMap" : null
|
||||
}, {
|
||||
"urlName" : "出库任务完成上报",
|
||||
"url" : "/wz/order/report",
|
||||
"serverName" : "天津众华WMS",
|
||||
"requestType" : "POST",
|
||||
"responseBody" : "{\n\t\"code\": 0,\n \"message\":\"success\"\n}",
|
||||
"headerMap" : null
|
||||
}, {
|
||||
"urlName" : "盘点结果同步",
|
||||
"url" : "/wz/material/update",
|
||||
"serverName" : "天津众华WMS",
|
||||
"requestType" : "POST",
|
||||
"responseBody" : "{\n\"code\": 0,\n\"message\": \"success\"\n}",
|
||||
"headerMap" : null
|
||||
}, {
|
||||
"urlName" : "物资信息定时同步",
|
||||
"url" : "/wz/material/infos",
|
||||
"serverName" : "天津众华WMS",
|
||||
"requestType" : "POST",
|
||||
"responseBody" : "{\n\t\"code\": 0,\n\t\"message\": \"success\"\n}",
|
||||
"headerMap" : null
|
||||
} ]
|
||||
} ]
|
||||
"serverConfigs" : null
|
||||
}
|
||||
81
pom.xml
Normal file
81
pom.xml
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.dayrain</groupId>
|
||||
<artifactId>http-server-simulator</artifactId>
|
||||
<version>1.4</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.12.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.12.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>2.12.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>
|
||||
${basedir}/target/extra
|
||||
</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.zenjava</groupId>
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>8.8.3</version>
|
||||
<configuration>
|
||||
<vendor>dayrain</vendor>
|
||||
<mainClass>com.dayrain.views.ApplicationStarter</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.dayrain;
|
||||
|
||||
import com.dayrain.views.HomePage;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class ApplicationStarter extends Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
new HomePage(primaryStage).start();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.dayrain.component;
|
||||
|
||||
import javafx.scene.control.TextArea;
|
||||
|
||||
public class LogArea extends TextArea {
|
||||
private String serverName;
|
||||
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
public void setServerName(String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package com.dayrain.component;
|
||||
|
||||
public enum RequestType {
|
||||
GET, POST;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.Configuration;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.style.ButtonFactory;
|
||||
import com.dayrain.style.LabelFactory;
|
||||
import com.dayrain.views.HomePage;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 添加server
|
||||
*
|
||||
* @author peng
|
||||
* @date 2021/10/28
|
||||
*/
|
||||
public class AddServerHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final Stage primaryStage;
|
||||
|
||||
private final Configuration configuration;
|
||||
|
||||
private final HomePage homePage;
|
||||
|
||||
public AddServerHandler(Stage primaryStage, Configuration configuration, HomePage homePage) {
|
||||
this.primaryStage = primaryStage;
|
||||
this.configuration = configuration;
|
||||
this.homePage = homePage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
Stage stage = new Stage();
|
||||
Label nameLabel = LabelFactory.getLabel("服务名称:");
|
||||
nameLabel.setPrefWidth(80);
|
||||
TextField nameField = new TextField();
|
||||
Label portLabel = LabelFactory.getLabel("端口号:");
|
||||
TextField portField = new TextField();
|
||||
portField.setPrefWidth(80);
|
||||
|
||||
HBox btnHBox = new HBox();
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
btnHBox.getChildren().add(saveButton);
|
||||
btnHBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.add(nameLabel, 0, 0);
|
||||
gridPane.add(nameField, 1, 0);
|
||||
gridPane.add(portLabel, 0, 1);
|
||||
gridPane.add(portField, 1, 1);
|
||||
gridPane.add(btnHBox, 1, 3);
|
||||
gridPane.setAlignment(Pos.CENTER);
|
||||
gridPane.setHgap(20d);
|
||||
gridPane.setVgap(10d);
|
||||
|
||||
stage.setWidth(500);
|
||||
stage.setHeight(400);
|
||||
stage.initOwner(primaryStage);
|
||||
stage.initModality(Modality.WINDOW_MODAL);
|
||||
stage.setScene(new Scene(gridPane));
|
||||
stage.getIcons().addAll(primaryStage.getIcons());
|
||||
stage.show();
|
||||
|
||||
saveButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
String name = nameField.getText();
|
||||
String port = portField.getText();
|
||||
ServerConfig serverConfig = new ServerConfig(name, Integer.parseInt(port), new ArrayList<>());
|
||||
configuration.getServerConfigs().add(serverConfig);
|
||||
homePage.refreshServerContainer();
|
||||
ConfigHolder.save();
|
||||
stage.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.RequestType;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.component.ServerUrl;
|
||||
import com.dayrain.server.ServerThread;
|
||||
import com.dayrain.style.ButtonFactory;
|
||||
import com.dayrain.style.LabelFactory;
|
||||
import com.dayrain.utils.ListViewHelper;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 添加路径
|
||||
*
|
||||
* @author peng
|
||||
* @date 2021/10/27
|
||||
*/
|
||||
public class AddUrlHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final ServerConfig serverConfig;
|
||||
|
||||
private final ListView<ServerUrl> serverUrlListView;
|
||||
|
||||
private final HashMap<String, ServerThread> threadMap;
|
||||
|
||||
private final Stage primaryStage;
|
||||
|
||||
public AddUrlHandler(ServerConfig serverConfig, ListView<ServerUrl> serverUrlListView, HashMap<String, ServerThread> threadMap, Stage primaryStage) {
|
||||
this.serverConfig = serverConfig;
|
||||
this.serverUrlListView = serverUrlListView;
|
||||
this.threadMap = threadMap;
|
||||
this.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
Stage stage = new Stage();
|
||||
Label nameLabel = LabelFactory.getLabel("接口名称:");
|
||||
nameLabel.setPrefWidth(80);
|
||||
TextField nameField = new TextField();
|
||||
|
||||
Label urlLabel = LabelFactory.getLabel("接口地址:");
|
||||
TextField urlField = new TextField();
|
||||
urlField.setPrefWidth(80);
|
||||
|
||||
Label methodLabel = LabelFactory.getLabel("请求方式:");
|
||||
ChoiceBox<String> choiceBox = new ChoiceBox<>();
|
||||
choiceBox.setItems(FXCollections.observableArrayList("POST", "GET"));
|
||||
choiceBox.setValue("POST");
|
||||
urlField.setPrefWidth(80);
|
||||
|
||||
Label respLabel = LabelFactory.getLabel("返回结果:");
|
||||
TextArea textArea = new TextArea();
|
||||
textArea.setPrefWidth(80);
|
||||
|
||||
HBox btnHBox = new HBox();
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
btnHBox.getChildren().add(saveButton);
|
||||
btnHBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.add(methodLabel, 0, 0);
|
||||
gridPane.add(choiceBox, 1, 0);
|
||||
gridPane.add(nameLabel, 0, 1);
|
||||
gridPane.add(nameField, 1, 1);
|
||||
gridPane.add(urlLabel, 0, 2);
|
||||
gridPane.add(urlField, 1, 2);
|
||||
gridPane.add(respLabel, 0, 3);
|
||||
gridPane.add(textArea, 1, 3);
|
||||
gridPane.add(btnHBox, 1, 4);
|
||||
gridPane.setAlignment(Pos.CENTER);
|
||||
gridPane.setHgap(20d);
|
||||
gridPane.setVgap(10d);
|
||||
|
||||
stage.setWidth(550);
|
||||
stage.setHeight(500);
|
||||
stage.initOwner(primaryStage);
|
||||
stage.initModality(Modality.WINDOW_MODAL);
|
||||
stage.setScene(new Scene(gridPane));
|
||||
stage.getIcons().addAll(primaryStage.getIcons());
|
||||
stage.show();
|
||||
|
||||
saveButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
String name = nameField.getText();
|
||||
List<ServerUrl> serverUrls = serverConfig.getServerUrls();
|
||||
for (ServerUrl serverUrl : serverUrls) {
|
||||
if (serverUrl.getUrlName().equals(name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String url = urlField.getText();
|
||||
String resp = textArea.getText();
|
||||
|
||||
String type = choiceBox.getValue();
|
||||
ServerUrl serverUrl = new ServerUrl(serverConfig.getServerName(), name, url, type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET, resp);
|
||||
serverUrls.add(serverUrl);
|
||||
ServerThread serverThread = threadMap.getOrDefault(serverConfig.getServerName(), null);
|
||||
if (serverThread != null) {
|
||||
serverThread.addContext(serverUrl);
|
||||
}
|
||||
ListViewHelper.addAndRefresh(serverUrl, serverUrlListView);
|
||||
ConfigHolder.save();
|
||||
stage.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.Configuration;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.views.HomePage;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class DeleteServerHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final ServerConfig serverConfig;
|
||||
|
||||
private final Configuration configuration;
|
||||
|
||||
private final HomePage homePage;
|
||||
|
||||
public DeleteServerHandler(ServerConfig serverConfig, Configuration configuration, HomePage homePage) {
|
||||
this.serverConfig = serverConfig;
|
||||
this.configuration = configuration;
|
||||
this.homePage = homePage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||
|
||||
alert.setGraphic(new ImageView(homePage.getIcon()));
|
||||
Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
|
||||
stage.getIcons().add(homePage.getIcon());
|
||||
alert.setHeaderText("是否确定删除该服务?");
|
||||
Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK);
|
||||
okButton.setOnAction(event1 -> {
|
||||
configuration.getServerConfigs().remove(serverConfig);
|
||||
homePage.refreshServerContainer();
|
||||
ConfigHolder.save();
|
||||
});
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.component.ServerUrl;
|
||||
import com.dayrain.utils.ListViewHelper;
|
||||
import com.dayrain.views.HomePage;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 删除路径
|
||||
* @author peng
|
||||
* @date 2021/10/27
|
||||
*/
|
||||
public class DeleteUrlHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final ServerConfig serverConfig;
|
||||
|
||||
private final ListView<ServerUrl> serverUrlListView;
|
||||
|
||||
private final ServerUrl serverUrl;
|
||||
|
||||
private final HomePage homePage;
|
||||
|
||||
public DeleteUrlHandler(ServerUrl serverUrl, ServerConfig serverConfig, ListView<ServerUrl> serverUrlListView, HomePage homePage) {
|
||||
this.serverUrl = serverUrl;
|
||||
this.serverConfig = serverConfig;
|
||||
this.serverUrlListView = serverUrlListView;
|
||||
this.homePage = homePage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||
alert.setGraphic(new ImageView(homePage.getIcon()));
|
||||
Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
|
||||
stage.getIcons().add(homePage.getIcon());
|
||||
alert.setHeaderText("是否确定删除该接口?");
|
||||
Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK);
|
||||
okButton.setOnAction(event1 -> {
|
||||
List<ServerUrl> serverUrls = serverConfig.getServerUrls();
|
||||
serverUrls.remove(serverUrl);
|
||||
ConfigHolder.save();
|
||||
ListViewHelper.deleteAndRefresh(serverUrl, serverUrlListView);
|
||||
});
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.Configuration;
|
||||
import com.dayrain.utils.FileUtils;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 导出配置文件
|
||||
*
|
||||
* @author peng
|
||||
* @date 2021/10/28
|
||||
*/
|
||||
public class ExportConfigHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final Stage primaryStage;
|
||||
|
||||
private final Configuration configuration;
|
||||
|
||||
public ExportConfigHandler(Stage primaryStage, Configuration configuration) {
|
||||
this.primaryStage = primaryStage;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
Stage stage = new Stage();
|
||||
stage.initOwner(primaryStage);
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
String projectName = configuration.getProjectName();
|
||||
if (projectName == null) {
|
||||
projectName = "";
|
||||
}
|
||||
projectName += "server";
|
||||
fileChooser.setTitle("导出配置");
|
||||
fileChooser.setInitialFileName(projectName + ".json");
|
||||
File file = fileChooser.showSaveDialog(stage);
|
||||
if (file != null) {
|
||||
FileUtils.saveConfig(configuration, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.Configuration;
|
||||
import com.dayrain.utils.FileUtils;
|
||||
import com.dayrain.views.HomePage;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 导入配置文件
|
||||
*
|
||||
* @author peng
|
||||
* @date 2021/10/28
|
||||
*/
|
||||
public class ImportConfigHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final Stage primaryStage;
|
||||
|
||||
private final HomePage homePage;
|
||||
|
||||
public ImportConfigHandler(Stage primaryStage, HomePage homePage) {
|
||||
this.primaryStage = primaryStage;
|
||||
this.homePage = homePage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
Stage stage = new Stage();
|
||||
stage.initOwner(primaryStage);
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("选择一个文件");
|
||||
//过滤器
|
||||
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("只能导入json文件", "*.json"));
|
||||
File file = fileChooser.showOpenDialog(stage);
|
||||
|
||||
if (file != null) {
|
||||
Configuration loadConfig = FileUtils.load(file);
|
||||
ConfigHolder.replace(loadConfig);
|
||||
FileUtils.saveConfig(loadConfig);
|
||||
homePage.replaceConfig(loadConfig);
|
||||
homePage.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.Server;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.server.ServerThread;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Circle;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 服务启动与关闭控制器
|
||||
*
|
||||
* @author peng
|
||||
* @date 2021/10/27
|
||||
*/
|
||||
public class StartServerHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final Button openButton;
|
||||
|
||||
private final Circle statusCircle;
|
||||
|
||||
private final ServerConfig serverConfig;
|
||||
|
||||
private final HashMap<String, ServerThread> threadMap;
|
||||
|
||||
public StartServerHandler(Button openButton, Circle statusCircle, ServerConfig serverConfig, HashMap<String, ServerThread> threadMap) {
|
||||
this.openButton = openButton;
|
||||
this.statusCircle = statusCircle;
|
||||
this.serverConfig = serverConfig;
|
||||
this.threadMap = threadMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
String serverName = serverConfig.getServerName();
|
||||
if (threadMap.containsKey(serverName)) {
|
||||
ServerThread serverThread = threadMap.get(serverName);
|
||||
if (serverThread != null) {
|
||||
serverThread.stopServer();
|
||||
}
|
||||
threadMap.remove(serverName);
|
||||
openButton.setText("开启服务");
|
||||
statusCircle.setFill(Color.RED);
|
||||
} else {
|
||||
ServerThread serverThread = new ServerThread(new Server(serverConfig));
|
||||
serverThread.start();
|
||||
threadMap.put(serverName, serverThread);
|
||||
openButton.setText("关闭服务");
|
||||
statusCircle.setFill(Color.GREEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.Configuration;
|
||||
import com.dayrain.style.ButtonFactory;
|
||||
import com.dayrain.style.LabelFactory;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class UpdateRandomLenHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final Stage primaryStage;
|
||||
|
||||
public UpdateRandomLenHandler(Stage primaryStage) {
|
||||
this.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
Configuration configuration = ConfigHolder.get();
|
||||
Stage stage = new Stage();
|
||||
Label strName = LabelFactory.getLabel("随机字符长度:");
|
||||
strName.setPrefWidth(150);
|
||||
TextField strField = new TextField(String.valueOf(configuration.getStringLen()));
|
||||
Label intName = LabelFactory.getLabel("随机整数长度:");
|
||||
TextField intField = new TextField(String.valueOf(configuration.getIntLen()));
|
||||
intField.setPrefWidth(150);
|
||||
|
||||
HBox btnHBox = new HBox();
|
||||
Label saveTips1 = LabelFactory.getLabel("注: $string$代指随机字符串");
|
||||
Label saveTips2 = LabelFactory.getLabel("$int$代指随机整数");
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
btnHBox.getChildren().addAll(saveButton);
|
||||
btnHBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
btnHBox.setSpacing(20d);
|
||||
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.add(strName, 0, 0);
|
||||
gridPane.add(strField, 1, 0);
|
||||
gridPane.add(intName, 0, 1);
|
||||
gridPane.add(intField, 1, 1);
|
||||
gridPane.add(saveTips1, 0, 3);
|
||||
gridPane.add(saveTips2, 1, 3);
|
||||
|
||||
gridPane.add(btnHBox, 1, 4);
|
||||
gridPane.setAlignment(Pos.CENTER);
|
||||
gridPane.setHgap(20d);
|
||||
gridPane.setVgap(10d);
|
||||
|
||||
stage.setWidth(500);
|
||||
stage.setHeight(400);
|
||||
stage.initOwner(primaryStage);
|
||||
stage.initModality(Modality.WINDOW_MODAL);
|
||||
stage.setScene(new Scene(gridPane));
|
||||
stage.getIcons().addAll(primaryStage.getIcons());
|
||||
stage.show();
|
||||
|
||||
saveButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
String strLen = strField.getText();
|
||||
String intLen = intField.getText();
|
||||
configuration.setStringLen(Integer.parseInt(strLen));
|
||||
configuration.setIntLen(Integer.parseInt(intLen));
|
||||
ConfigHolder.save();
|
||||
stage.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.style.ButtonFactory;
|
||||
import com.dayrain.style.LabelFactory;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class UpdateServerConfigHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final ServerConfig serverConfig;
|
||||
|
||||
private final Stage primaryStage;
|
||||
|
||||
public UpdateServerConfigHandler(ServerConfig serverConfig, Stage primaryStage) {
|
||||
this.serverConfig = serverConfig;
|
||||
this.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
Stage stage = new Stage();
|
||||
Label serverName = LabelFactory.getLabel("服务名称:");
|
||||
serverName.setPrefWidth(80);
|
||||
TextField nameField = new TextField(serverConfig.getServerName());
|
||||
Label portLabel = LabelFactory.getLabel("端口:");
|
||||
TextField portField = new TextField(String.valueOf(serverConfig.getPort()));
|
||||
portField.setPrefWidth(80);
|
||||
|
||||
HBox btnHBox = new HBox();
|
||||
Label saveTips = LabelFactory.getLabel("重启后生效");
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
btnHBox.getChildren().addAll(saveTips, saveButton);
|
||||
btnHBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
btnHBox.setSpacing(20d);
|
||||
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.add(serverName, 0, 0);
|
||||
gridPane.add(nameField, 1, 0);
|
||||
gridPane.add(portLabel, 0, 1);
|
||||
gridPane.add(portField, 1, 1);
|
||||
|
||||
gridPane.add(btnHBox, 1, 3);
|
||||
gridPane.setAlignment(Pos.CENTER);
|
||||
gridPane.setHgap(20d);
|
||||
gridPane.setVgap(10d);
|
||||
|
||||
stage.setWidth(500);
|
||||
stage.setHeight(400);
|
||||
stage.initOwner(primaryStage);
|
||||
stage.initModality(Modality.WINDOW_MODAL);
|
||||
stage.setScene(new Scene(gridPane));
|
||||
stage.getIcons().addAll(primaryStage.getIcons());
|
||||
stage.show();
|
||||
|
||||
saveButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
String name = nameField.getText();
|
||||
int port = Integer.parseInt(portField.getText());
|
||||
serverConfig.setPort(port);
|
||||
serverConfig.setServerName(name);
|
||||
ConfigHolder.save();
|
||||
stage.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
package com.dayrain.handle;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.RequestType;
|
||||
import com.dayrain.component.ServerUrl;
|
||||
import com.dayrain.style.ButtonFactory;
|
||||
import com.dayrain.style.LabelFactory;
|
||||
import com.dayrain.utils.ListViewHelper;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
|
||||
public class UpdateUrlHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private final ListView<ServerUrl> serverUrlListView;
|
||||
|
||||
private final ServerUrl serverUrl;
|
||||
|
||||
private final Stage primaryStage;
|
||||
|
||||
public UpdateUrlHandler(ServerUrl serverUrl, ListView<ServerUrl> serverUrlListView, Stage primaryStage) {
|
||||
this.serverUrl = serverUrl;
|
||||
this.serverUrlListView = serverUrlListView;
|
||||
this.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
Stage stage = new Stage();
|
||||
Label nameLabel = LabelFactory.getLabel("接口名称:");
|
||||
nameLabel.setPrefWidth(80);
|
||||
TextField nameField = new TextField(serverUrl.getUrlName());
|
||||
Label urlLabel = LabelFactory.getLabel("接口地址:");
|
||||
TextField urlField = new TextField(serverUrl.getUrl());
|
||||
urlField.setEditable(false);
|
||||
urlField.setPrefWidth(80);
|
||||
|
||||
Label methodLabel = LabelFactory.getLabel("请求方式:");
|
||||
ChoiceBox<String> choiceBox = new ChoiceBox<>();
|
||||
choiceBox.setItems(FXCollections.observableArrayList("POST", "GET"));
|
||||
choiceBox.setValue("POST");
|
||||
urlField.setPrefWidth(80);
|
||||
|
||||
Label respLabel = LabelFactory.getLabel("返回结果:");
|
||||
TextArea textArea = new TextArea(serverUrl.getResponseBody());
|
||||
textArea.setPrefWidth(80);
|
||||
|
||||
HBox btnHBox = new HBox();
|
||||
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
btnHBox.getChildren().addAll(saveButton);
|
||||
btnHBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
btnHBox.setSpacing(20d);
|
||||
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.add(methodLabel, 0, 0);
|
||||
gridPane.add(choiceBox, 1, 0);
|
||||
gridPane.add(nameLabel, 0, 1);
|
||||
gridPane.add(nameField, 1, 1);
|
||||
gridPane.add(urlLabel, 0, 2);
|
||||
gridPane.add(urlField, 1, 2);
|
||||
gridPane.add(respLabel, 0, 3);
|
||||
gridPane.add(textArea, 1, 3);
|
||||
gridPane.add(btnHBox, 1, 4);
|
||||
gridPane.setAlignment(Pos.CENTER);
|
||||
gridPane.setHgap(20d);
|
||||
gridPane.setVgap(10d);
|
||||
|
||||
stage.setWidth(550);
|
||||
stage.setHeight(450);
|
||||
stage.initOwner(primaryStage);
|
||||
stage.initModality(Modality.WINDOW_MODAL);
|
||||
stage.setScene(new Scene(gridPane));
|
||||
stage.getIcons().addAll(primaryStage.getIcons());
|
||||
stage.show();
|
||||
|
||||
saveButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
String name = nameField.getText();
|
||||
String url = urlField.getText();
|
||||
String resp = textArea.getText();
|
||||
String type = choiceBox.getValue();
|
||||
serverUrl.setUrlName(name);
|
||||
serverUrl.setUrl(url);
|
||||
serverUrl.setResponseBody(resp);
|
||||
serverUrl.setRequestType(type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET);
|
||||
|
||||
ListViewHelper.refresh(serverUrlListView);
|
||||
ConfigHolder.save();
|
||||
stage.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.Configuration;
|
||||
import com.dayrain.component.ConsoleLog;
|
||||
import com.dayrain.component.LogArea;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.component.ServerUrl;
|
||||
import com.dayrain.handle.AddServerHandler;
|
||||
import com.dayrain.handle.AddUrlHandler;
|
||||
import com.dayrain.handle.DeleteServerHandler;
|
||||
import com.dayrain.handle.DeleteUrlHandler;
|
||||
import com.dayrain.handle.ExportConfigHandler;
|
||||
import com.dayrain.handle.ImportConfigHandler;
|
||||
import com.dayrain.handle.StartServerHandler;
|
||||
import com.dayrain.handle.UpdateRandomLenHandler;
|
||||
import com.dayrain.handle.UpdateServerConfigHandler;
|
||||
import com.dayrain.handle.UpdateUrlHandler;
|
||||
import com.dayrain.server.ServerThread;
|
||||
import com.dayrain.style.ButtonFactory;
|
||||
import com.dayrain.style.LabelFactory;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.MenuBar;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.layout.BackgroundFill;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.CornerRadii;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class HomePage {
|
||||
|
||||
private Stage primaryStage;
|
||||
|
||||
private Configuration configuration = ConfigHolder.init();
|
||||
|
||||
private HashMap<String, ServerThread> threadMap = new HashMap<>();
|
||||
|
||||
private VBox serverContainer;
|
||||
|
||||
private LogArea logArea;
|
||||
|
||||
public HomePage(Stage primaryStage) {
|
||||
this.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
|
||||
BorderPane borderPane = new BorderPane();
|
||||
|
||||
//菜单栏
|
||||
MenuBar menuBar = new MenuBar();
|
||||
Menu menu1 = new Menu("文件");
|
||||
MenuItem menuItem1 = new MenuItem("新建");
|
||||
MenuItem menuItem2 = new MenuItem("导入");
|
||||
MenuItem menuItem3 = new MenuItem("导出");
|
||||
menu1.getItems().addAll(menuItem1, menuItem2, menuItem3);
|
||||
Menu menu2 = new Menu("设置");
|
||||
MenuItem menuItem21 = new MenuItem("随机值长度");
|
||||
menu2.getItems().add(menuItem21);
|
||||
Menu menu3 = new Menu("帮助");
|
||||
MenuItem menuItem31 = new MenuItem("说明书");
|
||||
menuItem31.setOnAction(event -> {
|
||||
try {
|
||||
Desktop.getDesktop().browse(new URI("https://blog.csdn.net/qq_37855749/article/details/121030800"));
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
MenuItem menuItem32 = new MenuItem("源码地址");
|
||||
menuItem32.setOnAction(event -> {
|
||||
try {
|
||||
Desktop.getDesktop().browse(new URI("https://github.com/DayRain/http-server-simulator"));
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
menu3.getItems().addAll(menuItem31, menuItem32);
|
||||
menuBar.getMenus().addAll(menu1, menu2, menu3);
|
||||
borderPane.setTop(menuBar);
|
||||
|
||||
//渲染服务列表
|
||||
this.serverContainer = new VBox();
|
||||
refreshServerContainer();
|
||||
|
||||
menuItem1.setOnAction(new AddServerHandler(primaryStage, configuration, this));
|
||||
menuItem2.setOnAction(new ImportConfigHandler(primaryStage, this));
|
||||
menuItem3.setOnAction(new ExportConfigHandler(primaryStage, configuration));
|
||||
menuItem21.setOnAction(new UpdateRandomLenHandler(primaryStage));
|
||||
borderPane.setLeft(serverContainer);
|
||||
|
||||
//日志
|
||||
logArea = new LogArea();
|
||||
logArea.setEditable(false);
|
||||
logArea.setFont(Font.font("Microsoft YaHei", 20));
|
||||
logArea.setPrefWidth(582);
|
||||
logArea.setPrefHeight(600);
|
||||
|
||||
ConsoleLog.setTextArea(logArea);
|
||||
|
||||
borderPane.setRight(logArea);
|
||||
|
||||
menuBar.setBackground(getBackGround());
|
||||
|
||||
Scene scene = new Scene(borderPane);
|
||||
primaryStage.setTitle(configuration.getProjectName());
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.setWidth(configuration.getWidth());
|
||||
primaryStage.setHeight(configuration.getHeight());
|
||||
primaryStage.getIcons().add(getIcon());
|
||||
primaryStage.show();
|
||||
primaryStage.setOnCloseRequest(event -> {
|
||||
ConfigHolder.save();
|
||||
if(threadMap.size() > 0) {
|
||||
for (String serverName : threadMap.keySet()) {
|
||||
ServerThread serverThread = threadMap.get(serverName);
|
||||
serverThread.stopServer();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void drawServerPanel(VBox serverContainer, ServerConfig serverConfig, Stage primaryStage) {
|
||||
|
||||
VBox vBox = new VBox();
|
||||
HBox headBox = new HBox();
|
||||
Button editButton = ButtonFactory.getButton("修改配置");
|
||||
Button openButton = ButtonFactory.getButton("开启服务");
|
||||
Button deleteButton = ButtonFactory.getButton("删除服务");
|
||||
Button addButton = ButtonFactory.getButton("添加接口");
|
||||
Circle statusCircle = new Circle();
|
||||
statusCircle.setRadius(10);
|
||||
statusCircle.setFill(Color.RED);
|
||||
//设置服务启动与关闭
|
||||
openButton.setOnAction(new StartServerHandler(openButton, statusCircle, serverConfig, threadMap));
|
||||
editButton.setOnAction(new UpdateServerConfigHandler(serverConfig, primaryStage));
|
||||
deleteButton.setOnAction(new DeleteServerHandler(serverConfig, configuration, this));
|
||||
headBox.getChildren().addAll(openButton, editButton, deleteButton, addButton, statusCircle);
|
||||
HBox.setMargin(statusCircle, new Insets(0, 0, 0, 30));
|
||||
headBox.setSpacing(20d);
|
||||
headBox.setAlignment(Pos.CENTER);
|
||||
//添加url
|
||||
ListView<ServerUrl> serverUrlListView = drawUrlPanel(serverConfig.getServerUrls(), serverConfig);
|
||||
addButton.setOnAction(new AddUrlHandler(serverConfig, serverUrlListView, threadMap, primaryStage));
|
||||
vBox.getChildren().addAll(headBox, serverUrlListView);
|
||||
|
||||
vBox.setSpacing(10d);
|
||||
VBox.setMargin(headBox, new Insets(10, 0, 0, 0));
|
||||
vBox.setPadding(Insets.EMPTY);
|
||||
TitledPane titledPane = new TitledPane(serverConfig.getServerName(), vBox);
|
||||
titledPane.setFont(Font.font("Microsoft YaHei", 18));
|
||||
titledPane.setPrefWidth(600d);
|
||||
titledPane.setExpanded(false);
|
||||
titledPane.setBackground(getBackGround());
|
||||
titledPane.setOnMouseClicked(event -> {
|
||||
if (!serverConfig.getServerName().equals(logArea.getServerName())) {
|
||||
ConsoleLog.resetTextArea(serverConfig.getServerName());
|
||||
}
|
||||
});
|
||||
|
||||
HBox hBox = new HBox();
|
||||
hBox.setPrefHeight(60d);
|
||||
titledPane.setGraphic(hBox);
|
||||
|
||||
serverContainer.getChildren().add(titledPane);
|
||||
}
|
||||
|
||||
public ListView<ServerUrl> drawUrlPanel(List<ServerUrl> serverUrls, ServerConfig serverConfig) {
|
||||
ObservableList<ServerUrl> urlList = FXCollections.observableArrayList(serverUrls);
|
||||
ListView<ServerUrl> serverListViews = new ListView<>(urlList);
|
||||
|
||||
serverListViews.setCellFactory(new Callback<ListView<ServerUrl>, ListCell<ServerUrl>>() {
|
||||
@Override
|
||||
public ListCell<ServerUrl> call(ListView<ServerUrl> param) {
|
||||
return new ListCell<ServerUrl>() {
|
||||
@Override
|
||||
protected void updateItem(ServerUrl item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (empty || item == null) {
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
} else {
|
||||
BorderPane urlPane = new BorderPane();
|
||||
|
||||
HBox labelBox = new HBox();
|
||||
Label nameLabel = LabelFactory.getLabel(item.getUrlName());
|
||||
nameLabel.setPrefWidth(150d);
|
||||
Label urlLabel = LabelFactory.getLabel(item.getUrl());
|
||||
labelBox.getChildren().addAll(nameLabel, urlLabel);
|
||||
labelBox.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
HBox btnBox = new HBox();
|
||||
Button configButton = ButtonFactory.getButton("配置");
|
||||
Button deleteButton = ButtonFactory.getButton("删除");
|
||||
btnBox.setSpacing(10d);
|
||||
btnBox.getChildren().addAll(configButton, deleteButton);
|
||||
HBox.setMargin(deleteButton, new Insets(0, 5, 0, 0));
|
||||
|
||||
deleteButton.setOnAction(new DeleteUrlHandler(item, serverConfig, serverListViews, HomePage.this));
|
||||
configButton.setOnAction(new UpdateUrlHandler(item, serverListViews, primaryStage));
|
||||
|
||||
urlPane.setLeft(labelBox);
|
||||
urlPane.setRight(btnBox);
|
||||
this.setGraphic(urlPane);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
serverListViews.prefHeightProperty().bind(Bindings.size(urlList).multiply(60));
|
||||
serverListViews.setFocusTraversable(false);
|
||||
|
||||
return serverListViews;
|
||||
}
|
||||
|
||||
public void refreshServerContainer() {
|
||||
serverContainer.getChildren().removeAll(serverContainer.getChildren());
|
||||
List<ServerConfig> serverConfigs = configuration.getServerConfigs();
|
||||
if (serverConfigs == null || serverConfigs.size() == 0) {
|
||||
serverConfigs = new ArrayList<>();
|
||||
configuration.setServerConfigs(serverConfigs);
|
||||
}
|
||||
|
||||
for (ServerConfig serverConfig : serverConfigs) {
|
||||
drawServerPanel(serverContainer, serverConfig, primaryStage);
|
||||
}
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
cleanUp();
|
||||
start();
|
||||
}
|
||||
|
||||
public void cleanUp() {
|
||||
for (String name : threadMap.keySet()) {
|
||||
threadMap.get(name).stopServer();
|
||||
}
|
||||
}
|
||||
|
||||
public void replaceConfig(Configuration configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public Image getIcon() {
|
||||
return new Image("resources/panda.png");
|
||||
}
|
||||
|
||||
public Background getBackGround() {
|
||||
BackgroundFill backgroundFill = new BackgroundFill(Color.GRAY, new CornerRadii(1),
|
||||
new Insets(0.0, 0.0, 0.0, 0.0));
|
||||
return new Background(backgroundFill);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,13 @@
|
||||
package com.dayrain.component;
|
||||
|
||||
import com.dayrain.utils.FileUtils;
|
||||
|
||||
/**
|
||||
* 配置类句柄
|
||||
* @author peng
|
||||
* @date 2021/11/8
|
||||
*/
|
||||
public class ConfigHolder {
|
||||
|
||||
private static Configuration configuration;
|
||||
|
||||
private ConfigHolder() {
|
||||
@@ -13,15 +18,18 @@ public class ConfigHolder {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
public synchronized static void save() {
|
||||
FileUtils.saveConfig(configuration);
|
||||
}
|
||||
|
||||
public static Configuration get() {
|
||||
public synchronized static Configuration get() {
|
||||
if(configuration == null) {
|
||||
init();
|
||||
}
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public static void replace(Configuration config) {
|
||||
public synchronized static void replace(Configuration config) {
|
||||
configuration = config;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
package com.dayrain.component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 配置文件
|
||||
* @author peng
|
||||
* @date 2021/11/8
|
||||
*/
|
||||
public class Configuration {
|
||||
|
||||
private String projectName = "HTTP SERVER 模拟器";
|
||||
private String projectName = "HTTP SERVER 模拟器 V1.4";
|
||||
|
||||
private int width;
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package com.dayrain.component;
|
||||
|
||||
import com.dayrain.views.LogArea;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 请求日志打印
|
||||
* @author peng
|
||||
* @date 2021/11/8
|
||||
*/
|
||||
public class ConsoleLog {
|
||||
|
||||
private static final HashMap<String, String> logs = new HashMap<>();
|
||||
@@ -12,11 +18,11 @@ public class ConsoleLog {
|
||||
|
||||
private static LogArea logArea;
|
||||
|
||||
public static void setTextArea(LogArea area) {
|
||||
public static void initTextArea(LogArea area) {
|
||||
logArea = area;
|
||||
}
|
||||
|
||||
public static void log(ServerUrl serverUrl, String params, String resp) {
|
||||
public synchronized static void log(ServerUrl serverUrl, String params, String resp) {
|
||||
String log = logs.getOrDefault(serverUrl.getServerName(), null);
|
||||
if (log == null || NO_REQUEST.equals(log)) {
|
||||
log = "";
|
||||
@@ -36,19 +42,26 @@ public class ConsoleLog {
|
||||
stringBuilder.append("\n\n");
|
||||
|
||||
log += stringBuilder.toString();
|
||||
|
||||
if(log.length() > 5000) {
|
||||
log = log.substring(log.length() - 5000);
|
||||
System.out.println(log.length());
|
||||
}
|
||||
|
||||
logs.put(serverUrl.getServerName(), log);
|
||||
|
||||
if (serverUrl.getServerName().equals(logArea.getServerName())) {
|
||||
if (NO_REQUEST.equals(logArea.getText())) {
|
||||
logArea.setText(log);
|
||||
} else {
|
||||
logArea.setText("");
|
||||
logArea.appendText(log);
|
||||
}
|
||||
logArea.setScrollTop(Double.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetTextArea(String serverName) {
|
||||
public synchronized static void resetTextArea(String serverName) {
|
||||
if (!logs.containsKey(serverName)) {
|
||||
logs.put(serverName, NO_REQUEST);
|
||||
}
|
||||
@@ -8,10 +8,15 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 请求处理
|
||||
* @author peng
|
||||
* @date 2021/11/8
|
||||
*/
|
||||
public class RequestHandler implements HttpHandler {
|
||||
|
||||
private static final String STRING_PATTERN = "$string$";
|
||||
|
||||
private static final String INT_PATTERN = "$int$";
|
||||
|
||||
private final ServerUrl serverUrl;
|
||||
@@ -21,7 +26,7 @@ public class RequestHandler implements HttpHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpExchange exchange) throws IOException {
|
||||
public void handle(HttpExchange exchange) {
|
||||
RequestType requestType = serverUrl.getRequestType();
|
||||
String param = null;
|
||||
if (RequestType.GET.equals(requestType)) {
|
||||
@@ -49,7 +54,8 @@ public class RequestHandler implements HttpHandler {
|
||||
|
||||
private void response(HttpExchange exchange, String jsonBody) {
|
||||
try {
|
||||
exchange.sendResponseHeaders(200, jsonBody.length());
|
||||
byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8);
|
||||
exchange.sendResponseHeaders(200, bytes.length);
|
||||
exchange.setAttribute("Content-Type", "application/json; charset=utf-8");
|
||||
OutputStream outputStream = exchange.getResponseBody();
|
||||
outputStream.write(jsonBody.getBytes(StandardCharsets.UTF_8));
|
||||
9
src/main/java/com/dayrain/component/RequestType.java
Normal file
9
src/main/java/com/dayrain/component/RequestType.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package com.dayrain.component;
|
||||
/**
|
||||
* 请求方式
|
||||
* @author peng
|
||||
* @date 2021/11/8
|
||||
*/
|
||||
public enum RequestType {
|
||||
GET, POST
|
||||
}
|
||||
@@ -1,19 +1,23 @@
|
||||
package com.dayrain.component;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 服务
|
||||
*
|
||||
* @author peng
|
||||
* @date 2021/10/25
|
||||
*/
|
||||
public class Server implements Runnable {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Server.class);
|
||||
|
||||
private final ServerConfig serverConfig;
|
||||
|
||||
private HttpServer httpServer;
|
||||
@@ -25,6 +29,11 @@ public class Server implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
start();
|
||||
System.out.println("【" + serverConfig.getServerName() + "】服务已开启...");
|
||||
}
|
||||
|
||||
public synchronized void start() {
|
||||
try {
|
||||
this.httpServer = HttpServer.create(new InetSocketAddress(serverConfig.getPort()), 0);
|
||||
httpServer.setExecutor(Executors.newCachedThreadPool());
|
||||
@@ -32,20 +41,36 @@ public class Server implements Runnable {
|
||||
addContext(serverUrl);
|
||||
}
|
||||
httpServer.start();
|
||||
System.out.println("【" + serverConfig.getServerName() + "】服务已开启...");
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
logger.error(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
public synchronized void stop() {
|
||||
if (httpServer != null) {
|
||||
System.out.println("【" + serverConfig.getServerName() + "】服务已关闭...");
|
||||
httpServer.stop(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void addContext(ServerUrl serverUrl) {
|
||||
public synchronized void restart() {
|
||||
stop();
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(2);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
start();
|
||||
}
|
||||
|
||||
public synchronized void addContext(ServerUrl serverUrl) {
|
||||
httpServer.createContext(serverUrl.getUrl(), new RequestHandler(serverUrl));
|
||||
}
|
||||
|
||||
public void removeContext(String url) {
|
||||
httpServer.removeContext(url);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.dayrain.component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务配置
|
||||
* @author peng
|
||||
* @date 2021/11/8
|
||||
*/
|
||||
public class ServerConfig {
|
||||
/**
|
||||
* 服务名
|
||||
@@ -48,4 +52,5 @@ public class ServerConfig {
|
||||
public void setServerUrls(List<ServerUrl> serverUrls) {
|
||||
this.serverUrls = serverUrls;
|
||||
}
|
||||
|
||||
}
|
||||
68
src/main/java/com/dayrain/component/ServerThreadHolder.java
Normal file
68
src/main/java/com/dayrain/component/ServerThreadHolder.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package com.dayrain.component;
|
||||
|
||||
import com.dayrain.server.ServerThread;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 正在运行的 server 线程组
|
||||
* @author peng
|
||||
* @date 2021/11/8
|
||||
*/
|
||||
public class ServerThreadHolder {
|
||||
|
||||
private static final HashMap<String, ServerThread> threadMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 停止所有线程
|
||||
*/
|
||||
public synchronized static void stopAll() {
|
||||
if(threadMap.size() > 0) {
|
||||
for (String serverName : threadMap.keySet()) {
|
||||
ServerThread serverThread = threadMap.get(serverName);
|
||||
serverThread.stopServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static void add(String serverName, ServerThread serverThread) {
|
||||
if(!threadMap.containsKey(serverName)) {
|
||||
serverThread.start();
|
||||
threadMap.put(serverName, serverThread);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static void remove(String serverName) {
|
||||
if(contains(serverName)) {
|
||||
threadMap.get(serverName).stopServer();
|
||||
threadMap.remove(serverName);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static boolean contains(String key) {
|
||||
return threadMap.containsKey(key);
|
||||
}
|
||||
|
||||
public synchronized static void addUrl(ServerUrl serverUrl) {
|
||||
if(serverUrl == null || !contains(serverUrl.getServerName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerThread serverThread = threadMap.get(serverUrl.getServerName());
|
||||
serverThread.addContext(serverUrl);
|
||||
}
|
||||
|
||||
public synchronized static void restart(String serverName) {
|
||||
if(contains(serverName)) {
|
||||
ServerThread serverThread = threadMap.get(serverName);
|
||||
serverThread.restartServer();
|
||||
}
|
||||
}
|
||||
|
||||
public static void replaceUrl(String beforeName, String beforeUrl, ServerUrl serverUrl) {
|
||||
if(contains(beforeName)) {
|
||||
ServerThread serverThread = threadMap.get(beforeName);
|
||||
serverThread.replaceUrl(beforeUrl, serverUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.dayrain.component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 请求路径
|
||||
* @author peng
|
||||
* @date 2021/11/8
|
||||
*/
|
||||
public class ServerUrl {
|
||||
|
||||
/**
|
||||
@@ -4,6 +4,7 @@ import com.dayrain.component.Server;
|
||||
import com.dayrain.component.ServerUrl;
|
||||
|
||||
public class ServerThread extends Thread {
|
||||
|
||||
private final Server server;
|
||||
|
||||
public ServerThread(Server server) {
|
||||
@@ -15,7 +16,20 @@ public class ServerThread extends Thread {
|
||||
server.stop();
|
||||
}
|
||||
|
||||
public void restartServer() {
|
||||
server.restart();
|
||||
}
|
||||
|
||||
public void addContext(ServerUrl serverUrl) {
|
||||
server.addContext(serverUrl);
|
||||
}
|
||||
|
||||
public void removeContext(String url) {
|
||||
server.removeContext(url);
|
||||
}
|
||||
|
||||
public void replaceUrl(String beforeUrl, ServerUrl serverUrl) {
|
||||
removeContext(beforeUrl);
|
||||
addContext(serverUrl);
|
||||
}
|
||||
}
|
||||
15
src/main/java/com/dayrain/style/BackGroundFactory.java
Normal file
15
src/main/java/com/dayrain/style/BackGroundFactory.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package com.dayrain.style;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.layout.BackgroundFill;
|
||||
import javafx.scene.layout.CornerRadii;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
public class BackGroundFactory {
|
||||
public static Background getBackGround() {
|
||||
BackgroundFill backgroundFill = new BackgroundFill(Color.GRAY, new CornerRadii(1),
|
||||
new Insets(0.0, 0.0, 0.0, 0.0));
|
||||
return new Background(backgroundFill);
|
||||
}
|
||||
}
|
||||
18
src/main/java/com/dayrain/style/CircleFactory.java
Normal file
18
src/main/java/com/dayrain/style/CircleFactory.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.dayrain.style;
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Circle;
|
||||
/**
|
||||
* 圆
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class CircleFactory {
|
||||
|
||||
public static Circle getLightCircle(Color color) {
|
||||
Circle circle = new Circle();
|
||||
circle.setRadius(10);
|
||||
circle.setFill(color);
|
||||
return circle;
|
||||
}
|
||||
}
|
||||
30
src/main/java/com/dayrain/style/FormFactory.java
Normal file
30
src/main/java/com/dayrain/style/FormFactory.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package com.dayrain.style;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Control;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.HBox;
|
||||
|
||||
public class FormFactory {
|
||||
|
||||
public static HBox getLine(Label label, Control control, double labelWidth, double nodeWidth, double maxWidth) {
|
||||
HBox hBox = new HBox();
|
||||
label.setPrefWidth(labelWidth);
|
||||
control.setPrefWidth(nodeWidth);
|
||||
hBox.getChildren().addAll(label, control);
|
||||
hBox.setAlignment(Pos.CENTER_LEFT);
|
||||
hBox.setMaxWidth(maxWidth);
|
||||
return hBox;
|
||||
}
|
||||
|
||||
public static HBox getButtonLine(Button button, double labelWidth, double width) {
|
||||
HBox hBox = new HBox();
|
||||
Label label = LabelFactory.getLabel("");
|
||||
label.setPrefWidth(labelWidth);
|
||||
hBox.getChildren().addAll(label, button);
|
||||
hBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
hBox.setMaxWidth(width);
|
||||
return hBox;
|
||||
}
|
||||
}
|
||||
10
src/main/java/com/dayrain/style/IconFactory.java
Normal file
10
src/main/java/com/dayrain/style/IconFactory.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.dayrain.style;
|
||||
|
||||
import javafx.scene.image.Image;
|
||||
|
||||
public class IconFactory {
|
||||
|
||||
public static Image getIcon() {
|
||||
return new Image("panda.png");
|
||||
}
|
||||
}
|
||||
30
src/main/java/com/dayrain/style/StageFactory.java
Normal file
30
src/main/java/com/dayrain/style/StageFactory.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package com.dayrain.style;
|
||||
|
||||
import com.dayrain.views.ViewHolder;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
/**
|
||||
* 窗口
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class StageFactory {
|
||||
|
||||
/**
|
||||
* 获取标准弹窗
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public static Stage getPopStage(String name, Scene scene) {
|
||||
Stage stage = new Stage();
|
||||
stage.setTitle(name);
|
||||
stage.setWidth(700);
|
||||
stage.setHeight(500);
|
||||
stage.initOwner(ViewHolder.getPrimaryStage());
|
||||
stage.initModality(Modality.WINDOW_MODAL);
|
||||
stage.getIcons().addAll(IconFactory.getIcon());
|
||||
stage.setScene(scene);
|
||||
return stage;
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class FileUtils {
|
||||
while ((buf = bufferedReader.readLine()) != null) {
|
||||
configStr.append(buf);
|
||||
}
|
||||
return "".equals(configStr.toString()) ? new Configuration(1200, 800, 8, 8) : new ObjectMapper().readValue(configStr.toString(), Configuration.class);
|
||||
return "".equals(configStr.toString()) ? new Configuration(1400, 800, 8, 8) : new ObjectMapper().readValue(configStr.toString(), Configuration.class);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
@@ -75,7 +75,7 @@ public class FileUtils {
|
||||
public static String getFromInputStream(InputStream inputStream) {
|
||||
try {
|
||||
byte[] buf = new byte[4096];
|
||||
int len = 0;
|
||||
int len;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
while ((len = inputStream.read(buf)) != -1) {
|
||||
stringBuilder.append(new String(buf, 0, len));
|
||||
32
src/main/java/com/dayrain/views/ApplicationStarter.java
Normal file
32
src/main/java/com/dayrain/views/ApplicationStarter.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
/**
|
||||
* 启动入口
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class ApplicationStarter extends Application {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ApplicationStarter.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) {
|
||||
try {
|
||||
ConfigHolder.init();
|
||||
ViewHolder.setPrimaryStage(primaryStage);
|
||||
new HomeView().start();
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
85
src/main/java/com/dayrain/views/HomeView.java
Normal file
85
src/main/java/com/dayrain/views/HomeView.java
Normal file
@@ -0,0 +1,85 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.ConsoleLog;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.component.ServerThreadHolder;
|
||||
import com.dayrain.style.IconFactory;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.SplitPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
/**
|
||||
* 主页
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class HomeView {
|
||||
|
||||
private final Stage primaryStage;
|
||||
|
||||
public HomeView() {
|
||||
this.primaryStage = ViewHolder.getPrimaryStage();
|
||||
}
|
||||
/**
|
||||
* 启动程序
|
||||
*/
|
||||
public void start() {
|
||||
VBox vBox = new VBox();
|
||||
|
||||
//菜单栏
|
||||
MenuBarView menuBar = new MenuBarView();
|
||||
SplitPane splitPane = new SplitPane();
|
||||
//日志
|
||||
LogArea logArea = new LogArea();
|
||||
ConsoleLog.initTextArea(logArea);
|
||||
ViewHolder.setLogArea(logArea);
|
||||
|
||||
//server
|
||||
ServerContainer serverContainer = initServer();
|
||||
ViewHolder.setServerContainer(serverContainer);
|
||||
splitPane.getItems().addAll(serverContainer, logArea);
|
||||
splitPane.setDividerPositions(0.55f, 0.45f);
|
||||
vBox.getChildren().addAll(menuBar, splitPane);
|
||||
|
||||
primaryStage.setTitle(ConfigHolder.get().getProjectName());
|
||||
primaryStage.setScene(new Scene(vBox));
|
||||
primaryStage.setWidth(ConfigHolder.get().getWidth());
|
||||
primaryStage.setHeight(ConfigHolder.get().getHeight());
|
||||
primaryStage.getIcons().add(IconFactory.getIcon());
|
||||
|
||||
primaryStage.show();
|
||||
primaryStage.setOnCloseRequest(event -> {
|
||||
ConfigHolder.save();
|
||||
ServerThreadHolder.stopAll();
|
||||
Platform.exit();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化服务列表
|
||||
* @return 服务的容器
|
||||
*/
|
||||
private ServerContainer initServer() {
|
||||
List<ServerConfig> serverConfigs = ConfigHolder.get().getServerConfigs();
|
||||
List<ServerPane>serverPanes = new ArrayList<>();
|
||||
if(serverConfigs != null) {
|
||||
for (ServerConfig serverConfig : serverConfigs) {
|
||||
ServerPane serverPane = new ServerPane(serverConfig);
|
||||
serverPanes.add(serverPane);
|
||||
}
|
||||
}
|
||||
return new ServerContainer(serverPanes);
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
//停止所有线程
|
||||
ServerThreadHolder.stopAll();
|
||||
start();
|
||||
}
|
||||
}
|
||||
34
src/main/java/com/dayrain/views/LogArea.java
Normal file
34
src/main/java/com/dayrain/views/LogArea.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.text.Font;
|
||||
|
||||
/**
|
||||
* 打印日志的组件
|
||||
* 每个服务都有各自的组件
|
||||
* @author peng
|
||||
* @date 2021/11/8
|
||||
*/
|
||||
public class LogArea extends TextArea {
|
||||
private String serverName;
|
||||
|
||||
public LogArea() {
|
||||
createView();
|
||||
}
|
||||
|
||||
public void createView() {
|
||||
this.setEditable(false);
|
||||
this.setFont(Font.font("Microsoft YaHei", 16));
|
||||
this.setPrefWidth(582);
|
||||
this.setPrefHeight(ConfigHolder.get().getHeight());
|
||||
}
|
||||
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
public void setServerName(String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
}
|
||||
210
src/main/java/com/dayrain/views/MenuBarView.java
Normal file
210
src/main/java/com/dayrain/views/MenuBarView.java
Normal file
@@ -0,0 +1,210 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.Configuration;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.style.BackGroundFactory;
|
||||
import com.dayrain.style.ButtonFactory;
|
||||
import com.dayrain.style.LabelFactory;
|
||||
import com.dayrain.style.StageFactory;
|
||||
import com.dayrain.utils.FileUtils;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.MenuBar;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 菜单栏
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class MenuBarView extends MenuBar {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MenuBarView.class);
|
||||
|
||||
private final Menu menu1 = new Menu("文件");
|
||||
private final Menu menu2 = new Menu("设置");
|
||||
private final Menu menu3 = new Menu("帮助");
|
||||
|
||||
public MenuBarView() {
|
||||
creatView();
|
||||
}
|
||||
|
||||
private void creatView() {
|
||||
MenuItem menuItem11 = new MenuItem("新建");
|
||||
MenuItem menuItem12 = new MenuItem("导入");
|
||||
MenuItem menuItem13 = new MenuItem("导出");
|
||||
menu1.getItems().addAll(menuItem11, menuItem12, menuItem13);
|
||||
menuItem11.setOnAction(this::addServer);
|
||||
menuItem12.setOnAction(this::importConfig);
|
||||
menuItem13.setOnAction(this::exportConfig);
|
||||
|
||||
MenuItem menuItem21 = new MenuItem("随机值长度");
|
||||
menu2.getItems().addAll(menuItem21);
|
||||
menuItem21.setOnAction(this::updateRandomLength);
|
||||
|
||||
MenuItem menuItem31 = new MenuItem("说明书");
|
||||
MenuItem menuItem32 = new MenuItem("源码地址");
|
||||
menu3.getItems().addAll(menuItem31, menuItem32);
|
||||
menuItem31.setOnAction(this::linkIntroduce);
|
||||
menuItem32.setOnAction(this::linkGithub);
|
||||
|
||||
this.setBackground(BackGroundFactory.getBackGround());
|
||||
|
||||
this.getMenus().addAll(menu1, menu2, menu3);
|
||||
}
|
||||
|
||||
public void updateRandomLength(ActionEvent evt) {
|
||||
Configuration configuration = ConfigHolder.get();
|
||||
Label strName = LabelFactory.getLabel("随机字符长度:");
|
||||
strName.setPrefWidth(150);
|
||||
TextField strField = new TextField(String.valueOf(configuration.getStringLen()));
|
||||
Label intName = LabelFactory.getLabel("随机整数长度:");
|
||||
javafx.scene.control.TextField intField = new TextField(String.valueOf(configuration.getIntLen()));
|
||||
intField.setPrefWidth(150);
|
||||
|
||||
HBox btnHBox = new HBox();
|
||||
Label saveTips1 = LabelFactory.getLabel("注: $string$代指随机字符串");
|
||||
Label saveTips2 = LabelFactory.getLabel("$int$代指随机整数");
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
btnHBox.getChildren().addAll(saveButton);
|
||||
btnHBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
btnHBox.setSpacing(20d);
|
||||
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.add(strName, 0, 0);
|
||||
gridPane.add(strField, 1, 0);
|
||||
gridPane.add(intName, 0, 1);
|
||||
gridPane.add(intField, 1, 1);
|
||||
gridPane.add(saveTips1, 0, 3);
|
||||
gridPane.add(saveTips2, 1, 3);
|
||||
|
||||
gridPane.add(btnHBox, 1, 4);
|
||||
gridPane.setAlignment(Pos.CENTER);
|
||||
gridPane.setHgap(20d);
|
||||
gridPane.setVgap(10d);
|
||||
|
||||
Stage stage = StageFactory.getPopStage("更改随机值配置", new Scene(gridPane));
|
||||
stage.show();
|
||||
|
||||
saveButton.setOnAction(event -> {
|
||||
String strLen = strField.getText();
|
||||
String intLen = intField.getText();
|
||||
configuration.setStringLen(Integer.parseInt(strLen));
|
||||
configuration.setIntLen(Integer.parseInt(intLen));
|
||||
ConfigHolder.save();
|
||||
stage.close();
|
||||
});
|
||||
}
|
||||
|
||||
public void exportConfig(ActionEvent evt) {
|
||||
Stage stage = new Stage();
|
||||
stage.initOwner(ViewHolder.getPrimaryStage());
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
String projectName = ConfigHolder.get().getProjectName();
|
||||
if (projectName == null) {
|
||||
projectName = "";
|
||||
}
|
||||
projectName += "server";
|
||||
fileChooser.setTitle("导出配置");
|
||||
fileChooser.setInitialFileName(projectName + ".json");
|
||||
File file = fileChooser.showSaveDialog(stage);
|
||||
if (file != null) {
|
||||
FileUtils.saveConfig(ConfigHolder.get(), file);
|
||||
}
|
||||
}
|
||||
|
||||
private void importConfig(ActionEvent evt) {
|
||||
Stage stage = new Stage();
|
||||
stage.initOwner(ViewHolder.getPrimaryStage());
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("选择一个文件");
|
||||
//过滤器
|
||||
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("只能导入json文件", "*.json"));
|
||||
File file = fileChooser.showOpenDialog(stage);
|
||||
|
||||
if (file != null) {
|
||||
Configuration loadConfig = FileUtils.load(file);
|
||||
ConfigHolder.replace(loadConfig);
|
||||
FileUtils.saveConfig(loadConfig);
|
||||
ConfigHolder.replace(loadConfig);
|
||||
ViewHolder.getHomeView().restart();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加服务
|
||||
*/
|
||||
private void addServer(ActionEvent evt) {
|
||||
Label nameLabel = LabelFactory.getLabel("服务名称:");
|
||||
nameLabel.setPrefWidth(80);
|
||||
javafx.scene.control.TextField nameField = new javafx.scene.control.TextField();
|
||||
javafx.scene.control.Label portLabel = LabelFactory.getLabel("端口号:");
|
||||
javafx.scene.control.TextField portField = new javafx.scene.control.TextField();
|
||||
portField.setPrefWidth(80);
|
||||
|
||||
HBox btnHBox = new HBox();
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
btnHBox.getChildren().add(saveButton);
|
||||
btnHBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.add(nameLabel, 0, 0);
|
||||
gridPane.add(nameField, 1, 0);
|
||||
gridPane.add(portLabel, 0, 1);
|
||||
gridPane.add(portField, 1, 1);
|
||||
gridPane.add(btnHBox, 1, 3);
|
||||
gridPane.setAlignment(Pos.CENTER);
|
||||
gridPane.setHgap(20d);
|
||||
gridPane.setVgap(10d);
|
||||
|
||||
Stage stage = StageFactory.getPopStage("添加服务", new Scene(gridPane));
|
||||
stage.show();
|
||||
|
||||
saveButton.setOnAction(event -> {
|
||||
String name = nameField.getText();
|
||||
String port = portField.getText();
|
||||
ServerConfig serverConfig = new ServerConfig(name, Integer.parseInt(port), new ArrayList<>());
|
||||
ConfigHolder.get().getServerConfigs().add(serverConfig);
|
||||
ViewHolder.getServerContainer().refresh();
|
||||
ConfigHolder.save();
|
||||
stage.close();
|
||||
});
|
||||
}
|
||||
|
||||
private void linkGithub(ActionEvent evt) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(new URI("https://github.com/DayRain/http-server-simulator"));
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
logger.error("跳转到github时发生了错误: {}", e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void linkIntroduce(ActionEvent evt){
|
||||
try {
|
||||
Desktop.getDesktop().browse(new URI("https://blog.csdn.net/qq_37855749/article/details/121030800"));
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
logger.error("跳转到csdn时发生了错误: {}", e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
28
src/main/java/com/dayrain/views/ServerContainer.java
Normal file
28
src/main/java/com/dayrain/views/ServerContainer.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.util.List;
|
||||
/**
|
||||
* server容器
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class ServerContainer extends VBox {
|
||||
|
||||
private List<ServerPane> serverPanes;
|
||||
|
||||
public ServerContainer(List<ServerPane> serverPanes) {
|
||||
this.serverPanes = serverPanes;
|
||||
createView();
|
||||
}
|
||||
|
||||
public void createView() {
|
||||
getChildren().addAll(serverPanes);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
getChildren().removeAll();
|
||||
getChildren().addAll(serverPanes);
|
||||
}
|
||||
}
|
||||
239
src/main/java/com/dayrain/views/ServerPane.java
Normal file
239
src/main/java/com/dayrain/views/ServerPane.java
Normal file
@@ -0,0 +1,239 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.ConsoleLog;
|
||||
import com.dayrain.component.RequestType;
|
||||
import com.dayrain.component.Server;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
|
||||
import com.dayrain.component.ServerThreadHolder;
|
||||
import com.dayrain.component.ServerUrl;
|
||||
import com.dayrain.server.ServerThread;
|
||||
import com.dayrain.style.BackGroundFactory;
|
||||
import com.dayrain.style.ButtonFactory;
|
||||
|
||||
import com.dayrain.style.CircleFactory;
|
||||
import com.dayrain.style.FormFactory;
|
||||
import com.dayrain.style.IconFactory;
|
||||
import com.dayrain.style.LabelFactory;
|
||||
import com.dayrain.style.StageFactory;
|
||||
import com.dayrain.utils.ListViewHelper;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* server容器
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class ServerPane extends TitledPane {
|
||||
|
||||
private final ServerConfig serverConfig;
|
||||
|
||||
private ServerUrlListView serverUrlListView;
|
||||
|
||||
private final Circle statusCircle;
|
||||
private final Button editButton;
|
||||
private final Button openButton;
|
||||
private final Button deleteButton;
|
||||
private final Button addButton;
|
||||
|
||||
public ServerPane(ServerConfig serverConfig) {
|
||||
this.serverConfig = serverConfig;
|
||||
this.statusCircle = CircleFactory.getLightCircle(ServerThreadHolder.contains(serverConfig.getServerName()) ? Color.GREEN : Color.RED);
|
||||
this.editButton = ButtonFactory.getButton("修改配置");
|
||||
this.openButton = ButtonFactory.getButton("开启服务");
|
||||
this.deleteButton = ButtonFactory.getButton("删除服务");
|
||||
this.addButton = ButtonFactory.getButton("添加接口");
|
||||
createView();
|
||||
}
|
||||
|
||||
public void createView() {
|
||||
VBox vBox = new VBox();
|
||||
HBox headBox = new HBox();
|
||||
//设置服务启动与关闭
|
||||
openButton.setOnAction(this::startServer);
|
||||
editButton.setOnAction(this::updateServer);
|
||||
deleteButton.setOnAction(this::deleteSever);
|
||||
headBox.getChildren().addAll(openButton, editButton, deleteButton, addButton, statusCircle);
|
||||
HBox.setMargin(statusCircle, new Insets(0, 0, 0, 30));
|
||||
headBox.setSpacing(20d);
|
||||
headBox.setAlignment(Pos.CENTER);
|
||||
|
||||
//添加url
|
||||
this.serverUrlListView = new ServerUrlListView(serverConfig);
|
||||
addButton.setOnAction(this::addUrl);
|
||||
vBox.getChildren().addAll(headBox, serverUrlListView);
|
||||
|
||||
vBox.setSpacing(10d);
|
||||
VBox.setMargin(headBox, new Insets(10, 0, 0, 0));
|
||||
vBox.setPadding(Insets.EMPTY);
|
||||
setText(serverConfig.getServerName());
|
||||
this.setContent(vBox);
|
||||
this.setFont(Font.font("Microsoft YaHei", 18));
|
||||
this.setPrefWidth(600d);
|
||||
this.setExpanded(false);
|
||||
this.setBackground(BackGroundFactory.getBackGround());
|
||||
this.setOnMouseClicked(event -> {
|
||||
if (!serverConfig.getServerName().equals(ViewHolder.getLogArea().getServerName())) {
|
||||
ConsoleLog.resetTextArea(serverConfig.getServerName());
|
||||
}
|
||||
});
|
||||
|
||||
HBox hBox = new HBox();
|
||||
hBox.setPrefHeight(60d);
|
||||
this.setGraphic(hBox);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动服务
|
||||
*/
|
||||
private void startServer(ActionEvent evt) {
|
||||
String serverName = serverConfig.getServerName();
|
||||
if (ServerThreadHolder.contains(serverName)) {
|
||||
ServerThreadHolder.remove(serverName);
|
||||
openButton.setText("开启服务");
|
||||
statusCircle.setFill(Color.RED);
|
||||
} else {
|
||||
ServerThreadHolder.add(serverName, new ServerThread(new Server(serverConfig)));
|
||||
openButton.setText("关闭服务");
|
||||
statusCircle.setFill(Color.GREEN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新服务
|
||||
*/
|
||||
private void updateServer(ActionEvent evt) {
|
||||
Label serverName = LabelFactory.getLabel("服务名称:");
|
||||
serverName.setPrefWidth(80);
|
||||
TextField nameField = new TextField(serverConfig.getServerName());
|
||||
Label portLabel = LabelFactory.getLabel("端口:");
|
||||
TextField portField = new TextField(String.valueOf(serverConfig.getPort()));
|
||||
portField.setPrefWidth(80);
|
||||
|
||||
HBox btnHBox = new HBox();
|
||||
Label saveTips = LabelFactory.getLabel("重启后生效");
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
btnHBox.getChildren().addAll(saveTips, saveButton);
|
||||
btnHBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
btnHBox.setSpacing(20d);
|
||||
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.add(serverName, 0, 0);
|
||||
gridPane.add(nameField, 1, 0);
|
||||
gridPane.add(portLabel, 0, 1);
|
||||
gridPane.add(portField, 1, 1);
|
||||
|
||||
gridPane.add(btnHBox, 1, 3);
|
||||
gridPane.setAlignment(Pos.CENTER);
|
||||
gridPane.setHgap(20d);
|
||||
gridPane.setVgap(10d);
|
||||
|
||||
Stage stage = StageFactory.getPopStage("更新服务配置", new Scene(gridPane));
|
||||
stage.show();
|
||||
|
||||
saveButton.setOnAction(event -> {
|
||||
String name = nameField.getText();
|
||||
int port = Integer.parseInt(portField.getText());
|
||||
serverConfig.setPort(port);
|
||||
serverConfig.setServerName(name);
|
||||
ConfigHolder.save();
|
||||
stage.close();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除服务
|
||||
*/
|
||||
private void deleteSever(ActionEvent evt) {
|
||||
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||
alert.setGraphic(new ImageView(IconFactory.getIcon()));
|
||||
Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
|
||||
stage.getIcons().add(IconFactory.getIcon());
|
||||
alert.setHeaderText("是否确定删除该服务?");
|
||||
Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK);
|
||||
okButton.setOnAction(event1 -> {
|
||||
ConfigHolder.get().getServerConfigs().remove(serverConfig);
|
||||
ViewHolder.getServerContainer().refresh();
|
||||
ConfigHolder.save();
|
||||
});
|
||||
alert.show();
|
||||
}
|
||||
|
||||
private void addUrl(ActionEvent evt) {
|
||||
VBox vBox = new VBox();
|
||||
|
||||
Label nameLabel = LabelFactory.getLabel("接口名称:");
|
||||
TextField nameField = new TextField();
|
||||
HBox hBox1 = FormFactory.getLine(nameLabel, nameField, 120, 300, 500);
|
||||
|
||||
Label urlLabel = LabelFactory.getLabel("接口地址:");
|
||||
TextField urlField = new TextField();
|
||||
HBox hBox2 = FormFactory.getLine(urlLabel, urlField, 120, 300, 500);
|
||||
|
||||
Label typeLabel = LabelFactory.getLabel("请求方式:");
|
||||
ChoiceBox<String> choiceBox = new ChoiceBox<>();
|
||||
choiceBox.setItems(FXCollections.observableArrayList("POST", "GET"));
|
||||
choiceBox.setValue("POST");
|
||||
HBox hBox3 = FormFactory.getLine(typeLabel, choiceBox, 120, 70, 500);
|
||||
|
||||
Label respLabel = LabelFactory.getLabel("返回结果:");
|
||||
TextArea textArea = new TextArea();
|
||||
HBox hBox4 = FormFactory.getLine(respLabel, textArea, 120, 300, 500);
|
||||
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
HBox hBox5 = FormFactory.getButtonLine(saveButton, 120, 500);
|
||||
|
||||
vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5);
|
||||
vBox.setSpacing(20d);
|
||||
vBox.setAlignment(Pos.CENTER);
|
||||
|
||||
Stage stage = StageFactory.getPopStage("新增接口信息", new Scene(vBox));
|
||||
stage.show();
|
||||
|
||||
saveButton.setOnAction(event1 -> {
|
||||
String name = nameField.getText();
|
||||
List<ServerUrl> serverUrls = serverConfig.getServerUrls();
|
||||
for (ServerUrl serverUrl : serverUrls) {
|
||||
if (serverUrl.getUrlName().equals(name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String url = urlField.getText();
|
||||
String resp = textArea.getText();
|
||||
|
||||
String type = choiceBox.getValue();
|
||||
ServerUrl serverUrl = new ServerUrl(serverConfig.getServerName(), name, url, type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET, resp);
|
||||
serverUrls.add(serverUrl);
|
||||
ServerThreadHolder.addUrl(serverUrl);
|
||||
ListViewHelper.addAndRefresh(serverUrl, serverUrlListView);
|
||||
ConfigHolder.save();
|
||||
stage.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
54
src/main/java/com/dayrain/views/ServerUrlListView.java
Normal file
54
src/main/java/com/dayrain/views/ServerUrlListView.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.component.ServerUrl;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Callback;
|
||||
|
||||
/**
|
||||
* server 列表
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class ServerUrlListView extends ListView<ServerUrl> {
|
||||
|
||||
private ServerConfig serverConfig;
|
||||
|
||||
public ServerUrlListView(ServerConfig serverConfig) {
|
||||
this.serverConfig = serverConfig;
|
||||
createView();
|
||||
}
|
||||
|
||||
private void createView() {
|
||||
ObservableList<ServerUrl> urlList = FXCollections.observableArrayList(serverConfig.getServerUrls());
|
||||
setItems(urlList);
|
||||
this.setCellFactory(new Callback<ListView<ServerUrl>, ListCell<ServerUrl>>() {
|
||||
@Override
|
||||
public ListCell<ServerUrl> call(ListView<ServerUrl> param) {
|
||||
return new ListCell<ServerUrl>() {
|
||||
@Override
|
||||
protected void updateItem(ServerUrl item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (empty || item == null) {
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
} else {
|
||||
ServerUrlPaneView urlPane = new ServerUrlPaneView(item, serverConfig, ServerUrlListView.this);
|
||||
this.setGraphic(urlPane);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
this.prefHeightProperty().bind(Bindings.size(urlList).multiply(60));
|
||||
this.setFocusTraversable(false);
|
||||
}
|
||||
|
||||
}
|
||||
156
src/main/java/com/dayrain/views/ServerUrlPaneView.java
Normal file
156
src/main/java/com/dayrain/views/ServerUrlPaneView.java
Normal file
@@ -0,0 +1,156 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import com.dayrain.component.ConfigHolder;
|
||||
import com.dayrain.component.RequestType;
|
||||
import com.dayrain.component.ServerConfig;
|
||||
import com.dayrain.component.ServerThreadHolder;
|
||||
import com.dayrain.component.ServerUrl;
|
||||
import com.dayrain.style.ButtonFactory;
|
||||
import com.dayrain.style.FormFactory;
|
||||
import com.dayrain.style.IconFactory;
|
||||
import com.dayrain.style.LabelFactory;
|
||||
import com.dayrain.style.StageFactory;
|
||||
import com.dayrain.utils.ListViewHelper;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* url面板
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class ServerUrlPaneView extends BorderPane {
|
||||
private final ServerUrl serverUrl;
|
||||
private final ServerConfig serverConfig;
|
||||
private final ListView<ServerUrl> serverListViews;
|
||||
|
||||
public ServerUrlPaneView(ServerUrl serverUrl, ServerConfig serverConfig, ListView<ServerUrl> serverListViews) {
|
||||
this.serverUrl = serverUrl;
|
||||
this.serverConfig = serverConfig;
|
||||
this.serverListViews = serverListViews;
|
||||
createView();
|
||||
}
|
||||
|
||||
public void createView() {
|
||||
HBox labelBox = new HBox();
|
||||
Label nameLabel = LabelFactory.getLabel(serverUrl.getUrlName());
|
||||
nameLabel.setPrefWidth(180d);
|
||||
nameLabel.setMaxWidth(180d);
|
||||
|
||||
|
||||
Label typeLabel = LabelFactory.getLabel(serverUrl.getRequestType().name());
|
||||
typeLabel.setPrefWidth(65d);
|
||||
|
||||
Label urlLabel = LabelFactory.getLabel(serverUrl.getUrl());
|
||||
urlLabel.setMaxWidth(220d);
|
||||
labelBox.getChildren().addAll(nameLabel, typeLabel, urlLabel);
|
||||
labelBox.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
HBox btnBox = new HBox();
|
||||
Button configButton = ButtonFactory.getButton("配置");
|
||||
Button deleteButton = ButtonFactory.getButton("删除");
|
||||
btnBox.setSpacing(10d);
|
||||
btnBox.getChildren().addAll(configButton, deleteButton);
|
||||
HBox.setMargin(deleteButton, new Insets(0, 5, 0, 0));
|
||||
|
||||
deleteButton.setOnAction(this::deleteUrl);
|
||||
configButton.setOnAction(this::updateUrl);
|
||||
|
||||
this.setLeft(labelBox);
|
||||
this.setRight(btnBox);
|
||||
}
|
||||
|
||||
|
||||
private void deleteUrl(ActionEvent event) {
|
||||
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||
alert.setGraphic(new ImageView(IconFactory.getIcon()));
|
||||
Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
|
||||
stage.getIcons().add(IconFactory.getIcon());
|
||||
alert.setHeaderText("是否确定删除该接口?");
|
||||
Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK);
|
||||
okButton.setOnAction(event1 -> {
|
||||
List<ServerUrl> serverUrls = serverConfig.getServerUrls();
|
||||
serverUrls.remove(serverUrl);
|
||||
ConfigHolder.save();
|
||||
ListViewHelper.deleteAndRefresh(serverUrl, serverListViews);
|
||||
});
|
||||
alert.show();
|
||||
}
|
||||
|
||||
private void updateUrl(ActionEvent event) {
|
||||
VBox vBox = new VBox();
|
||||
|
||||
Label nameLabel = LabelFactory.getLabel("接口名称:");
|
||||
TextField nameField = new TextField(serverUrl.getUrlName());
|
||||
HBox hBox1 = FormFactory.getLine(nameLabel, nameField, 120, 300, 500);
|
||||
|
||||
Label urlLabel = LabelFactory.getLabel("接口地址:");
|
||||
TextField urlField = new TextField(serverUrl.getUrl());
|
||||
HBox hBox2 = FormFactory.getLine(urlLabel, urlField, 120, 300, 500);
|
||||
|
||||
Label typeLabel = LabelFactory.getLabel("请求方式:");
|
||||
ChoiceBox<String> choiceBox = new ChoiceBox<>();
|
||||
choiceBox.setItems(FXCollections.observableArrayList("POST", "GET"));
|
||||
choiceBox.setValue(serverUrl.getRequestType().name());
|
||||
HBox hBox3 = FormFactory.getLine(typeLabel, choiceBox, 120, 70, 500);
|
||||
|
||||
Label respLabel = LabelFactory.getLabel("返回结果:");
|
||||
TextArea textArea = new TextArea(serverUrl.getResponseBody());
|
||||
HBox hBox4 = FormFactory.getLine(respLabel, textArea, 120, 300, 500);
|
||||
|
||||
Button saveButton = ButtonFactory.getButton("保存");
|
||||
HBox hBox5 = FormFactory.getButtonLine(saveButton, 120, 500);
|
||||
|
||||
vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5);
|
||||
vBox.setSpacing(20d);
|
||||
vBox.setAlignment(Pos.CENTER);
|
||||
|
||||
Stage stage = StageFactory.getPopStage("更新接口信息", new Scene(vBox));
|
||||
stage.show();
|
||||
|
||||
|
||||
saveButton.setOnAction(event1 -> {
|
||||
String name = nameField.getText();
|
||||
String url = urlField.getText();
|
||||
String resp = textArea.getText();
|
||||
String type = choiceBox.getValue();
|
||||
if(url == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!url.startsWith("/")) {
|
||||
url = "/" + url;
|
||||
}
|
||||
String beforeUrl = serverUrl.getUrl();
|
||||
serverUrl.setUrlName(name);
|
||||
serverUrl.setUrl(url);
|
||||
serverUrl.setResponseBody(resp);
|
||||
serverUrl.setRequestType(type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET);
|
||||
ListViewHelper.refresh(serverListViews);
|
||||
ConfigHolder.save();
|
||||
|
||||
ServerThreadHolder.replaceUrl(serverUrl.getServerName(), beforeUrl, serverUrl);
|
||||
stage.close();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
50
src/main/java/com/dayrain/views/ViewHolder.java
Normal file
50
src/main/java/com/dayrain/views/ViewHolder.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.dayrain.views;
|
||||
|
||||
import javafx.stage.Stage;
|
||||
/**
|
||||
* 主要视图的句柄
|
||||
* @author peng
|
||||
* @date 2021/11/11
|
||||
*/
|
||||
public class ViewHolder {
|
||||
|
||||
private static Stage primaryStage;
|
||||
|
||||
private static LogArea logArea;
|
||||
|
||||
private static ServerContainer serverContainer;
|
||||
|
||||
private static HomeView homeView;
|
||||
|
||||
static void setPrimaryStage(Stage primaryStage) {
|
||||
ViewHolder.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
public static Stage getPrimaryStage() {
|
||||
return primaryStage;
|
||||
}
|
||||
|
||||
static void setLogArea(LogArea logArea) {
|
||||
ViewHolder.logArea = logArea;
|
||||
}
|
||||
|
||||
public static LogArea getLogArea() {
|
||||
return logArea;
|
||||
}
|
||||
|
||||
public static ServerContainer getServerContainer() {
|
||||
return serverContainer;
|
||||
}
|
||||
|
||||
static void setServerContainer(ServerContainer serverContainer) {
|
||||
ViewHolder.serverContainer = serverContainer;
|
||||
}
|
||||
|
||||
static void setHomePage(HomeView homeView) {
|
||||
ViewHolder.homeView = homeView;
|
||||
}
|
||||
|
||||
public static HomeView getHomeView() {
|
||||
return ViewHolder.homeView;
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
33
src/main/resources/logback.xml
Normal file
33
src/main/resources/logback.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration debug="false">
|
||||
<property name="LOG_HOME" value="./logs" />
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="STDOUT"
|
||||
class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder
|
||||
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="errorFile"
|
||||
class="ch.qos.logback.core.FileAppender">
|
||||
<file>${LOG_HOME}/error.log</file>
|
||||
<encoder
|
||||
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<logger name="com.dayrain" level="ERROR" additivity="false">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="errorFile" />
|
||||
</logger>
|
||||
</configuration>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Reference in New Issue
Block a user