燃爆了(java 获取ip地址)java中获取ip地址的方法,手把手教你用Java获取IP归属地,java获取服务器ip地址,
前几个月微信公众号上线了 IP归属地 的功能,后续知乎、抖音等平台纷纷添加了该功能。如果是国内的用户精确到省份,国外用户精确到国家。本文就使用 Java 实现获取 IP归属地 。
主要讲解几个步骤:
Java 获取请求 IP解决 Nginx 转发问题通过 IP 地址获取归属地获取IP地址
首先使用基于 Spring Boot搭建项目,在controller 添加 HttpServletRequest 请求参数:
@RestControllerpublic class IpController {@GetMapping("/ip-address")public String ipAddress(HttpServletRequest request) {// 接收request }}通过 HttpServletRequest 获取 IP地址 :
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();}return ip;在本地环境调用获取IP,要么是 0:0:0:0:0:0:0:1 ,或者是局域网 IP 。
局域网 IP 是以 192.168.x.x 开头,或者是 127.0.0.1 的 IP 。
所以需要部署到外网服务器 才能获取到公网地址。部署到外网的服务器能成功获取 IP 地址。
Nginx 反向代理问题
直接访问公网服务器地址能成功获取 IP 地址,但是通过 Nginx 反向代理获取的都是 127.0.0.1 。客户端请求 Nginx 服务器再反向代理转发到服务端,此时拿到的 IP 反向代理的 IP ,也就是 Nginx服务器的IP ,并不是真正的客户端 IP 。
在 Nginx 的配置文件中的 location 模块添加以下配置,将客户端的 IP 传入到 Nginx 服务:
proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;示例:
server {listen 80;server_name localhost;location / {proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://xxxx;}完成以上操作之后,就能成功获取到 IP 了。然后通过 IP 获取归属地了。
IP获取归属地
通过 IP 获取归属地一般都是从地址库找到匹配的地址,本文介绍两种方法.
通过归属地API获取
需要发起 http 请求,这里使用 Spring Boot 的 RestTemplate 发起 http 请求,首先创建 RestTemplate 的 bean 实例:
@Configurationpublic class RestTemplateConfig {@Beanpublic RestTemplate restTemplate() {return newRestTemplate();}}再调用 RestTemplate 发起 http 请求:
private String URL = "https://api.beijinxuetang.com/api/common/ip";JSONObject jsonObject = newJSONObject();jsonObject.put("ip",ip);JSONObject json = restTemplate.postForObject(URL,jsonObject, JSONObject.class);if (json.getInteger("code") == 0) {json = json.getJSONObject("data");// 国家String nation = json.getString("nation");// 省份String province = json.getString("province");// 市Stringcity = json.getString("city");}上面的 json 是引入 fastjson 。
通过地址库获取
使用 API接口 ,可能会出现服务挂了,或者服务地址不提供服务了等问题。而采用本地地址库就没有这些问题。
本文采用离线 IP 地址定位库 Ip2region , Ip2region 是一个离线 IP 地址定位库,微秒的查询时间:
首先找到在 gihub官网 找到地址库ip2region.xdb ,具体路径为 data/ip2region.xdb :
将 ip2region.xdb 放在项目的 resources 目录下:
引入 maven 依赖:
<dependency><groupId>org.lionsoul</groupId><artifactId>ip2region</artifactId><version>2.6.5</version></dependency>获取归属地:
private Searcher searcher;@Overridepublic String getIpAddress(String ip){if ("127.0.0.1".equals(ip) || ip.startsWith("192.168")) {return "局域网 ip";}if (searcher == null) {try {File file = ResourceUtils.getFile("classpath:ipdb/ip2region.xdb");String dbPath = file.getPath();searcher = Searcher.newWithFileOnly(dbPath);} catch(FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}}String region = null;String errorMessage = null;try{region = searcher.search(ip);}catch (Exception e) {errorMessage = e.getMessage();if (errorMessage != null && errorMessage.length() > 256) {errorMessage = errorMessage.substring(0,256);}e.printStackTrace();}// 输出 region}获取 region 就能获取到 IP 归属地了。例如 中国|0|广东省|广州市|电信 。
本文系作者 @河马 原创发布在河马博客站点。未经许可,禁止转载。
暂无评论数据