修复textArea刷新时的bug

This commit is contained in:
peng
2021-12-04 15:22:57 +08:00
parent db2341a23d
commit 6e4f8ac710
18 changed files with 269 additions and 129 deletions

View File

@@ -4,5 +4,69 @@
"height" : 800,
"stringLen" : 8,
"intLen" : 8,
"serverConfigs" : null
"serverConfigs" : [ {
"serverName" : "天津众华-唯智WMS",
"port" : 8081,
"serverUrls" : [ {
"urlName" : "上报入库订单完成信息",
"url" : "/wz/accept/report",
"serverName" : "天津众华-唯智WMS",
"requestType" : "POST",
"responseBody" : "{\n\t\"status\": 1,\n\t\"statusMsg\": \"success\"\n}",
"hiddenLog" : false,
"headerMap" : null
}, {
"urlName" : "出库任务完成上报",
"url" : "/wz/order/report",
"serverName" : "天津众华-唯智WMS",
"requestType" : "POST",
"responseBody" : "{\n\t\"status\": 1,\n\t\"statusMsg\": \"success\"\n}",
"hiddenLog" : false,
"headerMap" : null
}, {
"urlName" : "上传盘点结果",
"url" : "/wz/invent/resp",
"serverName" : "天津众华-唯智WMS",
"requestType" : "POST",
"responseBody" : "{\n\t\"status\": 1,\n\t\"statusMsg\": \"success\"\n}",
"hiddenLog" : false,
"headerMap" : null
}, {
"urlName" : "库存同步",
"url" : "/wz/stock/sync",
"serverName" : "天津众华-唯智WMS",
"requestType" : "POST",
"responseBody" : "{\n\t\"status\": 1,\n\t\"statusMsg\": \"success\"\n}",
"hiddenLog" : false,
"headerMap" : null
} ]
}, {
"serverName" : "天津众华-AIOT",
"port" : 8000,
"serverUrls" : [ {
"urlName" : "查询状态",
"url" : "/aiot/task/info",
"serverName" : "天津众华-AIOT",
"requestType" : "POST",
"responseBody" : "{\n \"msg\": \"ok\",\n \"code\": 0,\n \"status\": 3\n}",
"hiddenLog" : true,
"headerMap" : null
}, {
"urlName" : "派发任务",
"url" : "/aiot/task/add",
"serverName" : "天津众华-AIOT",
"requestType" : "POST",
"responseBody" : "{\n \"msg\": \"ok\",\n \"code\": 0,\n \"data\": \"$int$\"\n}",
"hiddenLog" : false,
"headerMap" : null
}, {
"urlName" : "查询区域内设备状态",
"url" : "/tjzh/area/device/status",
"serverName" : "天津众华-AIOT",
"requestType" : "POST",
"responseBody" : "[\n {\n \"areaId\": 1,\n \"valid\": true\n },\n {\n \"areaId\": 2,\n \"valid\": true\n },\n {\n \"areaId\": 3,\n \"valid\": true\n },\n {\n \"areaId\": 4,\n \"valid\": true\n },\n {\n \"areaId\": 10,\n \"valid\": true\n },\n {\n \"areaId\": 11,\n \"valid\": true\n },\n {\n \"areaId\": 20,\n \"valid\": true\n },\n {\n \"areaId\": 21,\n \"valid\": true\n }\n]",
"hiddenLog" : false,
"headerMap" : null
} ]
} ]
}

View File

@@ -6,7 +6,7 @@
<groupId>com.dayrain</groupId>
<artifactId>http-server-simulator</artifactId>
<version>1.4</version>
<version>1.5</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>

View File

@@ -0,0 +1,9 @@
package com.dayrain;
/**
* 版本信息
* @author peng
* @date 2021/12/1
*/
public class Version {
public static final String VERSION_NAME = "HTTP SERVER 模拟器 V1.5";
}

View File

@@ -1,5 +1,6 @@
package com.dayrain.component;
import java.util.ArrayList;
import java.util.List;
/**
* 配置文件
@@ -8,7 +9,7 @@ import java.util.List;
*/
public class Configuration {
private String projectName = "HTTP SERVER 模拟器 V1.4";
private String projectName;
private int width;
@@ -39,6 +40,9 @@ public class Configuration {
}
public List<ServerConfig> getServerConfigs() {
if(serverConfigs == null) {
serverConfigs = new ArrayList<>();
}
return serverConfigs;
}

View File

@@ -1,79 +0,0 @@
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<>();
private static final String NO_REQUEST = "暂无请求";
private static LogArea logArea;
public static void initTextArea(LogArea area) {
logArea = area;
}
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 = "";
}
if (params == null || "".equals(params)) {
params = "";
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[").append(now()).append("]");
stringBuilder.append(serverUrl.getUrlName()).append(" ");
stringBuilder.append(serverUrl.getUrl()).append(" ").append(serverUrl.getRequestType().name()).append("\n");
stringBuilder.append("参数: ").append("\n");
stringBuilder.append(params).append("\n");
stringBuilder.append("返回值: ").append("\n");
stringBuilder.append(resp);
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 synchronized static void resetTextArea(String serverName) {
if (!logs.containsKey(serverName)) {
logs.put(serverName, NO_REQUEST);
}
logArea.setServerName(serverName);
logArea.setText(logs.get(serverName));
logArea.appendText("");
logArea.setScrollTop(Double.MAX_VALUE);
}
private static String now() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-DD-mm HH:mm:ss");
return simpleDateFormat.format(new Date());
}
}

View File

@@ -1,12 +1,15 @@
package com.dayrain.component;
import com.dayrain.utils.FileUtils;
import com.dayrain.views.ViewHolder;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.UUID;
/**
* 请求处理
@@ -39,7 +42,7 @@ public class RequestHandler implements HttpHandler {
String resp = replaceResp(serverUrl.getResponseBody());
ConsoleLog.log(serverUrl, param, resp);
ViewHolder.log(serverUrl, param, resp);
response(exchange, resp);
}
@@ -55,8 +58,8 @@ public class RequestHandler implements HttpHandler {
private void response(HttpExchange exchange, String jsonBody) {
try {
byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8);
exchange.getResponseHeaders().add("Content-Type", "application/json; charset=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));
outputStream.close();

View File

@@ -52,13 +52,6 @@ public class ServerThreadHolder {
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);

View File

@@ -28,6 +28,10 @@ public class ServerUrl {
* 响应体
*/
private String responseBody;
/**
* 是否隐藏日志
*/
private boolean hiddenLog;
/**
* 请求头
*/
@@ -91,4 +95,12 @@ public class ServerUrl {
public void setServerName(String serverName) {
this.serverName = serverName;
}
public boolean isHiddenLog() {
return hiddenLog;
}
public void setHiddenLog(boolean hiddenLog) {
this.hiddenLog = hiddenLog;
}
}

View File

@@ -16,10 +16,6 @@ public class ServerThread extends Thread {
server.stop();
}
public void restartServer() {
server.restart();
}
public void addContext(ServerUrl serverUrl) {
server.addContext(serverUrl);
}

View File

@@ -21,4 +21,5 @@ public class ListViewHelper {
serverUrls.setItems(null);
serverUrls.setItems(items);
}
}

View File

@@ -23,7 +23,9 @@ public class ApplicationStarter extends Application {
try {
ConfigHolder.init();
ViewHolder.setPrimaryStage(primaryStage);
new HomeView().start();
HomeView homeView = new HomeView();
ViewHolder.setHomePage(homeView);
homeView.start();
}catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());

View File

@@ -1,13 +1,11 @@
package com.dayrain.views;
import com.dayrain.Version;
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;
@@ -37,9 +35,7 @@ public class HomeView {
SplitPane splitPane = new SplitPane();
//日志
LogArea logArea = new LogArea();
ConsoleLog.initTextArea(logArea);
ViewHolder.setLogArea(logArea);
//server
ServerContainer serverContainer = initServer();
ViewHolder.setServerContainer(serverContainer);
@@ -47,7 +43,7 @@ public class HomeView {
splitPane.setDividerPositions(0.55f, 0.45f);
vBox.getChildren().addAll(menuBar, splitPane);
primaryStage.setTitle(ConfigHolder.get().getProjectName());
primaryStage.setTitle(Version.VERSION_NAME);
primaryStage.setScene(new Scene(vBox));
primaryStage.setWidth(ConfigHolder.get().getWidth());
primaryStage.setHeight(ConfigHolder.get().getHeight());
@@ -58,6 +54,7 @@ public class HomeView {
ConfigHolder.save();
ServerThreadHolder.stopAll();
Platform.exit();
System.exit(0);
});
}

View File

@@ -1,9 +1,20 @@
package com.dayrain.views;
import com.dayrain.component.ConfigHolder;
import com.dayrain.component.ServerUrl;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextArea;
import javafx.scene.text.Font;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
/**
* 打印日志的组件
* 每个服务都有各自的组件
@@ -11,7 +22,53 @@ import javafx.scene.text.Font;
* @date 2021/11/8
*/
public class LogArea extends TextArea {
private String serverName;
private static final ConcurrentHashMap<String, String> LOG_MAP = new ConcurrentHashMap<>();
private static final int LOG_LENGTH = 5000;
private ContextMenu contextMenu;
private MenuItem clearMenu;
/**
* 当前服务名
*/
private String currentServerName;
public synchronized void log(ServerUrl serverUrl, String params, String resp) {
if(serverUrl.isHiddenLog()) {
return;
}
String str = "[" + now() + "]" +
serverUrl.getUrlName() + " " +
serverUrl.getUrl() + " " + serverUrl.getRequestType().name() + "\n" +
"参数: " + "\n" +
params + "\n" +
"返回值: " + "\n" +
resp +
"\n\n";
logAppend(serverUrl.getServerName(), str);
refresh();
}
public void logAppend(String serverName, String logContent) {
String log = LOG_MAP.getOrDefault(serverName, null);
if(log == null) {
LOG_MAP.put(serverName, logContent);
return;
}
log += logContent;
if(log.length() > LOG_LENGTH) {
log = log.substring(log.length() - LOG_LENGTH);
}
LOG_MAP.put(serverName, log);
}
public LogArea() {
createView();
@@ -22,13 +79,39 @@ public class LogArea extends TextArea {
this.setFont(Font.font("Microsoft YaHei", 16));
this.setPrefWidth(582);
this.setPrefHeight(ConfigHolder.get().getHeight());
clearMenu = new MenuItem("清空");
contextMenu = new ContextMenu();
contextMenu.getItems().addAll(clearMenu);
this.setContextMenu(contextMenu);
clearMenu.setOnAction(event -> {
clear();
});
}
public String getServerName() {
return serverName;
public String getCurrentServerName() {
return currentServerName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
public synchronized void setCurrentServerName(String currentServerName) {
this.currentServerName = currentServerName;
}
private static String now() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-DD-mm HH:mm:ss");
return simpleDateFormat.format(new Date());
}
public void refresh() {
if(currentServerName == null) {
//拒绝刷新
return;
}
Platform.runLater(()->{
setText("");
appendText(LOG_MAP.getOrDefault(currentServerName, ""));
setScrollTop(Double.MAX_VALUE);
});
}
}

View File

@@ -1,5 +1,6 @@
package com.dayrain.views;
import com.dayrain.Version;
import com.dayrain.component.ConfigHolder;
import com.dayrain.component.Configuration;
import com.dayrain.component.ServerConfig;
@@ -30,6 +31,7 @@ import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
/**
* 菜单栏
@@ -119,11 +121,15 @@ public class MenuBarView extends MenuBar {
Stage stage = new Stage();
stage.initOwner(ViewHolder.getPrimaryStage());
FileChooser fileChooser = new FileChooser();
String projectName = ConfigHolder.get().getProjectName();
if (projectName == null) {
projectName = "";
String projectName = Version.VERSION_NAME;
Configuration configuration = ConfigHolder.get();
List<ServerConfig> serverConfigs = configuration.getServerConfigs();
if(serverConfigs != null && serverConfigs.size()>1) {
String serverName = serverConfigs.get(0).getServerName();
if(serverName != null && !"".equals(serverName.trim())) {
projectName = serverName;
}
}
projectName += "server";
fileChooser.setTitle("导出配置");
fileChooser.setInitialFileName(projectName + ".json");
File file = fileChooser.showSaveDialog(stage);
@@ -184,7 +190,7 @@ public class MenuBarView extends MenuBar {
String port = portField.getText();
ServerConfig serverConfig = new ServerConfig(name, Integer.parseInt(port), new ArrayList<>());
ConfigHolder.get().getServerConfigs().add(serverConfig);
ViewHolder.getServerContainer().refresh();
ViewHolder.getServerContainer().addServer(serverConfig);
ConfigHolder.save();
stage.close();
});

View File

@@ -1,5 +1,6 @@
package com.dayrain.views;
import com.dayrain.component.ServerConfig;
import javafx.scene.layout.VBox;
import java.util.List;
@@ -10,7 +11,7 @@ import java.util.List;
*/
public class ServerContainer extends VBox {
private List<ServerPane> serverPanes;
private final List<ServerPane> serverPanes;
public ServerContainer(List<ServerPane> serverPanes) {
this.serverPanes = serverPanes;
@@ -22,7 +23,20 @@ public class ServerContainer extends VBox {
}
public void refresh() {
getChildren().removeAll();
getChildren().clear();
getChildren().addAll(serverPanes);
}
public synchronized void addServer(ServerConfig serverConfig) {
serverPanes.add(new ServerPane(serverConfig));
refresh();
}
public synchronized void removeServer(ServerConfig serverConfig) {
if(serverConfig == null) {
return;
}
serverPanes.removeIf(serverPane -> serverConfig.getServerName().equals(serverPane.getServerConfig().getServerName()));
refresh();
}
}

View File

@@ -1,7 +1,6 @@
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;
@@ -21,7 +20,6 @@ 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;
@@ -40,7 +38,6 @@ 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;
@@ -99,8 +96,9 @@ public class ServerPane extends TitledPane {
this.setExpanded(false);
this.setBackground(BackGroundFactory.getBackGround());
this.setOnMouseClicked(event -> {
if (!serverConfig.getServerName().equals(ViewHolder.getLogArea().getServerName())) {
ConsoleLog.resetTextArea(serverConfig.getServerName());
if (!serverConfig.getServerName().equals(ViewHolder.getLogArea().getCurrentServerName())) {
ViewHolder.setLogOwner(serverConfig.getServerName());
ViewHolder.refreshLog();
}
});
@@ -178,8 +176,12 @@ public class ServerPane extends TitledPane {
alert.setHeaderText("是否确定删除该服务?");
Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK);
okButton.setOnAction(event1 -> {
//从配置文件中移除
ConfigHolder.get().getServerConfigs().remove(serverConfig);
ViewHolder.getServerContainer().refresh();
//从视图中移除
ViewHolder.getServerContainer().removeServer(serverConfig);
//如果当前线程未关闭,则关闭
ServerThreadHolder.remove(serverConfig.getServerName());
ConfigHolder.save();
});
alert.show();
@@ -202,14 +204,20 @@ public class ServerPane extends TitledPane {
choiceBox.setValue("POST");
HBox hBox3 = FormFactory.getLine(typeLabel, choiceBox, 120, 70, 500);
Label logLabel = LabelFactory.getLabel("日志记录:");
ChoiceBox<String> choiceBox2 = new ChoiceBox<>();
choiceBox2.setItems(FXCollections.observableArrayList("显示", "隐藏"));
choiceBox2.setValue("显示");
HBox hBox4 = FormFactory.getLine(logLabel, choiceBox2, 120, 70, 500);
Label respLabel = LabelFactory.getLabel("返回结果:");
TextArea textArea = new TextArea();
HBox hBox4 = FormFactory.getLine(respLabel, textArea, 120, 300, 500);
HBox hBox5 = FormFactory.getLine(respLabel, textArea, 120, 300, 500);
Button saveButton = ButtonFactory.getButton("保存");
HBox hBox5 = FormFactory.getButtonLine(saveButton, 120, 500);
HBox hBox6 = FormFactory.getButtonLine(saveButton, 120, 500);
vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5);
vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5, hBox6);
vBox.setSpacing(20d);
vBox.setAlignment(Pos.CENTER);
@@ -226,9 +234,10 @@ public class ServerPane extends TitledPane {
}
String url = urlField.getText();
String resp = textArea.getText();
String type = choiceBox.getValue();
String hidLog = choiceBox.getValue();
ServerUrl serverUrl = new ServerUrl(serverConfig.getServerName(), name, url, type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET, resp);
serverUrl.setHiddenLog("隐藏".equals(hidLog));
serverUrls.add(serverUrl);
ServerThreadHolder.addUrl(serverUrl);
ListViewHelper.addAndRefresh(serverUrl, serverUrlListView);
@@ -236,4 +245,8 @@ public class ServerPane extends TitledPane {
stage.close();
});
}
public ServerConfig getServerConfig() {
return serverConfig;
}
}

View File

@@ -113,26 +113,32 @@ public class ServerUrlPaneView extends BorderPane {
choiceBox.setValue(serverUrl.getRequestType().name());
HBox hBox3 = FormFactory.getLine(typeLabel, choiceBox, 120, 70, 500);
Label logLabel = LabelFactory.getLabel("日志记录:");
ChoiceBox<String> choiceBox2 = new ChoiceBox<>();
choiceBox2.setItems(FXCollections.observableArrayList("显示", "隐藏"));
choiceBox2.setValue(serverUrl.isHiddenLog() ? "隐藏" : "显示");
HBox hBox4 = FormFactory.getLine(logLabel, choiceBox2, 120, 70, 500);
Label respLabel = LabelFactory.getLabel("返回结果:");
TextArea textArea = new TextArea(serverUrl.getResponseBody());
HBox hBox4 = FormFactory.getLine(respLabel, textArea, 120, 300, 500);
HBox hBox5 = FormFactory.getLine(respLabel, textArea, 120, 300, 500);
Button saveButton = ButtonFactory.getButton("保存");
HBox hBox5 = FormFactory.getButtonLine(saveButton, 120, 500);
HBox hBox6 = FormFactory.getButtonLine(saveButton, 120, 500);
vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5);
vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5, hBox6);
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();
String hidLog = choiceBox2.getValue();
if(url == null) {
return;
}
@@ -144,6 +150,7 @@ public class ServerUrlPaneView extends BorderPane {
serverUrl.setUrlName(name);
serverUrl.setUrl(url);
serverUrl.setResponseBody(resp);
serverUrl.setHiddenLog("隐藏".equals(hidLog));
serverUrl.setRequestType(type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET);
ListViewHelper.refresh(serverListViews);
ConfigHolder.save();

View File

@@ -1,5 +1,6 @@
package com.dayrain.views;
import com.dayrain.component.ServerUrl;
import javafx.stage.Stage;
/**
* 主要视图的句柄
@@ -28,7 +29,7 @@ public class ViewHolder {
ViewHolder.logArea = logArea;
}
public static LogArea getLogArea() {
public synchronized static LogArea getLogArea() {
return logArea;
}
@@ -47,4 +48,18 @@ public class ViewHolder {
public static HomeView getHomeView() {
return ViewHolder.homeView;
}
public static void log(ServerUrl serverUrl, String params, String resp) {
if(logArea != null) {
logArea.log(serverUrl, params, resp);
}
}
public static void refreshLog() {
logArea.refresh();
}
public static void setLogOwner(String serverName) {
logArea.setCurrentServerName(serverName);
}
}