【问题标题】:How to add a custom header into coming request on server?如何将自定义标头添加到服务器上的请求中?
【发布时间】:2021-09-14 19:48:28
【问题描述】:

我正在使用一个 Jetty 11 服务器,它有一个名为 getObject() 的 GET 方法。

当我在服务器上收到请求时,我想添加一个自定义标头来为请求创建唯一标识。所以我试图在标题中添加类似x-request-id 的值,使用UUID 获得的值。

我尝试使用 -

在标头本身中进行伪搜索
        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);

但这似乎没有被添加到请求的标头中。

我的最终目标是在我的请求切换环境时使用此x-request-id 将此请求转发到服务器外部。收到回复后,我想稍后对此请求进行一些查找。

我的方法是这样的 -

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);
    }

如何使用码头中的HttpServletRequest 请求来实现这一点?

【问题讨论】:

  • 正在询问如何在服务器上提取自定义标头,或者如何在客户端指定自定义标头? HttpClientclients 使用的 Java 类。 HttpServletRequest服务器 上用于获取客户端发送的信息的接口。您的问题非常令人困惑,因此请编辑问题并澄清您的问题。
  • @Andreas 感谢您的请求。是的,这基本上是在服务器上。我的处理程序代码有 httpServletRequest 我想在其中添加标头。很抱歉之前的混乱。我刚刚根据您的建议编辑了问题。
  • @Andreas 我知道 HttpServletRequest 类型是只读的,这就是为什么我对如何解决这个问题感到困惑。
  • 你是什么意思'将标头添加到服务器上的请求中'?您是否要将标头发送回客户端(将其放在响应中);或者只是为您的应用程序的其余部分添加一些上下文(只需以任意数量的方式之一将其添加到环境中:其他参数、线程局部变量、属性映射)?
  • 所以您是说您的 Java Web 服务器正在向 Python Web 服务器发送 HTTP 请求,并且您想在从 Java 发送到 Python 的请求中添加自定义标头?如果是这样,那么请了解 Java HttpServletRequestHttpServletResponse 不用于向 Python Web 服务器发送请求,您将为此使用 HttpClient。 --- 如果您想将自定义标头 back 发送到原始客户端,那么您将使用HttpServletResponse。你不会使用HttpServletRequest 来做任何事情。

标签: java request jetty request-headers http-request-parameters


【解决方案1】:

由于您使用的是嵌入式 Jetty,请使用内置的 org.eclipse.jetty.server.HttpChannel.Listener

您将有权访问包含该请求的 HTTP 字段的原始内部 Jetty org.eclipse.jetty.server.Request 对象。

要使用它,您将创建该 HttpChannel.Listener 的实例,并将其作为 bean 添加到您的连接器中。

MyChannelListener channelListener = new MyChannelListener();
connector.addBean(channelListener);

侦听器公开了许多事件,您可能希望在void onRequestBegin(Request request) 事件期间设置X-Request-ID

如果使用 Jetty 9.x,您可以使用以下 ...

@Override
public void onRequestBegin(Request request)
{
    request.getHttpFields().put("X-Request-ID", UUID.randomUUID().toString());
}

如果使用 Jetty 10.0.0+(包括 Jetty 11),request.getHttpFields() 是一个不可变对象。您只需要像这样故意将其拉出,修改并替换它..

@Override
public void onRequestBegin(Request request)
{
    HttpFields.Mutable replacement = HttpFields.build(request.getHttpFields())
        .put("X-Request-ID", UUID.randomUUID().toString().toUpperCase());
    request.setHttpFields(replacement);
}

阅读HttpChannel.Listener 上的 javadoc 并选择其他可能满足您需求的内容。

然后对该请求的所有其他访问,无论是 Jetty 的内部组件、webapp、特定的 servlet、过滤器、转发、包含、servlet 规范中的错误处理、servlet 上下文之外的错误处理等,都可以看到它。

您不会在此看到的唯一类型的请求是那些未通过请求行和/或低级别 Header/Field 解析步骤的请求,这些请求将作为 BadMessageExceptions 报告给服务器级错误处理程序。

【讨论】:

    猜你喜欢
    • 2016-11-14
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 2018-06-22
    • 2019-04-18
    • 2018-04-12
    相关资源
    最近更新 更多