Java利用Request请求如何获取IP地址对应的省份、城市详解
前言
最近的一个项目中需要将不同省份的用户,展示不同内容,所以需要通过request请求获取ip地址, 然后通过ip获取ip对应省份。
这里的操作步骤一共有步:
1. 通过request获取ip
2. 通过ip获取对应省份、城市
3. 通过设置的省份和ip对应省份进行比对,展示内容
通过request获取ip
可以参考我的另外一篇文章【java 通过request请求获取ip地址】下面是代码:
public class ipadrressutil { /** * 获取ip地址 * @param request * @return */ private static string getipadrress(httpservletrequest request) { string xip = request.getheader("x-real-ip"); string xfor = request.getheader("x-forwarded-for"); if(stringutils.isnotempty(xfor) && !"unknown".equalsignorecase(xfor)){ //多次反向代理后会有多个ip值,第一个ip才是真实ip int index = xfor.indexof(","); if(index != -1){ return xfor.substring(0,index); }else{ return xfor; } } xfor = xip; if(stringutils.isnotempty(xfor) && !"unknown".equalsignorecase(xfor)){ return xfor; } if (stringutils.isblank(xfor) || "unknown".equalsignorecase(xfor)) { xfor = request.getheader("proxy-client-ip"); } if (stringutils.isblank(xfor) || "unknown".equalsignorecase(xfor)) { xfor = request.getheader("wl-proxy-client-ip"); } if (stringutils.isblank(xfor) || "unknown".equalsignorecase(xfor)) { xfor = request.getheader("http_client_ip"); } if (stringutils.isblank(xfor) || "unknown".equalsignorecase(xfor)) { xfor = request.getheader("http_x_forwarded_for"); } if (stringutils.isblank(xfor) || "unknown".equalsignorecase(xfor)) { xfor = request.getremoteaddr(); } return xfor; } }
通过ip获取对应省份、城市
使用【geolite2 city】库
目前开源的ip地址库与城市对应关系用的比较多的是maxmind公司的geolite数据库,geolite数据库有开源版本和收费版本,我们使用的是开源版本,geolite目前已经更新到2了,所以我们下载geolite2 city库。
官方下载地址是【】
本地下载地址是【http://xiazai.jb51.net/201710/yuanma/geolite2-city_20171003(jb51.net).rar】
如果觉得慢就用迅雷下。下载完成后就是,下载完成就解压。得到【geolite2-city.mmdb】文件,这个就是数据库。
java例子是这样使用的:
首先在项目中加入maven支持
<dependency> <groupid>com.maxmind.geoip2</groupid> <artifactid>geoip2</artifactid> <version>2.8.1</version> </dependency>
然后通过geolite2查询得到省份、城市:
public static void main(string[] args) throws exception{ // 创建 geolite2 数据库 file database = new file("/users/admin/geolite2-city.mmdb"); // 读取数据库内容 databasereader reader = new databasereader.builder(database).build(); inetaddress ipaddress = inetaddress.getbyname("171.108.233.157"); // 获取查询结果 cityresponse response = reader.city(ipaddress); // 获取国家信息 country country = response.getcountry(); system.out.println(country.getisocode()); // 'cn' system.out.println(country.getname()); // 'china' system.out.println(country.getnames().get("zh-cn")); // '中国' // 获取省份 subdivision subdivision = response.getmostspecificsubdivision(); system.out.println(subdivision.getname()); // 'guangxi zhuangzu zizhiqu' system.out.println(subdivision.getisocode()); // '45' system.out.println(subdivision.getnames().get("zh-cn")); // '广西壮族自治区' // 获取城市 city city = response.getcity(); system.out.println(city.getname()); // 'nanning' postal postal = response.getpostal(); system.out.println(postal.getcode()); // 'null' system.out.println(city.getnames().get("zh-cn")); // '南宁' location location = response.getlocation(); system.out.println(location.getlatitude()); // 22.8167 system.out.println(location.getlongitude()); // 108.3167 }
如果是生产环境,可以直接创建一个service,在service初始化的时候创建reader对象,然后在公共方法中通过ip查询地址,下面以省份为例:
import com.maxmind.geoip2.databasereader; import com.maxmind.geoip2.model.cityresponse; import org.apache.commons.lang3.stringutils; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.beans.factory.annotation.autowired; import org.springframework.core.env.environment; import org.springframework.stereotype.service; import javax.annotation.postconstruct; import java.io.file; import java.net.inetaddress; /** * ip地址服务 */ @service public class ipaddressservice { private static logger logger = loggerfactory.getlogger(ipaddressservice.class); private static string dbpath = "/usr/local/geolite2-city.mmdb"; private static databasereader reader; @autowired private environment env; @postconstruct public void init() { try { string path = env.getproperty("geolite2.city.db.path"); if (stringutils.isnotblank(path)) { dbpath = path; } file database = new file(dbpath); reader = new databasereader.builder(database).build(); } catch (exception e) { logger.error("ip地址服务初始化异常:" + e.getmessage(), e); } } public string getsubdivision(string ipaddress){ try { cityresponse response = reader.city(inetaddress.getbyname(ipaddress)); return response.getmostspecificsubdivision().getnames().get("zh-cn"); }catch (exception e){ logger.error("根据ip[{}]获取省份失败:{}", ipaddress, e.getmessage()); return null; } } }
然后在需要的地方就行判断:
string areanames = {"北京","天津","上海"}; string subdivision = ipaddressservice.getsubdivision(getipadrress(request)); // 匹配 if(containsarea(subdivision, areanames)){ // 处理... }
匹配方法:
private boolean containsarea(string name, string[] areanames) { if(stringutils.isblank(name)){ return false; } for(string areaname : areanames){ if(name.contains(areaname)){ return true; } } return false; // 按地域返回数据 }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
上一篇: iOS中利用inputView 弹出 picker
下一篇: upload上传单张图片