2012-04-28 13 views

Respuesta

28

Utilice el método getHeader(String Name) del objeto javax.servlet.http.HttpServletRequest para recuperar el valor de la variable Remote_Addr. Aquí está el código de ejemplo:

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

Si este código devuelve una cadena vacía, a continuación, utilizar la siguiente manera:

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

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

Eso es increíble! :) Gracias, ¿hay algún método basado en la dirección IP dada que pueda concluir de qué país es el visitante? PD Lo marcará como el mejor, porque ya ha respondido en mi Q. –

+1

Para reconocer el uso GeoIP del país/ciudad. Por ejemplo, consulte este enlace: http://www.maxmind.com/app/java –

+2

Geocodificación de una dirección IP: http://stackoverflow.com/questions/3232516/geocode-an-ip-address –

7

A pesar de que hay una respuesta aceptada que ha sido altamente upvoted me gustaría sugerir una alternativas y señalar deficiencias de la respuesta aceptada.

request.getHeader("Remote_Addr") es specified para devolver exactamente lo mismo que request.getRemoteAddr(). Por lo tanto, no tiene sentido verificar ambos. También tenga en cuenta que getRemoteAddr es un método de javax.servlet.ServletRequest (es decir, HTTP-agnóstico) mientras que getHeader está en javax.servlet.http.HttpServletRequest.

Además, algunos proxies usan Client-IP en lugar de X-Forwarded-For. Para una discusión, vea https://stackoverflow.com/a/7446010/131929.

No sé qué tan confiable es el uso de HTTP_X_FORWARDED_FOR sobre X-Forwarded-For. En Java prefiero usar la forma directa, corta. Para una discusión, vea https://stackoverflow.com/a/3834169/131929. La mayúscula/minúscula no hace ninguna diferencia porque getHeader es specified en el caso en sensible.

Java alternativa

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 alternativa

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

Su solución es elegante y yo no puedo usar esto. UpVote – Mubasher

+0

X-Forwarded-For puede contener una lista de direcciones IP proxy separada por comas, por lo que primero dividiría la cadena. –

Cuestiones relacionadas