3

GrizzlyHTTPサーバーで次の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アドレスを確認するにはどうすればよいですか?

ありがとう、マイケル

4

4 に答える 4

2

現在、これはGrizzlyコンテキストからリモートIP情報にアクセスすることはできないため、このダーティハックを実装しました

まず、アプリケーションに新しい依存性注入バインダーを追加しました。これにより、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();
}

これが誰かに役立つことを願っています:)

于 2013-08-22T10:43:04.160 に答える
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());
    }
}
于 2014-03-15T10:49:13.757 に答える
2

開発者の説明によると、GrizzlyはJAX-RS 2.0に完全には準拠していないため、公式のコンテキストインジェクション/ラッピングはありません。ジャージーバグ-1960を参照してください 。ジャージー+グリズリーバージョン2.7以降に適用可能

幸いなことに、Grizzlyの要求/応答オブジェクトを挿入する方法があります。ちょっとトリッキーですが動作しますジャージーのユニットテストの1つで提供されたコードサンプル。ジャージーコンテナテストを参照してください

したがって、コードフラグメントは次のようになります。

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

フィルタとサービスメソッドの両方で正常に機能します

于 2014-05-09T13:16:38.860 に答える
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…</ p>

于 2012-07-03T14:08:17.543 に答える