我最近继承了一些遗留代码,这些代码大量使用内部类来实现线程。这些内部类使当前的JFrame
代码单片化,因此我正在重新分解代码以便使用SwingWorker
类。
我的SwingWorker
类对Web服务进行了大量的API调用,然后返回结果。由于这是异步的,这显然最好在线程内完成。目前,webservice的工作方式需要一些身份验证调用来验证请求。这些调用显然可以返回错误。我想要做的是,如果这些webservice调用未进行身份验证,则从SwingWorker
内抛出自定义异常。使用标准Future
模式,我有类似于以下内容的代码:
SwingWorker(后台主题)
@Override
protected String doInBackground() throws Exception {
if (!authenticationClient.authenticate(userid)) {
throw new PlaceOrderException("Failed to authenticate client");
}
return orderClient.placeOrder( ... );
}
主GUI(EDT主题)
// On the EDT
PlaceOrderWorker placeOrderWorker = new PlaceOrderWorker( ... ) {
// This method is invoked when the worker is finished its task
@Override
protected void done(){
try {
String orderID = get();
// Update some GUI elements using the orderID
} catch(PlaceOrderException e) {
JOptionPane.showMessageDialog(this, "Please review your order", e.getMessage(), JOptionPane.ERROR_MESSAGE, null);
} catch (Exception e) {
LOGGER.error("Error placing order", e);
}
}
}
错误发生在该行:
catch(PlaceOrderException e) {
JOptionPane.showMessageDialog(this, "Please review your order", e.getMessage(), JOptionPane.ERROR_MESSAGE, null);
}
因为Java声称从未抛出此异常。
exception PlaceOrderException is never thrown in body of corresponding try statement
现在我知道调用get
将导致从线程中重新抛出异常 - 它可以抛出PlaceOrderException
。我怎样才能抓住这个特定的例外?我将代码结构化的原因是,后台线程中可以抛出许多异常,我希望通过JDialog
提示用户。我在主GUI类中声明done
方法的原因是我需要在EDT线程中实例化JDialog
s。这让我有了一些很好的解耦。
有人知道使用instanceof
捕获此特定异常的方法吗?或者你能建议一个更好的模式使用吗?也许SwingWorker
是错误的选择?
答案 0 :(得分:6)
抓住ExecutionException
,然后调查其原因:
try {
String orderID = get();
// Update some GUI elements using the orderID
} catch(ExecutionException e) {
Throwable cause = e.getCause( );
if ( cause instanceof PlaceOrderException )
{
JOptionPane.showMessageDialog(
this,
"Please review your order",
cause.getMessage(),
JOptionPane.ERROR_MESSAGE,
null
);
}
else
{
LOGGER.error("Error placing order", e);
}
} catch (Exception e) {
LOGGER.error("Error placing order", e);
}