2012-04-28 254 views

答えて

28

javax.servlet.http.HttpServletRequestオブジェクトのgetHeader(String Name)メソッドを使用して、という変数を取得します。ここではサンプルコードは次のとおりです。

String ipAddress = request.getHeader("Remote_Addr"); 

このコードは、空の文字列を返す場合、この方法を使用します。

String ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR"); 

if (ipAddress == null) { 
    ipAddress = request.getRemoteAddr(); 
} 
+1

! :)ありがとう、ありがとうございます、特定のIPアドレスに基づいてどの国が訪問者であると結論付けることができる方法はありますか? P.S.最高のものとしてマークします。あなたがすでに私の質問に答えているからです。 –

+1

国/都市のGeoIPサービスを認識するためです。たとえば、次のリンクを確認してください。http://www.maxmind.com/app/java –

+2

IPアドレスをジオコードする:http://stackoverflow.com/questions/3232516/geocode-an-ip-address –

7

非常にupvotedされた受け入れ答えがあるのにもかかわらず、私が提案したいのですが代替案と受け入れられた答えの欠点を指摘する。

request.getHeader("Remote_Addr")は、request.getRemoteAddr()とまったく同じに戻るため、specifiedです。したがって、両方をチェックするのは意味がありません。また、getRemoteAddrjavax.servlet.ServletRequestのメソッド(つまりHTTP非依存型)であり、getHeaderjavax.servlet.http.HttpServletRequestであることに注意してください。

さらに、一部のプロキシはX-Forwarded-ForではなくClient-IPを使用します。議論については、https://stackoverflow.com/a/7446010/131929を参照してください。

HTTP_X_FORWARDED_FORを超えるX-Forwarded-Forの使用方法がわかりません。 Javaでは、私はむしろ、直接の短い形式を使用したいと思います。議論については、https://stackoverflow.com/a/3834169/131929を参照してください。 getHeaderspecifiedであるため、大文字と小文字は区別されません。の場合はです。

のJava代替

public final class ClientIpAddress { 

    // CHECKSTYLE:OFF 
    // https://stackoverflow.com/a/11327345/131929 
    private static Pattern PRIVATE_ADDRESS_PATTERN = Pattern.compile(
     "(^127\\.)|(^192\\.168\\.)|(^10\\.)|(^172\\.1[6-9]\\.)|(^172\\.2[0-9]\\.)|(^172\\.3[0-1]\\.)|(^::1$)|(^[fF][cCdD])", 
     Pattern.CANON_EQ); 
    // CHECKSTYLE:ON 

    private ClientIpAddress() { 
    } 

    /** 
    * Extracts the "real" client IP address from the request. It analyzes request headers 
    * {@code REMOTE_ADDR}, {@code X-Forwarded-For} as well as {@code Client-IP}. Optionally 
    * private/local addresses can be filtered in which case an empty string is returned. 
    * 
    * @param request HTTP request 
    * @param filterPrivateAddresses true if private/local addresses (see 
    * https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces and 
    * https://en.wikipedia.org/wiki/Unique_local_address) should be filtered i.e. omitted 
    * @return IP address or empty string 
    */ 
    public static String getFrom(HttpServletRequest request, boolean filterPrivateAddresses) { 
    String ip = request.getRemoteAddr(); 

    String headerClientIp = request.getHeader("Client-IP"); 
    String headerXForwardedFor = request.getHeader("X-Forwarded-For"); 
    if (StringUtils.isEmpty(ip) && StringUtils.isNotEmpty(headerClientIp)) { 
     ip = headerClientIp; 
    } else if (StringUtils.isNotEmpty(headerXForwardedFor)) { 
     ip = headerXForwardedFor; 
    } 
    if (filterPrivateAddresses && isPrivateOrLocalAddress(ip)) { 
     return StringUtils.EMPTY; 
    } else { 
     return ip; 
    } 
    } 

    private static boolean isPrivateOrLocalAddress(String address) { 
    Matcher regexMatcher = PRIVATE_ADDRESS_PATTERN.matcher(address); 
    return regexMatcher.matches(); 
    } 
} 

PHPの代替素晴らしいです

function getIp() 
{ 
    $ip = $_SERVER['REMOTE_ADDR']; 

    if (empty($ip) && !empty($_SERVER['HTTP_CLIENT_IP'])) { 
     $ip = $_SERVER['HTTP_CLIENT_IP']; 
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
     // omit private IP addresses which a proxy forwarded 
     $tmpIp = $_SERVER['HTTP_X_FORWARDED_FOR']; 
     $tmpIp = filter_var(
      $tmpIp, 
      FILTER_VALIDATE_IP, 
      FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE 
     ); 
     if ($tmpIp != false) { 
      $ip = $tmpIp; 
     } 
    } 
    return $ip; 
} 
+0

あなたの解決策はエレガントで、私はこれを使用しています。 UpVote – Mubasher

+0

X-Forwarded-Forには、コンマで区切ったプロキシIPアドレスのリストを含めることができるので、最初に文字列を分割します。 –

関連する問題