首页 > 解决方案 > 添加过滤器以使用 JdkHttpServerFactory 查找请求者的远程 IP 地址

问题描述

有什么方法可以在坚持 JdkHttpServerFactory 框架的同时获取远程 IP 地址吗?

我有一个非常轻量级的 RESTful 服务器,它使用 JdkHttpServerFactory 创建一个服务器,基本上只需要一行代码:

JdkHttpServerFactory.createHttpServer(baseUri, config);

我的依赖是:

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.23.2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-jdk-http</artifactId>
            <version>2.23.2</version>
        </dependency>

向该框架添加过滤器似乎并非易事。我已经通过引入 HttpServletRequest 进行了尝试,但这意味着我需要引入 servlet 框架,而这实际上不适用于 JdkHttpServerFactory,我最终得到 null 作为我的请求。

我找到了另一个建议,但该建议也意味着切换到使用 Grizly2,这再次意味着我必须放弃简单/轻量级的 JdkHttpServerFactory 方法。

标签: restjerseyglassfish

解决方案


我可以看到访问 IP 的唯一方法是通过HttpExchange. 不幸的是,这不是暴露给我们的东西。您可以提出功能请求来公开 IP,也可以自己修改它并构建自己的工件。在任何一种情况下,我建议进行的更改是在 中添加一个属性ContainerRequest,您可以在过滤器中提取该属性。

如果您查看这里的源代码,您将看到ContainerRequest. 我会做类似的事情

final ContainerRequest requestContext = new ContainerRequest(baseUri, requestUri,
                exchange.getRequestMethod(), getSecurityContext(exchange.getPrincipal(), isSecure),
                new MapPropertiesDelegate());
requestContext.setProperty(JdkServerProperties.REMOTE_IP_ADDR, exchange.getRemoteAddr());

然后在你的ContainerRequestFilter,你可以做

@Override
public void filter(ContainerRequestContext requestContext) {
    // ContainerRequest implements ContainerRequestContext
    InetSockAddress remoteAddr = (InetSocketAddress) requestContext.getProperty(JdkServerProperties.REMOTE_IP_ADDR);
}

是的,所以如果我要提出功能/拉取请求或只是构建我自己的工件,这可能就是我要做的改变。或者,如果您不想公开InetSocketAddress,您可以构建 IP 字符串并将其添加为属性值。


推荐阅读