![](/img/trans.png)
[英]Java Spring Async Exception Handling for methods with non void return value
[英]Async IO handling in Spring CLI with Java how to?
我已經構建了一個Spring CLI應用程序,該應用程序以異步方式與服務器通信。 服務器是給定的,我沒有創建它,基本上我的應用程序需要打開TCP套接字並通過它發送JSON,然后將它發送回JSON。 強制不使用CLI參數,而是在請求的回調中,我想向用戶顯示一組選項,他需要通過在CLI上插入相應的編號來選擇該選項。 很有可能我沒有做正確的事情,因為輸入命令后,我在控制台上看到spring>
(這是預期的行為),除非我按一下(否則當我未打印任何內容時,它將阻塞異步回調)除非我按了許多回車鍵,否則接收回調,這是意外的)。 到目前為止,要從控制台讀取信息,我使用了JLine的命令行,我想實現的是,當我從服務器獲取響應並提供回調時,會將控制台分配給運行回調的線程(我即時將回調的內容打印到控制台,並且我能夠輕松讀取輸入內容)。
一些代碼:
public void runReceiver(){
receiverThread = new Thread(() -> {
byte[] digit = null;
int nb;
Iterator<CommandListener> it;
CommandListener listener;
String message;
List<CommandListener> listenersToRemove = new ArrayList<>();
while (true) {
try {
nb = communicatorInput.readInt();
digit = new byte[nb];
communicatorInput.readFully(digit);
} catch (IOException e) {
e.printStackTrace();
}
it = listeners.iterator();
while (it.hasNext()){
listener = it.next();
if (digit != null && digit.length > 0) {
message = new String(digit);
// the message was not acknowledged
if(message.contains("NACK")){
try {
listener.onError(message);
if (listener.isDone()) {
listenersToRemove.add(listener);
}
} catch (Exception e){
e.printStackTrace();
}
} else try {
listener.onCompleted(message);
} catch (InvalidObjectException e){
Main.logger.debug(String.format("Response could not be parsed as %s", listener.getCommandType()));
} catch (Exception e){
e.printStackTrace();
}
if (listener.isDone()) {
listenersToRemove.add(listener);
}
}
}
listeners.removeAll(listenersToRemove);
}
}, "receiverThread");
receiverThread.setDaemon(true);
receiverThread.start();
然后是一個CLI命令(它在這里期望沒有輸入):
@CliCommand(value="start", help = "Starts stuff")
public void start() throws IOException, InterruptedException {
// this method is passed to the thread with the listener
getAvailabilities().updateAvailabilities("all", "all", "all", someListener);
}
以及該偵聽器的回調:
someListener = new CommandListener() {
private String source = "Start some listener";
@Override
public void onCompleted(String r) throws IOException {
System.out.println("Which would you like to start?");
getAvailabilities().printAvailableBrands();
String brandNumber = "";
while(Objects.equals(brandNumber, "")){
System.out.println("Please enter the number of the Brand: ");
//when the callback arrives here I still only see ">spring:" and I get nothing printed on the console
brandNumber = cr.readLine();
if(!isInputAllowed(brandNumber, getAvailabilities().AvailableBrands.size())){
brandNumber = "";
}
}
BrandName = getAvailabilities().AvailableBrands.get(Integer.parseInt(brandNumber) - 1);
//updating the availabilities narrows down the things I list to the console, so I send an update after every selection
getAvailabilities().updateAvailabilities("all", BrandName, "all", getInterfaceListener);
done = true;
}
這可能會與有時在Idea中調試CLI時輸入錯誤的輸入有關。 當我插入start
它說No such command as ar
,如果再次按回車,它將說(其中的一部分)其余部分: No such command as stt
。
問題在這里:
if (listener.isDone()) {
listenersToRemove.add(listener);
}
如果希望異步執行偵聽器,則不應立即在同一線程上檢查偵聽器的完成,因為它很可能會返回false。
您可能遇到的問題是,偵聽器安排了一些任務,但沒有時間完成任務,因為您在循環后立即將其刪除:
listeners.removeAll(listenersToRemove);
很難說出您的邏輯是什么,但是我想在接下來的迭代中您的列表為空。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.