1

如何在HttpSupportFilter中获取用于记录目的的responseBody字符串?

常见的日志解决方案是创建包装器并将其插入标准过滤器

如果我们使用标准过滤器,我们将无法访问 activejdbc db 连接层

我试图应用包装器,但它不起作用,字符串仍然是空的

public class HTTPLogFilter extends HttpSupportFilter {

    private static ThreadLocal<Long> start = new ThreadLocal<>();
    
    @Override
    public void before() {
        start.set(System.currentTimeMillis());
    }

    @Override
    public void after() {

        if(Configuration.HTTPLOGS_ENABLE) {

            Registry.instance().getStatisticsQueue().enqueue(
                    new QueryExecutionEvent(getRoute().getController().getClass().getName() +
                            "#" + getRoute().getActionName() + ":" + method(), System.currentTimeMillis() - start.get()));

            HttpLog httpLog = new HttpLog();

            String username ="TEST";

            Map request = new HashMap<String, Object>();
            request.put("requestUrl", url());
            request.put("contextPath", context());
            request.put("uriFullPath", uri());
            request.put("uriPath", path());
            request.put("method", method());
            request.put("requestHeaders", headers());
            request.put("requestParams", params());
            request.put("queryString", queryString());
            request.put("requestBody", getRequestString());

            Map response = new HashMap<String, Object>();
            response.put("responseHeaders", getResponseHeaders());
            try {
                // BUG ! this responseBody still empty
                response.put("responseBody", getHttpServletResponse().getWriter().toString());
            } catch (IOException e) {
                e.printStackTrace();
            }

            httpLog.setCreatedby(username);
            httpLog.setCreateddt(new Date());
            httpLog.setUsername(username);
            String remoteAddr = ipForwardedFor() != null ? ipForwardedFor() : remoteAddress();
            httpLog.setIpaddress(remoteAddr );
            httpLog.setUseragent(userAgent());
            httpLog.setControllername(getRoute().getController().getClass().getName() + "." + getRoute().getActionName());
            httpLog.setHttpmethod(method());
            httpLog.setHttpexceptions("");
            httpLog.setExecutiondt(new Date(start.get()));
            httpLog.setExecutiondur(System.currentTimeMillis() - start.get());
            httpLog.setHttpurl(url());
            httpLog.setHttprequest(JsonHelper.toJson(request));
            httpLog.setHttpresponse(JsonHelper.toJson(response));
            httpLog.setHttpstatuscode(getHttpServletResponse().getStatus());
            httpLog.saveIt();
        }
    }

}
4

1 回答 1

0

一般来说,你是在正确的道路上。我的理解HttpLog是模型,您想将请求值存储到数据库中,对吗?

你写:

如果我们使用标准过滤器,我们将无法访问 activejdbc 数据库连接层

因此,ActiveWeb 过滤器具有排序,此处记录:https ://javalite.io/controller_filters#filter-ordering

这意味着如果您想要在 中可用的数据库连接HTTPLogFilter,您必须在DBConnectionFilter之前注册HTTPLogFilter,例如:

public class AppControllerConfig extends AbstractControllerConfig {
    public void init(AppContext appContext) {
        add(new DBConnectionFilter(), new HTTPLogFilter());
    }
}

这样,DBConnectionFilter.before()将在 之前调用HTTPLogFilter.before() 并相应地打开数据库连接。

附带说明:您将很快填充数据库,建议将所有这些数据简单地记录到日志文件中,并使用 Splunk 或 Graylog 等日志分析器。

于 2020-08-05T17:52:15.620 回答