欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java利用Request请求如何获取IP地址对应的省份、城市详解

程序员文章站 2024-04-02 09:46:58
前言 最近的一个项目中需要将不同省份的用户,展示不同内容,所以需要通过request请求获取ip地址, 然后通过ip获取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

Java利用Request请求如何获取IP地址对应的省份、城市详解

如果觉得慢就用迅雷下。下载完成后就是,下载完成就解压。得到【geolite2-city.mmdb】文件,这个就是数据库。

Java利用Request请求如何获取IP地址对应的省份、城市详解

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; // 按地域返回数据
 }

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。