GWT服务异常日志记录的最佳实践

10

我决定在我的GWT服务层中添加日志系统。首先,我想记录从该层抛出的所有异常。我有一个类似于Spring的ServletDispatcher的对象,它调用其他服务。我认为可以在那里添加日志记录,但是我意识到GWT服务将已检查的异常封装在ServletResponse中,并将未经检查的异常封装在UnexpectedException中。

有人能分享一下他对这个问题的经验吗?最佳的方法是什么,以记录所有GWT服务的已检查和未检查异常。


我找到了一种解决方案,建议扩展RemoteServiceServlet并重写默认的异常流程。但我认为这个解决方案太费时间了。有人知道更简单的方法吗?

3个回答

12

在服务器端,我们有一个RemoteServiceServlet的子类,用于所有服务实现。你提到这似乎很耗时,但以下是代码示例。只需要做一次即可完成。

@Override
protected void doUnexpectedFailure(Throwable t) {
    t.printStackTrace(System.err);
    super.doUnexpectedFailure(t);
}

注意:我们实际上不会将它发送到System.err,而且您也可能不应该这样做,但您可以得到这个想法。
在客户端,我们使用AsyncCallback的子类AsyncSuccessCallback。它统一处理了大部分RPC调用的onFailure情况。大多数回调代码都可以通过了解已处理onFailure来处理onSuccess。它还提供了一个单一的地方来稍后更改此实现。
public abstract class AsyncSuccessCallback<T> implements AsyncCallback<T> {

    public void onFailure(Throwable t) {
        handleException(t);
    }

    protected void handleException(Throwable t) {
         Window.alert(t.getMessage());
    }

}

注意:我们实际上不使用Window.alert,但是你可以理解这个概念。在这种情况下,我们会显示一个GWT DialogBox,其中包含一个表单,该表单会向另一台接受错误报告的服务器进行POST提交。该表单允许用户输入错误发生时他们正在进行的操作的描述。
如果你想要获取堆栈跟踪信息,需要在客户端编写一些额外的代码:
// for lineEnding, use "<br>" for HTML, "\n" for text
public static final String getStackTrace(Throwable t, String lineEnding) {
    Object[] stackTrace = t.getStackTrace();
    if (stackTrace != null) {
        StringBuilder output = new StringBuilder();
        for (Object line : stackTrace) {
            output.append(line);
            output.append(lineEnding);
        }
        return output.toString();
    } else {
        return "[stack unavailable]";
    }
}

我还没有尝试过,但它似乎是正确的解决方案。一旦我有一个与日志记录相关的任务,我会尽快尝试它。在此之前,我将把它标记为正确。 - Zalivaka

1
使用gwt-dispatch。日志记录可以嵌入标准调度服务中,如下面的示例所示,该示例摘自gwt-dispatch Getting Started页面。
public class SimpleDispatchServlet extends RemoteServiceServlet 
       implements StandardDispatchService {

    private Dispatch dispatch;

    public SimpleDispatchServlet() {
        InstanceActionHandlerRegistry registry = 
          new DefaultActionHandlerRegistry();
        registry.addHandler(new IncrementCounterHandler());
        dispatch = new SimpleDispatch(registry);
    }

    public Result execute(Action<?> action) throws DispatchException {
        try {
            return dispatch.execute(action);
        } catch (RuntimeException e) {
            log("Exception while executing " + action.getClass().getName() 
                + ": " + e.getMessage(), e );
            throw e;
        }
    }
}

1

你想记录哪些异常?客户端还是服务器端? 我们有一个使用GWT的大型企业应用程序。我们在客户端使用MVP模式,并且所有对服务器的请求都使用通用的RPCservice类完成。 例如 saveUserService = new remoteService();

在服务器端,我们使用命令模式处理SaveUserRequest并准备SaveUserResponse。所有异常都在那里处理,除了ClientWarningException,它们被留下传播到客户端,在那里我们向用户显示一个漂亮的消息。

这可能有点冗长,但在大约100k行代码的大型应用程序上扩展得很好。


首先,我需要一个服务层的服务器端日志。 - Zalivaka
关于您的建议,我不是很清楚。您能解释一下吗?据我理解,您将异常包装在响应对象中,是这样构建的吗? - Zalivaka
所有服务器端的异常都应该已经被您选择的日志记录(或sysout)记录下来。 我们决定以特殊方式处理某些异常,并让它们上升到客户端,为用户提供有用的信息。例如验证错误。 - Uberto
确实,GWT默认会将它们包装起来,但你可以在代码中轻松更改这一点。 - Uberto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接