工具类:
package com.shinyv.common.util;
import com.shinyv.amc.client.AnchorAction;
import org.apache.log4j.Logger;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbMakerConfigException;
import org.lionsoul.ip2region.DbSearcher;
import org.springframework.core.io.ClassPathResource;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
public class HttpRequestIpAddrUtil {
private static final Logger logger;
static {
logger = Logger.getLogger(AnchorAction.class);
}
/**
* 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
*
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
* 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
*
* 如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
* 192.168.1.100
*
* 用户真实IP为: 192.168.1.110
*
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
/**
* 根据ip获取归属地
* @param ip
* @return
*/
// public static String getRealAddress(String ip) throws UnsupportedEncodingException {
// String url = "http://ip.ws.126.net/ipquery?ip=" + ip;
// try {
// Document doc= Jsoup.parse(new URL(url),(3000));//编码是GBK
// String body = doc.body().toString();
// String substring = body.substring(body.indexOf("{"), body.indexOf("}")+1);
logger.info("真实地址1:"+substring);
// JSONObject jsonObject = JSONObject.parseObject(substring);
// String province = jsonObject.getString("province");
// String city = jsonObject.getString("city");
// String realAddress= province + city;
logger.info("真实地址:"+realAddress);
// return realAddress;
// } catch (Exception e) {
// e.printStackTrace();
// logger.info("获取IP地址超时");
// }
// return null;
// }
public static String getRealAddress(String ip) {
try {
return getCityInfo(ip);
} catch (Exception e) {
e.printStackTrace();
}
return "未知地址";
}
/**
* 根据IP地址获取城市
*
* @param ip
* @return
*/
public static String getCityInfo(String ip) throws Exception {
//读取jar包内的配置文件信息
DbSearcher searcher = null;
Method method = null;
InputStream inputStream = null;
try {
ClassPathResource resource = new ClassPathResource("/resources/ip2region/ip2region.db");
inputStream = resource.getInputStream();
byte[] dbBinStr = toByteArray(inputStream);
DbConfig config = new DbConfig();
searcher = new DbSearcher(config, dbBinStr);
// 查询算法memory,采用二进制方式初始化DBSearcher需要使用MEMORY_ALGORITYM,
//否则会抛出null。
method = searcher.getClass().getMethod("memorySearch", String.class);
} catch (IOException | DbMakerConfigException| NoSuchMethodException | SecurityException e) {
logger.error(e.getMessage());
e.printStackTrace();
} finally {
if (inputStream != null) {
inputStream.close();
}
}
return ((DataBlock) method.invoke(searcher, ip)).getRegion();
}
/**
* InputStream 转换成byte[]
* @param input
* @return
* @throws IOException
*/
private static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024*4];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
}
jar包附件下载:
链接:百度网盘 请输入提取码
提取码:wsb8
db附件下载:
链接:百度网盘 请输入提取码
提取码:0nzf
ip获取:
String ip = HttpRequestIpAddrUtil.getIpAddress(request);