根据IP地址自动识别省份城市
2014-12-25 09:34
351 查看
功能说明:需要获取客户端的IP地址,自动识别省份
代码如下:
获取IP地址:
public static String getIpAddr(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();
if ("0:0:0:0:0:0:0:1".equals(ip.trim())) {
ip = "127.0.0.1";
}
return ip;
}
调用
String clientIp = PortalToolsUtil.getIpAddr(portalRequest);
根据IP地址获取省份类:
public class IpAddress { private Logger LogUtil = Logger.getLogger(IpAddress.class); // 随机文件访问类 private RandomAccessFile ipFile = null; // 单一模式实例 private static IpAddress instance = new IpAddress(); // ip开始结束位置 private long ipBegin = 0L; private long ipEnd = 0L; // ip总数 private long ipSum = 0L; // 国家,地区 private String country = ""; private String area = ""; // 一些固定常量,比如记录长度等等 private static final int RECORD_LENGTH = 7; private static final byte AREA_FOLLOWED = 0x01; private static final byte NO_AREA = 0x02; /* * 私有构造函数 */ private IpAddress() { // 数据库地址 String dataPath = PropUtil.getProp("ipfile"); try { ipFile = new RandomAccessFile(new File(dataPath).getAbsolutePath(),"r"); } catch (FileNotFoundException e) { LogUtil.error("IP地址信息文件没有找到(QQWry.Dat),IP显示功能将无法使用"); } if (ipFile != null) { try { ipBegin = byteArrayToLong(readBytes(0, 4)); ipEnd = byteArrayToLong(readBytes(4, 4)); if (ipBegin == -1 || ipEnd == -1) { ipFile.close(); ipFile = null; } } catch (IOException e) { LogUtil.error("IP地址信息文件格式有错误,IP显示功能将无法使用"); } } ipSum = (ipEnd - ipBegin) / RECORD_LENGTH + 1; } /** * 在指定位置读取一定数目的字节 * * @param offset * 位置 * @param num * 多少个字节 * @return ret */ private byte[] readBytes(long offset, int num) { byte[] ret = new byte[num]; try { ipFile.seek(offset); for (int i = 0; i != num; i++) { ret[i] = ipFile.readByte(); } return ret; } catch (IOException e) { LogUtil.error("读取文件失败_readBytes"); return ret; } } /** * 当前位置读取一定数目的字节 * * @param num * 多少个字节 * @return ret */ private byte[] readBytes(int num) { byte[] ret = new byte[num]; try { for (int i = 0; i != num; i++) { ret[i] = ipFile.readByte(); } return ret; } catch (IOException e) { LogUtil.error("读取文件失败_readBytes"); return ret; } } /** * 对little-endian字节序进行了转换 byte[]转换为long * * @param b * @return ret */ private long byteArrayToLong(byte[] b) { long ret = 0; for (int i = 0; i < b.length; i++) { ret |= (b[i] << (0x8 * i) & (0xFF * (long) (Math.pow(0x100, i)))); } return ret; } /** * 对little-endian字节序进行了转换 * * @param ip * ip的字节数组形式 * @return ip的字符串形式 */ private String byteArrayToStringIp(byte[] ip) { StringBuffer sb = new StringBuffer(); for (int i = ip.length - 1; i >= 0; i--) { sb.append(ip[i] & 0xFF); sb.append("."); } sb.deleteCharAt(sb.length() - 1); return sb.toString(); } /** * 把ip字符串转换为long型 * * @param ip * @return long */ private long StingIpToLong(String ip) { String[] arr = ip.split("\\."); return (Long.valueOf(arr[0]).longValue() * 0x1000000 + Long.valueOf(arr[1]).longValue() * 0x10000 + Long.valueOf(arr[2]).longValue() * 0x100 + Long.valueOf( arr[3]).longValue()); } /** * 搜索ip,二分法 * * @param ip * @return long ip所在位置 */ public long seekIp(String ip) { long tmp = StingIpToLong(ip); long i = 0; long j = ipSum; long m = 0; long lm = 0L; while (i < j) { m = (i + j) / 2; lm = m * RECORD_LENGTH + ipBegin; if (tmp == byteArrayToLong(readBytes(lm, 4))) { return byteArrayToLong(readBytes(3)); } else if (j == (i + 1)) { return byteArrayToLong(readBytes(3)); } else if (tmp > byteArrayToLong(readBytes(lm, 4))) { i = m; } else/* if( tmp < byteArrayToLong(readBytes(lm, 4))) */{ j = m; } } //LogUtil.error("没有找到ip"); return -1L; } private String readArea(long offset) throws IOException { ipFile.seek(offset); byte b = ipFile.readByte(); if (b == 0x01 || b == 0x02) { long areaOffset = byteArrayToLong(readBytes(offset + 1, 3)); // if(areaOffset == 0) // return "未知"; // else return readString(areaOffset); } else return readString(offset); } /** * 通过ip位置获取国家地区, 参照纯真ip数据库结构 * * @param offset * @return 国家+地区 */ private String seekCountryArea(long offset) { try { ipFile.seek(offset 4000 + 4); byte b = ipFile.readByte(); if (b == AREA_FOLLOWED) { long countryOffset = byteArrayToLong(readBytes(3)); ipFile.seek(countryOffset); b = ipFile.readByte(); if (b == NO_AREA) { country = readString(byteArrayToLong(readBytes(3))); ipFile.seek(countryOffset + 4); } else country = readString(countryOffset); // area = readArea(ipFile.getFilePointer()); } else if (b == NO_AREA) { country = readString(byteArrayToLong(readBytes(3))); // area = readArea(offset + 8); } else { country = readString(ipFile.getFilePointer() - 1); // area = readArea(ipFile.getFilePointer()); } // return country + " " + area; String country1; if (country.length() >= 2) // 只取前两个字 country1 = country.substring(0, 2); else country1 = country; return country1; // return CountryMap.getBranchCodeByCountryName(country1); } catch (IOException e) { return null; } } /** * 从offset偏移处读取一个以0结束的字符串 * * @param offset * @return ret 读取的字符串,出错返回空字符串 */ private String readString(long offset) { try { ipFile.seek(offset); byte[] b = new byte[128]; int i; for (i = 0; (b.length != i) && ((b[i] = ipFile.readByte()) != 0); i++) ; <span style="background-color: rgb(51, 0, 51);"> <span style="color:#FF0000;">String ret = new String(b, 0, i, "GBK");</span></span> ret = ret.trim(); return (ret.equals("") || ret.indexOf("CZ88.NET") != -1) ? "未知" : ret; } catch (IOException e) { LogUtil.error("读取文件失败_readString"); } return ""; } /** * 包含字符串的ip记录 * * @param addr * 地址 * @return IpRecord ip记录 */ public ArrayList stringToIp(String addr) { ArrayList ret = new ArrayList(); try { FileChannel fc = ipFile.getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, ipFile.length()); mbb.order(ByteOrder.LITTLE_ENDIAN); // 上面3代码未使用,内存映射文件功能未写 for (long i = ipBegin + 4; i != ipEnd + 4; i += RECORD_LENGTH) { String sca = seekCountryArea(byteArrayToLong(readBytes(i, 3))); if (sca.indexOf(addr) != -1) { IpRecord rec = new IpRecord(); rec.address = sca; rec.beginIp = byteArrayToStringIp(readBytes(i - 4, 4)); rec.endIp = byteArrayToStringIp(readBytes(i + 3, 4)); ret.add(rec); } } } catch (IOException e) { LogUtil.error(e.getMessage()); } return ret; } /** * 封装ip记录,包括开始ip,结束ip和地址 */ private class IpRecord { public String beginIp; public String endIp; public String address; public IpRecord() { beginIp = endIp = address = ""; } public String toString() { return beginIp + " - " + endIp + " " + address; } } /** * @return 单一实例 */ public static IpAddress getInstance() { return instance; } /** * @param ip * @return ret */ public String IpStringToAddress(String ip) { // 这里要添加ip格式判断 // public boolean isIP(Strin ip) long ipOffset = seekIp(ip); String ret = seekCountryArea(ipOffset); return ret; } /** * @return IpSum */ public long getIpSum() { return ipSum; } public static void main(String[] args) throws UnsupportedEncodingException { IpAddress ipAddr = IpAddress.getInstance(); // //ip总数 // long l = ipAddr.getIpSum(); // LogUtil.error(l); // 测试 String str = ipAddr.IpStringToAddress("218.65.88.101"); System.out.println(str); //LogUtil.error(str); /* * java.net.InetAddress addr = null; try{ addr = * java.net.InetAddress.getLocalHost(); * }catch(java.net.UnknownHostException e){ e.printStackTrace(); } * String ip=addr.getHostAddress().toString();//获得本机IP * System.out.print(ip); String * address=addr.getHostName().toString();//获得本机名称 * System.out.print(address); str = ipAddr.IpStringToAddress(ip); * LogUtil.error(str); */ // ArrayList<IpRecord> al = ipAddr.stringToIp("网吧"); // Iterator it = al.iterator(); // // File f = new File("ipdata.txt"); // try { // if (!f.exists()) { // f.createNewFile(); // } // BufferedWriter out = new BufferedWriter( // new OutputStreamWriter( // new FileOutputStream(f, true) // ) // ); // int i = 0; // while (it.hasNext()) { // out.write(it.next().toString()); // out.newLine(); // i++; // } // out.write(new Date().toString()); // out.write("总共搜索到 " + i); // out.close(); // } catch (IOException e) { // e.printStackTrace(); // } } }
注意事项:QQWry.Dat可以百度从网上下载,但该文件为GBK编码,读取时需要加编码,如代码中红色标注
相关文章推荐
- SQL触发器:根据客户档案中的地区信息自动更新联系页中的省份和城市
- 根据现有IP地址获取其地理位置(省份,城市等)的方法
- 根据不规范填写的地址,城市名自动判断省份,生成省名+城市名的地址栏
- Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)
- 根据现有IP地址获取其地理位置(省份,城市等)的方法
- Js根据Ip地址自动判断是哪个城市
- AJAX根据城市名,自动完成相应的城市信息
- PHP获取IP地址及根据IP判断城市实…
- Java学习笔记之网络编程基础-根据域名自动到DNS上获取IP地址
- 通过新浪IP服务器获得的当前客户端IP地址对应的国家、省份或直辖市、城市信息
- PHP根据IP地址获取所在城市具体实现
- 根据IP地址自动判断转向分站的代码
- ASP自动识别IP,并跳转到来访问者所在的城市
- AJAX根据邮政编码,自动完成城市和地址信息
- 根据IP地址获取所在城市信息
- 新浪接口之PHP根据IP地址获取所在城市
- 选择省份时,自动显示对应省份的城市
- 根据部门和城市自动创建邮箱
- 有没有办法让ifconfig将IP地址保存到某个文件中,然后启动时系统自动根据那个文件配置IP
- PHP根据IP地址获取所在城市具体实现