前言

  日常开发中,获取ip是常用的功能,本文记录如何在Java中获取本机外网ip、地理位置,访问用户的外网ip、地理位置,以及指定外网ip的地理位置;

  代码编写

  1、获取访问用户外网ip,我们从访问者的HttpServletRequest中获取(注:要外网访问才能获取到外网地址,如果你在局域网甚至本机上访问,获得的是内网或者本机的ip)

  2、获取本机外网ip、地理位置以及指定外网ip的地理位置,我们调用太平洋网络IP地址查询Web接口(http://whois.pconline.com.cn/),返回ip、地理位置

  太平洋网络IP地址查询接口丰富,参数设置多样齐全,总有一款适合我们的需求

  我们使用的就是第二个返回json(http://whois.pconline.com.cn/ipJson.jsp?json=true),如果要查询指定ip,就拼上&ip=

  Vo类

  根据接口返回的数据,封装IpVo类,以方便接参转换实体

        //太平洋接口返回数据格式
/*
{
ip: "58.63.47.115",
pro: "广东省",
proCode: "440000",
city: "广州市",
cityCode: "440100",
region: "天河区",
regionCode: "440106",
addr: "广东省广州市天河区 电信",
regionNames: "",
err: ""
}
*/

  IpVo.java

import lombok.Data;

/**
* ip
*/
@Data
public class IpVo {
private String ip;//IP地址
private String pro;//省
private String proCode;//省编码
private String city;//城市
private String cityCode;//城市编码
private String region;//区
private String regionCode;//区编码
private String addr;//详细地址 + 运营商 //主要用于接参,无实际意义
private String regionNames;
private String err;
}

  工具类

  封装工具类

import cn.huanzi.qch.baseadmin.common.pojo.IpVo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat; /**
* IP工具类
*/
@Slf4j
public class IpUtil {
/**
* 获取访问者的ip地址
* 注:要外网访问才能获取到外网地址,如果你在局域网甚至本机上访问,获得的是内网或者本机的ip
*/
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = null;
try {
//X-Forwarded-For:Squid 服务代理
String ipAddresses = request.getHeader("X-Forwarded-For"); if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
//Proxy-Client-IP:apache 服务代理
ipAddresses = request.getHeader("Proxy-Client-IP");
} if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
//WL-Proxy-Client-IP:weblogic 服务代理
ipAddresses = request.getHeader("WL-Proxy-Client-IP");
} if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
//HTTP_CLIENT_IP:有些代理服务器
ipAddresses = request.getHeader("HTTP_CLIENT_IP");
} if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
//X-Real-IP:nginx服务代理
ipAddresses = request.getHeader("X-Real-IP");
} //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
if (ipAddresses != null && ipAddresses.length() != 0) {
ipAddress = ipAddresses.split(",")[0];
} //还是不能获取到,最后再通过request.getRemoteAddr();获取
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
ipAddress = request.getRemoteAddr();
}
} catch (Exception e) {
ipAddress = "";
}
return ipAddress;
} /**
* 调用太平洋网络IP地址查询Web接口(http://whois.pconline.com.cn/),返回ip、地理位置
*/
public static IpVo getIpVo(String ip){
//查本机
String url = "http://whois.pconline.com.cn/ipJson.jsp?json=true"; //查指定ip
if(!StringUtils.isEmpty(ip)){
url = "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=" + ip;
} StringBuilder inputLine = new StringBuilder();
String read;
try {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestProperty("Charset", "GBK");
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "GBK"));
while ((read = in.readLine()) != null) {
inputLine.append(read);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
} //返回格式
/*
{
ip: "58.63.47.115",
pro: "广东省",
proCode: "440000",
city: "广州市",
cityCode: "440100",
region: "天河区",
regionCode: "440106",
addr: "广东省广州市天河区 电信",
regionNames: "",
err: ""
}
*/ IpVo ipVo = null;
try {
ObjectMapper mapper = new ObjectMapper();
//当属性的值为空(null或者"")时,不进行序列化,可以减少数据传输
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
//设置日期格式
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
//转换成IpVo
ipVo = mapper.readValue(new String(inputLine.toString().getBytes("GBK"), "GBK"), IpVo.class);
} catch (IOException e) {
e.printStackTrace();
}
return ipVo;
} /**
* 直接根据访问者的Request,返回ip、地理位置
*/
public static IpVo getIpVoByRequest(HttpServletRequest request){
return IpUtil.getIpVo(IpUtil.getIpAddr(request));
} /*
终极大法:java获取不了,就用js来获取
<!-- js获取客户ip -->
<script src="http://whois.pconline.com.cn/ipJson.jsp"></script>
*/ /*//测试
public static void main(String[] args) {
//获取本机ip
System.out.println(getIpVo(null)); //获取指定ip
System.out.println(getIpVo("115.48.58.106"));
}*/
}

  效果演示

  放开注释,运行main方法

    //测试
public static void main(String[] args) {
//获取本机ip
System.out.println(getIpVo(null)); //获取指定ip
System.out.println(getIpVo("115.48.58.106"));
}

  后记

  ip获取暂时记录到这,后续再进行补充

  代码开源

  注:数据库文件在resources/static/sql目录下面

  代码已经开源、托管到我的GitHub、码云:

  GitHub:https://github.com/huanzi-qch/base-admin

  码云:https://gitee.com/huanzi-qch/base-admin

Java 获取IP工具类、Vo类整理记录的更多相关文章

  1. 系统获取 IP 工具类

    系统获取 IP 工具类 import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterf ...

  2. Java获取ip地址的几种方法

    以下内容介绍下java获取ip地址的几种思路. 1.直接利用java.net.InetAddress类获取,不过这种方法只在windows环境下有效,在linux环境下只能获取localhost地址( ...

  3. java获取IP地址

    最近在一个多系统集成的项目中,由于跳转路径含IP地址,每次IP改了重启项目都得改好多地方,甚是麻烦.刚在网上了解到java获取IP地址,给大家分享下: 首先要导入jar包 request.getRem ...

  4. Java 获取 IP

    /** * 获取访问者IP. * 在一般情况下使用 Request.getRemoteAddr() 即可,但是经过 nginx 等反向代理软件后,这个方法会失效. */ private String ...

  5. 手把手教你用Java获取IP归属地

    前几个月微信公众号上线了IP归属地的功能,后续知乎.抖音等平台纷纷添加了该功能.如果是国内的用户精确到省份,国外用户精确到国家.本文就使用Java实现获取IP归属地. ! 主要讲解几个步骤: Java ...

  6. Java获取IP地址,IpUtils工具类,Java IP地址获取

    ================================ ©Copyright 蕃薯耀 2020-01-17 https://www.cnblogs.com/fanshuyao/ import ...

  7. java 获取ip地址和网络接口

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  8. Java获取Ip发送邮件

    import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import javax.servlet. ...

  9. MAC地址,使用java获取IP地址和MAC地址。

    MAC地址,通常在http连接的项目中,来区分唯一客户端. MAC:六组十六进制字符组成. 如:E0-3F-49-AB-DB-EB IP:四组八位的二进制字符组成. 如:10.6.62.244 /** ...

随机推荐

  1. NetCore项目实战篇02---全局异常处理

    在 .netcore中可以自定义自己的异常类型,步骤如下: 1.自定义自己的异常类型UserOperationException 并继承自Exception public class UserOper ...

  2. Codeforce 1155D Beautiful Array(DP)

    D. Beautiful Array You are given an array aa consisting of nn integers. Beauty of array is the maxim ...

  3. django源码解读——runserver分析

    开始之前建议先参考一下这篇文章:https://blog.csdn.net/qq_33339479/article/details/78862156class Command(BaseCommand) ...

  4. php扩展开发之hello world

    最近在公司做的事情就是php扩展开发,虽然我只负责c++代码的编写,但是了解扩展开发的流程还是很有必要的. (本文介绍的是动态扩展,对静态扩展有兴趣的读者可自行google) php扩展开发环境搭建可 ...

  5. nodejs开发准备工作(1)

    nvm工具(node版本管理工具) (1) 下载nvm: https://github.com/coreybutler/nvm-windows/releases: (2) 推荐下载压缩包,解压安装就好 ...

  6. 对文本的内容进行排序(io流、集合操作)

    package com.itheima.demo01.BufferedStream; import java.io.*; import java.util.HashMap; /* 练习: 对文本的内容 ...

  7. Fibonacci数列的性质

    Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13, .... F[0] = 0; 1: gcd(Fn, Fm) = F[gcd(n, m)]; 当n - m = 1 或 2时满足, ...

  8. js日期格式与时间戳相互转换

    本文转自:https://blog.csdn.net/Lc_style/article/details/80626748 1.将日期格式转化为时间戳: var date = new Date('201 ...

  9. Win32 Sdk 连接Access数据库

    /************************************************************* *** MyWinClass.cpp 创建窗口模板 *** vs2017+ ...

  10. 当Tomcat遇上Netty

    故事背景 嘀嘀嘀~,生产事故,内存泄漏! 昨天下午,突然收到运维的消息,分部某系统生产环境内存泄漏了,帮忙排查一下. 排查过程 第一步,要日志 分部给到的异常日志大概是这样(鉴于公司规定禁止截图禁止拍 ...