glassfish - 如何从 JAX-RS 资源确定远程 IP 地址?

标签 glassfish jax-rs grizzly

我在 Grizzly HTTP 服务器中运行了以下 JAX-RS 资源:

@Path("/board")
public class BoardResource {

    @POST
    @Consumes("application/x-www-form-urlencoded")
    public void login(@FormParam("email") String email, @FormParam("password") String password,
            @HeaderParam("user-agent") String userAgent) {
        // how to determine remote IP address here?
    }
}

如何在 login() 处理程序中确定远程 IP 地址?

谢谢, 迈克尔

最佳答案

因为现在这不是 possible为了从 Grizzly 上下文访问远程 IP 信息,我实现了这个肮脏的 hack:

首先,我在我的应用程序中添加了新的依赖注入(inject)绑定(bind)程序,它将 java.net.SocketAddress 实例绑定(bind)到一个包含请求源 IP 的实例:

package test;

import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import javax.inject.Inject;
import javax.inject.Provider;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.internal.PropertiesDelegate;
import org.glassfish.jersey.process.internal.RequestScoped;
import org.glassfish.jersey.server.ContainerRequest;

public class RemoteAddrBinder extends AbstractBinder {

    private static class RemoteAddrProviderFactory implements Factory<SocketAddress> {
        @Inject
        private Provider<ContainerRequest> request;

        @Override
        public SocketAddress provide() {
            ContainerRequest containerRequest = request.get();
            PropertiesDelegate delegate = containerRequest.getPropertiesDelegate();
            try {
                Field requestField = delegate.getClass().getDeclaredField("request");
                requestField.setAccessible(true);
                Request grizzlyRequest = (Request) requestField.get(delegate);
                return new InetSocketAddress(grizzlyRequest.getRemoteAddr(), grizzlyRequest.getRemotePort());
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        public void dispose(SocketAddress instance) {
        }
    }

    @Override
    protected void configure() {        bindFactory(RemoteAddrProviderFactory.class).to(SocketAddress.class).in(RequestScoped.class);
    }
}

然后,我在应用程序中注册了这个 Binder :

application.register(new RemoteAddrBinder());

现在,SocketAddress 可以注入(inject)到任何 JAX-RS 方法中:

@GET
@Path("test")
public Response test(@Context SocketAddress remoteAddr) {
    return Response.ok("Your IP is: " + ((InetSocketAddress) remoteAddr).getAddress().getHostAddress()).build();
}

希望这对某人有帮助:)

关于glassfish - 如何从 JAX-RS 资源确定远程 IP 地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11312578/

相关文章:

java - 泽西客户端非阻塞

java - 使独立的 grizzly2 JAX-RS 接受 URL 中的编码 URL?

grails - 如何更改Glassfish的默认错误页面?

java - 设置属性 : Non-serializable attribute (Java Object Serialization)

java - Jersey 与 jax-rs 有什么区别

error-handling - 来自 Jersey 的Dropwizard错误消息

Java EE 将 CDI @SessionScoped 注入(inject) EJB @Stateless session bean

java - 如何限制沙盒 Java 代码的性能?

java - 带有附加 url 参数的 Restful 帖子?

java - 安全灰熊 HttpServer (HTTPS)