根据IP地址查出对应城市
2012-04-13 15:47
651 查看
package com.jd.train.service.util; import com.jd.common.util.StringUtils; import com.jd.train.manager.util.impl.HttpClientUtilManagerImpl; import org.apache.log4j.Logger; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import javax.servlet.http.HttpServletRequest; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.RandomAccessFile; public class IPParser { private final Logger log = Logger.getLogger(IPParser.class); private String url; //ip查询请求地址 private String dbPath; //本地IP数据库地址 private String country, localStr; private long IPN; private int recordCount, countryFlag; private long rangE, rangB, offSet, startIP, endIP, firstStartIP,lastStartIP, endIPOff; private RandomAccessFile fis; private byte[] buff; private long B2L(byte[] b) { long ret = 0; for (int i = 0; i < b.length; i++) { long t = 1L; for (int j = 0; j < i; j++) t = t * 256L; ret += ((b[i] < 0) ? 256 + b[i] : b[i]) * t; } return ret; } private long ipToInt(String ip) { String[] arr = ip.split("\\."); long ret = 0; for (int i = 0; i < arr.length; i++) { long l = 1; for (int j = 0; j < i; j++) l *= 256; try { ret += Long.parseLong(arr[arr.length - i - 1]) * l; } catch (Exception e) { ret += 0; } } return ret; } private void seek(String ip) throws Exception { IPN = ipToInt(ip); fis = new RandomAccessFile(dbPath, "r"); buff = new byte[4]; fis.seek(0); fis.read(buff); firstStartIP = B2L(buff); fis.read(buff); lastStartIP = B2L(buff); recordCount = (int) ((lastStartIP - firstStartIP) / 7); if (recordCount <= 1) { localStr = country = "未知"; throw new Exception(); } rangB = 0; rangE = recordCount; long RecNo; do { RecNo = (rangB + rangE) / 2; getStartIP(RecNo); if (IPN == startIP) { rangB = RecNo; break; } if (IPN > startIP) rangB = RecNo; else rangE = RecNo; } while (rangB < rangE - 1); getStartIP(rangB); getEndIP(); getCountry(IPN); fis.close(); } private String getFlagStr(long OffSet) throws IOException { int flag = 0; do { fis.seek(OffSet); buff = new byte[1]; fis.read(buff); flag = (buff[0] < 0) ? 256 + buff[0] : buff[0]; if (flag == 1 || flag == 2) { buff = new byte[3]; fis.read(buff); if (flag == 2) { countryFlag = 2; endIPOff = OffSet - 4; } OffSet = B2L(buff); } else break; } while (true); if (OffSet < 12) { return ""; } else { fis.seek(OffSet); return getStr(); } } private String getStr() throws IOException { long l = fis.length(); ByteArrayOutputStream byteout = new ByteArrayOutputStream(); byte c = fis.readByte(); do { byteout.write(c); c = fis.readByte(); } while (c != 0 && fis.getFilePointer() < l); return byteout.toString(); } private void getCountry(long ip) throws IOException { if (countryFlag == 1 || countryFlag == 2) { country = getFlagStr(endIPOff + 4); if (countryFlag == 1) { localStr = getFlagStr(fis.getFilePointer()); if (IPN >= ipToInt("255.255.255.0") && IPN <= ipToInt("255.255.255.255")) { localStr = getFlagStr(endIPOff + 21); country = getFlagStr(endIPOff + 12); } } else { localStr = getFlagStr(endIPOff + 8); } } else { country = getFlagStr(endIPOff + 4); localStr = getFlagStr(fis.getFilePointer()); } } private long getEndIP() throws IOException { fis.seek(endIPOff); buff = new byte[4]; fis.read(buff); endIP = B2L(buff); buff = new byte[1]; fis.read(buff); countryFlag = (buff[0] < 0) ? 256 + buff[0] : buff[0]; return endIP; } private long getStartIP(long RecNo) throws IOException { offSet = firstStartIP + RecNo * 7; fis.seek(offSet); buff = new byte[4]; fis.read(buff); startIP = B2L(buff); buff = new byte[3]; fis.read(buff); endIPOff = B2L(buff); return startIP; } private String getUserIp(HttpServletRequest request) { String ip = CodesUtil.getIpAddr(request); if (ip != null && ip.indexOf(",") > 0) { log.info("取到客户多个ip1====================" + ip); String[] arr = ip.split(","); ip = arr[arr.length - 1].trim();//有多个ip时取最后一个ip log.info("取到客户多个ip2====================" + ip); } return ip; } private String findCity(HttpServletRequest request , String ipStr) { if(null == request && StringUtils.isEmpty(ipStr)){ log.info("IPParser,findIpAddr(), request and ip is empty !"); return null; } String ip = ipStr; if(request != null){ ip = getUserIp(request); } if(StringUtils.isEmpty(ip)){ log.info("IPParser,findIpAddr(), ip is empty !"); return null; } String result; String location; try { seek(ip.trim()); } catch (Exception e) { log.error("IPParser,findIpAddr() error ! " + e); } location = country; //查不到1 if (StringUtils.isEmpty(location)) { log.info("IPParser,findIpAddr(), location is empty ! Trying remote interface ..."); location = findIpAddrRemote(ip); if (StringUtils.isEmpty(location)) { log.info("IPParser,findIpAddr(), location is empty !"); return null; } } //查不到2 location = location.trim(); if (location.length() == 0) { log.info("IPParser,findIpAddr(), location length is 0 ! Trying remote interface ..."); location = findIpAddrRemote(ip); if (StringUtils.isEmpty(location)) { log.info("IPParser,findIpAddr(), location is empty !"); return null; } if (location.length() == 0) { log.info("IPParser,findIpAddr(), location length is 0 !"); return null; } } //查不到3 if (location.contains("未知")) { log.info("IPParser,findIpAddr(), location is not found ! Trying remote interface ..."); location = findIpAddrRemote(ip); if (StringUtils.isEmpty(location)) { log.info("IPParser,findIpAddr(), location is empty !"); return null; } if (location.contains("未知")) { log.info("IPParser,findIpAddr(), location is not found !"); return null; } } int cityIndex = location.indexOf("市"); int cityIndex2 = location.indexOf("市", cityIndex + 1); int provinceIndex = location.indexOf("省"); if (cityIndex > -1 && cityIndex2 == -1) { if (provinceIndex > -1) { location = location.substring(provinceIndex + 1, cityIndex); } else { location = location.substring(0, cityIndex); } } //处理有2个市的地址 if (cityIndex > -1 && cityIndex2 > -1) { location = location.substring(cityIndex + 1, cityIndex2); } //自治区处理 if (location.contains("宁夏")) { location = location.replaceAll("宁夏", ""); } if (location.indexOf("内蒙古") > -1) { location = location.replaceAll("内蒙古", ""); int districtIndex = location.indexOf("盟"); if (districtIndex > -1) { location = location.substring(districtIndex + 1, location.length()); } } if (location.indexOf("广西") > -1) { location = location.replaceAll("广西", ""); } if (location.indexOf("西藏") > -1) { location = location.replaceAll("西藏", ""); } if (location.indexOf("新疆") > -1) { location = location.replaceAll("新疆", ""); int districtIndex = location.indexOf("州"); if (districtIndex > -1) { location = location.substring(districtIndex + 1, location.length()); } } //港澳台处理 if (location.contains("省")) { location = location.replaceAll("省", ""); } //其他 if (location.startsWith("清华大学")) { location = "北京"; } //去掉CZ88.NET字样,去掉空格 location = location.replaceAll("CZ88.NET", ""); result = location.replaceAll(" ", ""); log.info(ip + " --> " + location); return result; } private String findIpAddrRemote(String ip) { String result; HttpClientUtilManagerImpl httpClientUtilManager = new HttpClientUtilManagerImpl(); httpClientUtilManager.setTimeout(1000); //超时时间 1s String ipXML = httpClientUtilManager.executeHttpRequestString(url + ip, null); if (ipXML == null) { log.info("IPParser,findIpAddrRemote(),ipXML is null !"); return null; } Document doc; try { doc = DocumentHelper.parseText(ipXML.trim()); } catch (DocumentException e) { log.error("IPParser,findIpAddrRemote() error !" + e); return null; } if (doc == null) { log.info("IPParser,findIpAddrRemote(),doc is null !"); return null; } Element rootElement = doc.getRootElement(); Element productElement = rootElement.element("product"); if (productElement == null) { log.info("IPParser,findIpAddrRemote(),productElement is null !"); return null; } Element element = productElement.element("location"); if (element == null) { log.info("IPParser,findIpAddrRemote(),element is null !"); return null; } result = element.getTextTrim(); return result; } /** * 根据ip获得城市名称 * @param ip * @return */ public String ipToCity(String ip){ return findCity(null , ip); } /** * 根据请求获得城市名称 * @param request * @return */ public String ipToCity(HttpServletRequest request){ return findCity(request, null); } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getDbPath() { return dbPath; } public void setDbPath(String dbPath) { this.dbPath = dbPath; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getLocalStr() { return localStr; } public void setLocalStr(String localStr) { this.localStr = localStr; } public long getIPN() { return IPN; } public void setIPN(long IPN) { this.IPN = IPN; } public int getRecordCount() { return recordCount; } public void setRecordCount(int recordCount) { this.recordCount = recordCount; } public int getCountryFlag() { return countryFlag; } public void setCountryFlag(int countryFlag) { this.countryFlag = countryFlag; } public long getRangE() { return rangE; } public void setRangE(long rangE) { this.rangE = rangE; } public long getRangB() { return rangB; } public void setRangB(long rangB) { this.rangB = rangB; } public long getOffSet() { return offSet; } public void setOffSet(long offSet) { this.offSet = offSet; } public long getStartIP() { return startIP; } public void setStartIP(long startIP) { this.startIP = startIP; } public long getFirstStartIP() { return firstStartIP; } public void setFirstStartIP(long firstStartIP) { this.firstStartIP = firstStartIP; } public long getLastStartIP() { return lastStartIP; } public void setLastStartIP(long lastStartIP) { this.lastStartIP = lastStartIP; } public long getEndIPOff() { return endIPOff; } public void setEndIPOff(long endIPOff) { this.endIPOff = endIPOff; } public RandomAccessFile getFis() { return fis; } public void setFis(RandomAccessFile fis) { this.fis = fis; } public byte[] getBuff() { return buff; } public void setBuff(byte[] buff) { this.buff = buff; } public static void main(String[] args) throws Exception { long initUsedMemory = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()); long start = System.currentTimeMillis(); IPParser w = new IPParser(); // w.setPath(new File("QQWry2.Dat").getAbsolutePath()); // w.seek("125.10.100.17"); // String ip = "211.161.190.171"; // String ip = "14.192.60.1"; // w.findRequestPhysAddr(ip); long end = System.currentTimeMillis(); long endUsedMemory = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()); System.out.println("time spent:" + (end - start) + " ms"); System.out.println("memory consumes:" + (endUsedMemory - initUsedMemory)); } }
相关文章推荐
- php根据IP地址跳转对应的城市,淘宝REST api调用地址直接使用
- PHP根据IP地址获取所在城市具体实现
- IP地址对应的物理位置简单地解析出城市
- PHP中根据IP地址判断城市实现城市切换或跳转代码
- js根据IP地址判断城市
- 根据IP地址,找到交换机上相对应的端口
- C#根据计算机名获取对应IP地址
- PHP 根据IP地址获取所在城市
- 根据IP地址获取所在城市【通过新浪接口】
- Js根据Ip地址自动判断是哪个城市
- PHP 根据IP地址获取所在城市
- C# 根据IP地址获取城市
- PHP获取IP地址及根据IP判断城市实…
- 根据IP地址获取所在城市【通过新浪接口】
- 思科交换机根据MAC、IP地址查找对应端口流程
- 根据IP地址,找到交换机上相对应的端口
- 根据网卡(eth0, eth1)获得对应的IP地址
- PHP 根据IP地址获取所在城市
- java根据正则表达式查出对应字符,并在查到的字符基础上作修改
- 根据IP地址查询其所属城市