【问题标题】:Best Practices for GWT services exceptions loggingGWT 服务异常日志记录的最佳实践
【发布时间】:2011-05-10 18:03:30
【问题描述】:

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

有人可以分享他在这个问题上的经验吗?记录所有 GWT 服务的已检查和未检查异常的最佳方式是什么。


我找到了建议扩展 RemoteServiceServlet 并覆盖默认异常流的解决方案。但我发现这个解决方案太耗时了。有人知道更简单的变体吗?

【问题讨论】:

    标签: java spring exception gwt logging


    【解决方案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;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      在服务器端,我们有一个 RemoteServiceServlet 的子类,用于所有服务实现。您提到这似乎很耗时,但这就是代码的样子。你做一次就完成了。

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

      注意:我们实际上并没有将其发送到 System.err,您可能也不应该这样做,但您明白了。

      在客户端,我们使用 AsyncCallback 的一个子类,称为 AsyncSuccessCallback。它为我们的大多数 RPC 调用统一处理 onFailure 情况。我们的大多数回调代码都可以处理 onSuccess 的情况,因为知道 onFailure 已被处理。它还提供了一个稍后更改此实现的地方。

      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 对话框,该对话框显示一个向接受错误报告的不同服务器执行 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]";
          }
      }
      

      【讨论】:

      • 我还没有尝试过,但这似乎是正确的解决方案。一旦我有与日志记录相关的任务,我会立即尝试。直到那时我将其标记为正确。
      【解决方案3】:

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

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

      这可能有点冗长,但它可以在大约 100k loc 的大型应用上很好地扩展。

      【讨论】:

      • 首先我需要一个服务层的服务器端日志。
      • 关于你的建议,我不清楚。你能解释一下吗?据我了解,您将异常包装在响应对象中,是这样构建的吗?
      • 服务器端的所有异常都应该已经由您选择的日志(或 sysout)记录下来。我们决定以特殊的方式处理一些异常,并让它们上升到客户端,为用户提供有用的信息。例如验证错误。
      • 确实 gwt 默认会包装它们,但您可以在代码中轻松更改它。
      猜你喜欢
      • 2020-01-25
      • 1970-01-01
      • 2012-11-02
      • 1970-01-01
      • 2018-03-27
      • 2017-11-15
      • 2021-08-05
      • 2010-10-08
      • 1970-01-01
      相关资源
      最近更新 更多