根据IP地址自动识别省份城市

来源:互联网 发布:java shiro盐值加密 编辑:程序博客网 时间:2024/05/02 01:53


功能说明:需要获取客户端的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 + 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编码,读取时需要加编码,如代码中红色标注

0 0
原创粉丝点击