I am using a Jetty 11 server which has a GET method called getObject().
When I receive a request on the server, I want to add a custom header to create a unique identify for the request. So I am trying to add something like x-request-id
with value obtained using UUID into the header.
I tried doing a pseudo search in the header itself using -
final String requestId;
if (!StringUtil.isEmpty(request.getHeader("request-id")) && !StringUtil.isEmpty(request.getHeader("request-id"))) {
requestId = request.getHeader(request.getHeader("request-id"));
}
else {
requestId = UUID.randomUUID().toString().toUpperCase(); //.replace("-", "");
}
request.setAttribute("Request-ID", requestId);
System.out.println("requestId - " + requestId);
But this does not seem to get added into the header of the request.
My ultimate target is to forward this request outside the server with this x-request-id
as my request switched the environment. Once I receive a response, I want to do some lookup on this request later.
My method looks like this -
public void handle(String target, Request jettyReq, HttpServletRequest request, HttpServletResponse response) {
// Redirect API control based on HTTP method type
if (request.getMethod().equals(constGetRequest)) {
doGetObject(jettyReq, request, response);
}
jettyReq.setHandled(true);
}
How do I achieve this with the HttpServletRequest
request in jetty?
Since you are using embedded Jetty, use the built in org.eclipse.jetty.server.HttpChannel.Listener
.
You'll have access to the raw internal Jetty org.eclipse.jetty.server.Request
object that has the HTTP Fields for that request.
To use it, you'll create an instance of that HttpChannel.Listener
, and add it as a bean to your connectors.
MyChannelListener channelListener = new MyChannelListener();
connector.addBean(channelListener);
There are many events that the listener exposes, you'll probably want to set the X-Request-ID
during the void onRequestBegin(Request request)
event.
If using Jetty 9.x you can use the following ...
@Override
public void onRequestBegin(Request request)
{
request.getHttpFields().put("X-Request-ID", UUID.randomUUID().toString());
}
If using Jetty 10.0.0+ (including Jetty 11), the request.getHttpFields()
is an immutable object. You'll just have to intentionally yank it out, modify it, and replace it, like this ..
@Override
public void onRequestBegin(Request request)
{
HttpFields.Mutable replacement = HttpFields.build(request.getHttpFields())
.put("X-Request-ID", UUID.randomUUID().toString().toUpperCase());
request.setHttpFields(replacement);
}
Read the javadoc on HttpChannel.Listener
and pick other things that might fit your needs.
Then all other access of that request, be it internal components of Jetty, a webapp, a specific servlet, filters, forwarding, includes, error handling in the servlet spec, error handling outside of a servlet context, etc can all see it.
The only types of requests you wont see on this, are ones that fail the Request line and/or low level Header/Field parsing steps, those will be reported as BadMessageExceptions to the server level error handler.