Gwt从服务器端登录客户端UI

时间:2013-09-18 15:29:13

标签: gwt logging

我创建了GWT应用程序,其中我有一个垂直面板,我在其中记录详细信息。

客户端记录我正在使用记录器

示例代码是:

         public static VerticalPanel customLogArea = new VerticalPanel();
         public static Logger rootLogger = Logger.getLogger("");
                    logerPanel.setTitle("Log");
        scrollPanel.add(customLogArea);
        logerPanel.add(scrollPanel);
        if (LogConfiguration.loggingIsEnabled()) {
        rootLogger.addHandler(new HasWidgetsLogHandler(customLogArea));

        }

我正在使用此代码更新我的垂直日志面板

         rootLogger.log(Level.INFO,
                        "Already Present in Process Workspace\n");

但现在我的问题是,我必须将服务器端详细信息记录到我的垂直日志面板中。

我的服务器端GreetingServiceImpl代码是:

      public boolean createDirectory(String fileName)
             throws IllegalArgumentException {
    Boolean result = false;
    try {
        rootLogger.log(Level.INFO,
                 "I want to log this to my UI vertical log Panel");

        system.out.println("log this to UI");
        File dir = new File("D:/GenomeSamples/" + fileName);
        if (!dir.exists()) {
            result = dir.mkdir();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

现在我想从这里将sysoutprt语句记录到我的UI中。我怎样才能做到这一点。现在使用rootLogger.log(Level.INFO,                      “我想将此记录到我的UI垂直日志面板”);代码它将此日志记录到eclipse控制台。但是如何将其记录到客户端的UI中。

如果这个问题有任何问题,请告诉我。

3 个答案:

答案 0 :(得分:3)

如果我理解正确,您希望在Web界面中看到您的服务器日志条目。当然,java logger和printStackTrace()对你没有帮助:你的gwt代码被编译为JavaScript,与控制台和日志文件无关。此外,您的服务器无法将日志条目“推送”到客户端 - 这取决于客户端发出请求。因此,如果要跟踪新日志条目并将其移动到客户端,则需要轮询服务器以获取新条目。还有一个问题:你可能有很多客户端轮询你的servlet,你应该记住这个多线程。

这就是我看到可能的实现方式(它只是概念,可能包含一些错误和拼写错误):

远程接口:

public interface GreetingService extends RemoteService {
    List<String> getLogEntries();
    boolean createDirectory(String fileName)throws IllegalArgumentException;

}

远程Servlet:

public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {

public static final String LOG_ENTRIES = "LogEntries";

public List<String> getLogEntries() {

    List<String> entries = getEntriesFromSession();
    List<String>copy = new ArrayList<String>(entries.size());
    copy.addAll(entries);
    //prevent loading the same entries twice
    entries.clear();
    return copy;

}



public boolean createDirectory(String fileName)throws IllegalArgumentException {
    Boolean result = false;
    try {

        log("I want to log this to my UI vertical log Panel");

        log("log this to UI");
        File dir = new File("D:/GenomeSamples/" + fileName);
        if (!dir.exists()) {
            result = dir.mkdir();
        }
    } catch (Exception e) {
        log("Exception occurred: " + e.getMessage());
    }
    return result;
}

private List<String> getEntriesFromSession()    {
    HttpSession session= getThreadLocalRequest().getSession();
    List<String>entries = (List<String>)session.getAttribute(LOG_ENTRIES);
    if (entries == null)    {
        entries = new ArrayList<String>();
        session.setAttribute(LOG_ENTRIES,entries);
    }

    return entries;

}

private void log(String message)  {
    getEntriesFromSession().add(message);
}

简单实施轮询(gwt客户端):

Timer t = new Timer() {
  @Override
  public void run() {
    greetingAsyncService.getLogEntries(new AsyncCallBack<List<String>>() {
       void onSuccess(List<String>entries) {
         //put entries to your vertical panel
       }

       void onFailure(Throwable caught){
           //handle exceptions
       }
    });
  }
};

// Schedule the timer to run once in second.
t.scheduleRepeating(1000);

greetingAsyncService.createDirectory(fileName, new AsyncCallBack<Void>(){
    void onSuccess(List<String>entries) {
          //no need to poll anymore
          t.cancel();
       }

       void onFailure(Throwable caught){
           //handle exceptions
       }
});

}

正如您所看到的,我使用会话来保留日志条目,因为会话是特定于客户端的,因此不同的客户端将接收不同的日志。由您来决定使用什么 - 您可以创建自己的Logger类来跟踪用户本身并将适当的日志提供给适当的客户端。

此外,您可能希望保存消息级别(INFO,ERROR等),然后以不同颜色显示消息(例如,红色表示ERROR)。为此,您需要保存而不是List,而是保存一些自定义类。

答案 1 :(得分:0)

您将创建一个日志记录servlet,其具有与日志记录框架相同的方法,以通过RPC将日志消息发送到您的服务器。

以下是一些可以使用的RPC日志方法示例:

public interface LogService extends RemoteService {
    public void logException(String logger, String priority, String message, String error, StackTraceElement[] stackTrace, String nativeStack);
}

public interface LogServiceAsync {
    public void logException(String logger, String priority, String message, String error, StackTraceElement[] stackTrace, String nativeStack, AsyncCallback<Void> callback);
}

public class LogServiceImpl extends RemoteServiceServlet implements LogService {

    public void logException(String loggerName, String priority, String logMessage, String errorMessage, StackTraceElement[] stackTrace, String nativeStack) {      
        Logger logger = getLogger(loggerName);
        Level level = getLevel(priority);
        // Create a Throwable to log
        Throwable caught = new Throwable();
        if (errorMessage != null && stackTrace != null) {
            caught = new Throwable(errorMessage);
            caught.setStackTrace(stackTrace);
        }
        //do stuff with the other passed arguments (optional)
        logger.log(level, message, caught);
    }
}

答案 2 :(得分:0)

虽然这些实现非常好,但忘记计时器和重复的服务器查询。我们现在有更好的东西。

可以使用支持AtmosphereWebSockets将数据从服务器推送到客户端。