Sono curioso di sapere se esiste una libreria che gestisce già questo tipo di cose, o devo farlo di nuovo da solo. Quindi, il fatto è che voglio ottenere il campo indirizzo IP dalla richiesta di intestazione HTTP dei visitatori sul mio server, e fare il tutto in Java? Qualsiasi aiuto sarebbe carino. Grazie in anticipo.Come posso recuperare l'indirizzo IP dall'intestazione HTTP in Java
risposta
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();
}
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;
}
La tua soluzione è elegante e io sono pronto ad usarlo. UpVote – Mubasher
X-Forwarded-For può contenere un elenco separato da virgole di indirizzi IP proxy, quindi vorrei dividere prima la stringa. –
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. –
Per riconoscere il Paese/la città usa il servizio GeoIP. Per esempio controlla questo link: http://www.maxmind.com/app/java –
Geocodifica un indirizzo IP: http://stackoverflow.com/questions/3232516/geocode-an-ip-address –