我有一个自定义模型(延伸的检票口标准模型类)的成分。 我的模型从数据库/ Web服务加载数据时,检票调用getObject()
此查找失败的几个原因。 我想通过该组件的网页上显示一个友好的信息来处理这个错误。 什么是做到这一点的最好方法是什么?
public class MyCustomModel extends Model {
@Override
public String getObject() {
try {
return Order.lookupOrderDataFromRemoteService();
} catch (Exception e) {
logger.error("Failed silently...");
// How do I propagate this to the component/page?
}
return null;
}
请注意,这是从成分分离模型内发生的错误。
您的模型可以实现IComponentAssignedModel,从而能够获得持有所属组件上。
但我不知道多久,你能重用MyCustomModel? 我知道有些开发者主张(在单独的包通常)创建独立的模型实现。 虽然有一般情况下,这是非常有用的(如FeedbackMessagesModel),在我的经验,其容易只是创建内部类是哪些具体成分。
处理,在模型的getObject发生(异常)是棘手的,因为这个时候,我们通常是深藏在整个请求周期的响应阶段,这是为时已晚改变组件层次。 因此,处理异常的地方是非常多的非本地,没有在任何地方你的组件或模型附近,但在RequestCycle
。
周围有,虽然方式。 我们使用的组合Behavior
和IRequestCycleListener
处理这个:
IRequestCycleListener#onException
允许你检查这是在请求期间抛出的任何异常。 如果返回IRequestHandler
此方法,该处理程序将运行并呈现,而不是事先被回事任何其他。
我们使用这个对自己赶上像Hibernate的通用东西StaleObjectException
将用户重定向到一个通用的“他人修改你的对象”页面。 如果你
对于更具体的情况下,我们增加一个RuntimeExceptionHandler
行为:
public abstract class RuntimeExceptionHandler extends Behavior { public abstract IRequestHandler handleRuntimeException(Component component, Exception ex); }
在IRequestCycleListener
我们走过当前页面的组件树看到任何部件是否有实例RuntimeExceptionHandler
。 如果我们发现一个,我们称之为其handleRuntimeException
方法,如果它返回一个IRequestHandler
这就是我们将使用一个。 这样你可以有错误地方到你的页面的实际操作。
例:
public MyPage() { ... this.add(new RuntimeExceptionHandler() { @Override public IRequestHandler handleRuntimeException(Component component, Exception ex) { if (ex instanceof MySpecialException) { // just an example, you really can do anything you want here. // show a feedback message... MyPage.this.error("something went wrong"); // then hide the affected component(s) so the error doesn't happen again... myComponentWithErrorInModel.setVisible(false); // ... // ...then finally just re-render this page: return new RenderPageRequestHandler(new PageProvider(MyPage.this)); } else { return null; } } }); }
注意:这不是随检票,我们推出我们自己的。 我们只是结合IRequestCycleListener
和Behavior
检票功能来想出这个。
作为这里的主要问题是Model
S被设计从组件层次分离,你可以实现一个组件感知Model
,将针对特定组件的报告的所有错误。
请记住,以确保它实现Detachable
,以便相关Component
将被分离。
如果Model
将执行一项昂贵的操作,你可能有兴趣使用LoadableDetachableModel
而不是(考虑到Model.getObject()
可能会被多次调用)。
public class MyComponentAwareModel extends LoadableDetachableModel {
private Component comp;
public MyComponentAwareModel(Component comp) {
this.comp = comp;
}
protected Object load() {
try {
return Order.lookupOrderDataFromRemoteService();
} catch (Exception e) {
logger.error("Failed silently...");
comp.error("This is an error message");
}
return null;
}
protected void onDetach(){
comp.detach();
}
}
这也可能是值得采取的一个尝试Session.get().error())
来代替。
我将在catch子句中添加FeedbackPanel页面并调用错误(“一些说明”)。
你可能想简单地返回null getObject
,并添加逻辑控制器类,如果显示消息getObject
返回null。
如果您需要为不同的失败原因的自定义消息,你可以添加喜欢的属性String errorMessage;
到正赶上在异常时设置的模型getObject
-让你的控制器类可以做这样的事情
if(model.getObject == null) {
add(new Label("label",model.getErrorMessage()));
} else {
/* display your model object*/
}