2012-04-28 4 views

risposta

28

Utilizzare il metodo dell'oggetto javax.servlet.http.HttpServletRequest per recuperare il valore della variabile Remote_Addr. Ecco il codice di esempio:

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

Se questo codice restituisce una stringa vuota, quindi utilizzare in questo modo:

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

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

Questo è impressionante! :) Grazie, esiste un metodo che in base al dato indirizzo IP può concludere da quale paese è il visitatore? Post scriptum Lo contrassegnerà come il migliore, perché hai già risposto alla mia Q. –

+1

Per riconoscere il Paese/la città usa il servizio GeoIP. Per esempio controlla questo link: http://www.maxmind.com/app/java –

+2

Geocodifica un indirizzo IP: http://stackoverflow.com/questions/3232516/geocode-an-ip-address –

7

anche se non c'è una risposta accettata che è stato altamente upvoted mi piacerebbe suggerire un alternative e sottolineare le carenze della risposta accettata.

request.getHeader("Remote_Addr") è specified restituire esattamente come request.getRemoteAddr(). Quindi, non ha senso controllare entrambi. Si noti inoltre che getRemoteAddr è un metodo di javax.servlet.ServletRequest (ovvero agnostico HTTP) mentre getHeader è in javax.servlet.http.HttpServletRequest.

Inoltre, alcuni proxy utilizzano Client-IP anziché X-Forwarded-For. Per una discussione vedi https://stackoverflow.com/a/7446010/131929.

Non so quanto sia affidabile l'uso di HTTP_X_FORWARDED_FOR su X-Forwarded-For. In Java preferisco usare la forma diretta e breve. Per una discussione vedi https://stackoverflow.com/a/3834169/131929. Maiuscole/minuscole non fa differenza perché getHeader è specified per il caso in sensibile.

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

La tua soluzione è elegante e io sono pronto ad usarlo. UpVote – Mubasher

+0

X-Forwarded-For può contenere un elenco separato da virgole di indirizzi IP proxy, quindi vorrei dividere prima la stringa. –