大家好,今天来为大家解答b站将展示ip属地这个问题的一些问题点,包括b站将展示ip属地什么意思也一样很多人还不知道,因此呢,今天就来为大家分析分析,现在让我们一起来看看吧!如果解决了您的问题,还望您关注下本站哦,谢谢~
我们在刷微博,抖音、B站的时候,在每个评论下面会显示网络用户所在地。国内的用户显示的是省份,国外的用户显示是国家。公开显示网络用户所在地可以提醒用户谨慎发言、治理水军、减少冒充当事人等现象。
那么,这个功能是怎么实现的呢?
Java中获取IP归属地,主要是分为以下两步:
1>通过HttpServletRequest获取Ip2>根据IP查询获取对应的归属地下面我们详细讲解2部内容。1、通过HttpServletRequest获取IPpublicclassIpUtil{nnprivatestaticfinalStringUNKNOWN="unknown";nprivatestaticfinalStringHEADER_FORWARDED="x-forwarded-for";nprivatestaticfinalStringHEADER_PROXY="Proxy-Client-IP";nprivatestaticfinalStringHEADER_WL_PROXY="WL-Proxy-Client-IP";nprivatestaticfinalStringHEADER_HTTP="HTTP_CLIENT_IP";nprivatestaticfinalStringHEADER_HTTP_FORWARDED="HTTP_X_FORWARDED_FOR";nprivatestaticfinalStringLOCAL_IP="127.0.0.1";nprivatestaticfinalStringLOCAL_HOST="localhost";nn/**n*获取IP地址n*n*@paramrequestn*@returnn*/npublicStringgetIpAddr(HttpServletRequestrequest){nStringip=request.getHeader(HEADER_FORWARDED);nnif(ip==null||ip.length()==0||UNKNOWN.equalsIgnoreCase(ip)){nip=request.getHeader(HEADER_PROXY);n}nnif(ip==null||ip.length()==0||UNKNOWN.equalsIgnoreCase(ip)){nip=request.getHeader(HEADER_WL_PROXY);n}nnif(ip==null||ip.length()==0||UNKNOWN.equalsIgnoreCase(ip)){nip=request.getHeader(HEADER_HTTP);n}nnif(ip==null||ip.length()==0||UNKNOWN.equalsIgnoreCase(ip)){nip=request.getHeader(HEADER_HTTP_FORWARDED);n}nnif(ip==null||ip.length()==0||UNKNOWN.equalsIgnoreCase(ip)){nip=request.getRemoteAddr();n}nn//本机访问nif(LOCAL_IP.equalsIgnoreCase(ip)||LOCAL_HOST.equalsIgnoreCase(ip)||"0:0:0:0:0:0:0:1".equalsIgnoreCase(ip)){n//根据网卡取本机配置的IPntry{nInetAddresslocalHost=InetAddress.getLocalHost();nip=localHost.getHostAddress();n}catch(UnknownHostExceptione){ne.printStackTrace();n}n}nn//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割nif(ip!=null&&ip.length()>15){nif(ip.indexOf(",")>15){nip=ip.substring(0,ip.indexOf(","));n}n}nnreturnip;n}n}
2、根据IP查询获取对应的归属地
2.1、第一种实现,参照百度方式实现。
此种会返回json格式:
{"regionCode":"0","regionNames":"","proCode":"510000","err":"","city":"成都市","cityCode":"510100","ip":"218.88.83.8","pro":"四川省","region":"","addr":"四川省成都市电信"}
具体代码实现为:
importcom.alibaba.fastjson.JSONObject;nnimportjava.io.BufferedReader;nimportjava.io.InputStreamReader;nimportjava.net.URL;nimportjava.net.URLConnection;nnnpublicclassAddressUtils{nn//IP地址查询npublicstaticfinalStringIP_URL="http://whois.pconline.com.cn/ipJson.jsp";nn//未知地址npublicstaticfinalStringUNKNOWN="XXXX";nnpublicstaticvoidmain(String[]args){nSystem.out.println(getRealAddressByIP("218.88.83.8"));n}nnpublicstaticStringgetRealAddressByIP(Stringip){n//内网不查询nif(internalIp(ip)){nreturn"内网IP";n}nntry{nStringrspStr=sendGet(IP_URL,"ip="+ip+"&json=true","GBK");nif("".equals(rspStr)){nreturnUNKNOWN;n}nJSONObjectobj=JSONObject.parseObject(rspStr);nreturnobj.toJSONString();n}catch(Exceptione){ne.printStackTrace();n}nnreturnUNKNOWN;n}nnnnpublicstaticbooleaninternalIp(Stringip){nbyte[]addr=textToNumericFormatV4(ip);nreturninternalIp(addr)||"127.0.0.1".equals(ip);n}nnprivatestaticbooleaninternalIp(byte[]addr){nif(addr==null||addr.length<2){nreturntrue;n}nfinalbyteb0=addr[0];nfinalbyteb1=addr[1];n//10.x.x.x/8nfinalbyteSECTION_1=0x0A;n//172.16.x.x/12nfinalbyteSECTION_2=(byte)0xAC;nfinalbyteSECTION_3=(byte)0x10;nfinalbyteSECTION_4=(byte)0x1F;n//192.168.x.x/16nfinalbyteSECTION_5=(byte)0xC0;nfinalbyteSECTION_6=(byte)0xA8;nswitch(b0){ncaseSECTION_1:nreturntrue;ncaseSECTION_2:nif(b1>=SECTION_3&&b1<=SECTION_4){nreturntrue;n}ncaseSECTION_5:nif(b1==SECTION_6){nreturntrue;n}ndefault:nreturnfalse;n}n}n/**n*将IPv4地址转换成字节n*n*@paramtextIPv4地址n*@returnbyte字节n*/npublicstaticbyte[]textToNumericFormatV4(Stringtext){nif(text.length()==0){nreturnnull;n}nnbyte[]bytes=newbyte[4];nString[]elements=text.split("\\.",-1);ntry{nlongl;ninti;nswitch(elements.length){ncase1:nl=Long.parseLong(elements[0]);nif((l<0L)||(l>4294967295L)){nreturnnull;n}nbytes[0]=(byte)(int)(l>>24&0xFF);nbytes[1]=(byte)(int)((l&0xFFFFFF)>>16&0xFF);nbytes[2]=(byte)(int)((l&0xFFFF)>>8&0xFF);nbytes[3]=(byte)(int)(l&0xFF);nbreak;ncase2:nl=Integer.parseInt(elements[0]);nif((l<0L)||(l>255L)){nreturnnull;n}nbytes[0]=(byte)(int)(l&0xFF);nl=Integer.parseInt(elements[1]);nif((l<0L)||(l>16777215L)){nreturnnull;n}nbytes[1]=(byte)(int)(l>>16&0xFF);nbytes[2]=(byte)(int)((l&0xFFFF)>>8&0xFF);nbytes[3]=(byte)(int)(l&0xFF);nbreak;ncase3:nfor(i=0;i<2;++i){nl=Integer.parseInt(elements[i]);nif((l<0L)||(l>255L)){nreturnnull;n}nbytes[i]=(byte)(int)(l&0xFF);n}nl=Integer.parseInt(elements[2]);nif((l<0L)||(l>65535L)){nreturnnull;n}nbytes[2]=(byte)(int)(l>>8&0xFF);nbytes[3]=(byte)(int)(l&0xFF);nbreak;ncase4:nfor(i=0;i<4;++i){nl=Integer.parseInt(elements[i]);nif((l<0L)||(l>255L)){nreturnnull;n}nbytes[i]=(byte)(int)(l&0xFF);n}nbreak;ndefault:nreturnnull;n}n}catch(NumberFormatExceptione){nreturnnull;n}nreturnbytes;n}nnnn/**n*向指定URL发送GET方法的请求n*n*@paramurl发送请求的URLn*@paramparam请求参数,请求参数应该是name1=value1&name2=value2的形式。n*@paramcontentType编码类型n*@return所代表远程资源的响应结果n*/npublicstaticStringsendGet(Stringurl,Stringparam,StringcontentType){nStringBuilderresult=newStringBuilder();nBufferedReaderin=null;ntry{nStringurlNameString=url+"?"+param;nURLrealUrl=newURL(urlNameString);nURLConnectionconnection=realUrl.openConnection();nconnection.setRequestProperty("accept","*/*");nconnection.setRequestProperty("connection","Keep-Alive");nconnection.setRequestProperty("user-agent","Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)");nconnection.connect();nin=newBufferedReader(newInputStreamReader(connection.getInputStream(),contentType));nStringline;nwhile((line=in.readLine())!=null){nresult.append(line);n}n}catch(Exceptione){ne.printStackTrace();n}nfinally{ntry{nif(in!=null){nin.close();n}n}ncatch(Exceptionex){nex.printStackTrace();n}n}nreturnresult.toString();n}n}nn
2.2、第二种实现
根据ip获取对应的归属地的写法很多以及第三方jar也很多,这里我们使用Ip2region第三方jar包。
据官网介绍,Ip2region的极速查询响应即使是完全基于xdb文件的查询,单次查询响应时间在十微秒级别。
引入依赖<dependency>n<groupId>org.lionsoul</groupId>n<artifactId>ip2region</artifactId>n<version>2.6.5</version>n</dependency>下载ip2region.xdb
下载地址为:
https://gitee.com/lionsoul/ip2region/blob/master/data/ip2region.xdb编写工具类
npublicclassIpUtil{nnprivatestaticSearchersearcher;nn/**n*判断是否为合法IPn*@returnn*/npublicstaticbooleancheckIp(StringipAddress){nStringip="([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";nPatternpattern=Pattern.compile(ip);nMatchermatcher=pattern.matcher(ipAddress);nreturnmatcher.matches();n}nn/**n*在服务启动时,将ip2region加载到内存中n*/n@PostConstructnprivatestaticvoidinitIp2Region(){ntry{nInputStreaminputStream=newClassPathResource("/ipdb/ip2region.xdb").getInputStream();nbyte[]bytes=FileCopyUtils.copyToByteArray(inputStream);nsearcher=Searcher.newWithBuffer(bytes);n}catch(Exceptionexception){nexception.printStackTrace();n}n}nn/**n*获取ip所属地址n*n*@paramipipn*@returnn*/npublicstaticStringgetIpRegion(Stringip){nnbooleanisIp=checkIp(ip);nnif(isIp){nninitIp2Region();nntry{n//searchIpInfo的数据格式:国家|区域|省份|城市|ISPnStringsearchIpInfo=searcher.search(ip);nnString[]splitIpInfo=searchIpInfo.split("\\|");nnif(splitIpInfo.length>0){nif("中国".equals(splitIpInfo[0])){n//国内属地返回省份nreturnsplitIpInfo[2];n}elseif("0".equals(splitIpInfo[0])){nif("内网IP".equals(splitIpInfo[4])){n//内网IPnreturnsplitIpInfo[4];n}else{nreturn"";n}n}else{n//国外属地返回国家nreturnsplitIpInfo[0];n}n}nn}catch(Exceptione){ne.printStackTrace();n}nreturn"";n}else{nthrownewIllegalArgumentException("非法的IP地址");n}nn}nn}对于initIp2Region方法,大家可以自定义改造处理下以满足各自的项目场景,也就是不一定要放到resource目录下。测试
@SpringBootTestnpublicclassIpUtilTest{nnprivatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(IpUtilTest.class);nn/**n*测试ip所属地址n*/n@TestnpublicvoidtestGetIpRegion(){nStringip="220.248.12.158";//IpRegion:上海n//Stringip="47.52.236.180";//IpRegion:香港n//Stringip="172.22.12.123";//IpRegion:内网IPn//Stringip="164.114.53.60";//IpRegion:美国nStringipRegion=IpUtil.getIpRegion(ip);nLOGGER.info("IpRegion:{}",ipRegion);n}n}
以上为全部内容。
关于b站将展示ip属地的内容到此结束,希望对大家有所帮助。