我在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地址?
谢谢, 迈克尔
答案 0 :(得分:2)
由于现在从Grizzly上下文访问远程IP信息不是possible,我已经实现了这个肮脏的黑客攻击:
首先,我在我的应用程序中添加了新的依赖注入工具,它将java.net.SocketAddress实例绑定到包含请求源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);
}
}
然后,我在应用程序中注册了这个活页夹:
application.register(new RemoteAddrBinder());
现在,可以将SocketAddress注入到任何JAX-RS方法中:
@GET
@Path("test")
public Response test(@Context SocketAddress remoteAddr) {
return Response.ok("Your IP is: " + ((InetSocketAddress) remoteAddr).getAddress().getHostAddress()).build();
}
希望这有助于某人:)
答案 1 :(得分:2)
spektom的解决方案不再适用于最新版本。幸运的是,现在存在一个更好的解决方案,将以下内容添加到方法参数中:
@Context org.glassfish.grizzly.http.server.Request req
在您的情况下,这将是这样的:
@Path("/board")
public class BoardResource {
@POST
@Consumes("application/x-www-form-urlencoded")
public void login(@Context Request req, @FormParam("email") String email, @FormParam("password") String password,
@HeaderParam("user-agent") String userAgent) {
// remote IP address
System.out.println(req.getRemoteAddr());
}
}
答案 2 :(得分:2)
根据开发人员的解释 - Grizzly并不完全符合JAX-RS 2.0,因此没有正式的上下文注入/包装。见Jersey Bug-1960 适用于Jersey + Grizzly 2.7 +版
幸运的是,有一种方法可以注入Grizzly请求/响应对象。有点棘手,但有效 在泽西岛的一个单元测试中提供的代码示例。见Jersey container test
所以代码片段将是:
import javax.inject.Inject;
import javax.inject.Provider;
public someclass {
@Inject
private Provider<Request> grizzlyRequestProvider;
public void method() {
if (grizzlyRequestProvider != null) {
Request httpRequest = grizzlyRequestProvider.get();
// Extract what you need
String remoteAddress = httpRequest.getRemoteAddr();
}
}
}
适用于过滤器和服务方法
答案 3 :(得分:1)
您应该为HttpServletRequest
类型的方法添加一个额外的参数,并将@Context
注释放在其上。然后,您可以使用该参数的getRemoteAddr()
方法来获得所需的内容。
@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,
@Context HttpServletRequest request) {
String remoteIP = request.getRemoteAddr();
// ...
}
}
是的,这是String
...