我想记录进出我的服务器的所有传入请求和传出响应。
是否有一个我可以注册的事件侦听器,它将在传递给任何
Request
之前提供一个 Handler
对象,并在发送出去之前提供一个 Response
对象?
我已经在我能找到的任何地方手动插入了日志语句,但有些调用永远不会到达我的应用程序的
Handler
。例如,如果用户调用 HTTP GET https://example.com//quests/195
我得到:
org.eclipse.jetty.http.BadMessageException: 400: Ambiguous URI empty segment
at [email protected]/org.eclipse.jetty.server.internal.HttpConnection$HttpStreamOverHTTP1.headerComplete(HttpConnection.java:1226)
at [email protected]/org.eclipse.jetty.server.internal.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:1012)
at [email protected]/org.eclipse.jetty.http.HttpParser.parseFields(HttpParser.java:1252)
at [email protected]/org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1545)
at [email protected]/org.eclipse.jetty.server.internal.HttpConnection.parseRequestBuffer(HttpConnection.java:626)
at [email protected]/org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:460)
at [email protected]/org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322)
at [email protected]/org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
at [email protected]/org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
at java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
在上述情况下,我没有地方可以获取
Request
对象,因此我可以记录传入的请求,也无法记录 Jetty 自动发出的响应。有什么想法吗?
你有2个选择。
选择1:使用自定义Request.Wrapper和Response.Wrapper创建自定义Handler.Wrapper
创建一个普通的 Handler.Wrapper,并将其放在 Handler 树早期的某个位置。
然后您可以用自己的实现包装现有的请求/响应并将其传递到包装的处理程序中。
例如:
public class CustomRequestResponseHandler extends Handler.Wrapper
{
@Override
public boolean handle(Request request, Response response, Callback callback) throws Exception
{
Request.Wrapper myRequest = new Request.Wrapper(request)
{
@Override
public HttpURI getHttpURI()
{
// TODO: give a different URI? or perhaps just log the URI used?
return super.getHttpURI();
}
};
Response.Wrapper myResponse = new Response.Wrapper(request, response)
{
@Override
public void write(boolean last, ByteBuffer byteBuffer, Callback callback)
{
// TODO: do something with the write
super.write(last, byteBuffer, callback);
}
};
return super.handle(myRequest, myResponse, callback);
}
}
选择 2:创建 EventsHandler 来捕获事件
摘要
EventsHandler
有一些事件,您可以在处理过程中的不同点挂钩这些事件,这可能对您有用。
public static class CustomEventsHandler extends EventsHandler
{
@Override
protected void onBeforeHandling(Request request) {
}
@Override
protected void onRequestRead(Request request, Content.Chunk chunk) {
}
@Override
protected void onAfterHandling(Request request, boolean handled, Throwable failure) {
}
@Override
protected void onResponseBegin(Request request, int status, HttpFields headers) {
}
@Override
protected void onResponseWrite(Request request, boolean last, ByteBuffer content) {
}
@Override
protected void onResponseWriteComplete(Request request, Throwable failure) {
}
@Override
protected void onResponseTrailersComplete(Request request, HttpFields trailers) {
}
@Override
protected void onComplete(Request request, Throwable failure) {
}
}
看