SpringBoot项目中获取IP地址

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

OkHttp 是一个由 Square 开发的高效、现代的 HTTP 客户端库,用于 Android 和 Java 应用程序。它支持 HTTP/2 和 SPDY 等现代网络协议,并提供了多种功能和优化,使其成为处理网络请求的流行选择。这次项目中我将会使用OkHttp来发送网络请求


一、OkHttp是什么?

OkHttp 是一个由 Square 开发的高效、现代的 HTTP 客户端库,用于 Android 和 Java 应用程序。

二、使用步骤

1.OkHttp请求代码

package com.easybbs.utils;import com.easybbs.entity.enums.ResponseCodeEnum;
import com.easybbs.exception.BusinessException;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.concurrent.TimeUnit;public class OKHttpUtils {/*** 请求超时时间5秒*/private static final int TIME_OUT_SECONDS = 5;private static Logger logger = LoggerFactory.getLogger(OKHttpUtils.class);private static OkHttpClient.Builder getClientBuilder() {OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder().followRedirects(false).addInterceptor(new RedirectInterceptor()).retryOnConnectionFailure(false);clientBuilder.connectTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS).readTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS);clientBuilder.sslSocketFactory(createSSLSocketFactory()).hostnameVerifier((hostname, session) -> true);return clientBuilder;}private static Request.Builder getRequestBuilder(Map<String, String> header) {Request.Builder requestBuilder = new Request.Builder();if (null != header) {for (Map.Entry<String, String> map : header.entrySet()) {String key = map.getKey();String value;if (map.getValue() == null) {value = "";} else {value = map.getValue();}requestBuilder.addHeader(key, value);}}return requestBuilder;}private static FormBody.Builder getBuilder(Map<String, String> params) {FormBody.Builder builder = new FormBody.Builder();if (params == null) {return builder;}for (Map.Entry<String, String> map : params.entrySet()) {String key = map.getKey();String value;if (map.getValue() == null) {value = "";} else {value = map.getValue();}builder.add(key, value);}return builder;}public static String getRequest(String url) throws BusinessException {ResponseBody responseBody = null;try {OkHttpClient.Builder clientBuilder = getClientBuilder();Request.Builder requestBuilder = getRequestBuilder(null);OkHttpClient client = clientBuilder.build();Request request = requestBuilder.url(url).build();Response response = client.newCall(request).execute();responseBody = response.body();return responseBody.string();} catch (SocketTimeoutException | ConnectException e) {logger.error("OKhttp POST 请求超时,url:{}", url, e);throw new BusinessException(ResponseCodeEnum.CODE_900);} catch (Exception e) {logger.error("OKhttp GET 请求异常", e);return null;} finally {if (responseBody != null) {responseBody.close();}}}public static String postRequest(String url, Map<String, String> header, Map<String, String> params) throws BusinessException {ResponseBody responseBody = null;try {OkHttpClient.Builder clientBuilder = getClientBuilder();Request.Builder requestBuilder = getRequestBuilder(header);FormBody.Builder builder = getBuilder(params);OkHttpClient client = clientBuilder.build();RequestBody requestBody = builder.build();Request request = requestBuilder.url(url).post(requestBody).build();Response response = client.newCall(request).execute();responseBody = response.body();String responseStr = responseBody.string();return responseStr;} catch (SocketTimeoutException | ConnectException e) {logger.error("OKhttp POST 请求超时,url:{}", url, e);throw new BusinessException(ResponseCodeEnum.CODE_900);} catch (Exception e) {logger.error("OKhttp POST 请求异常,url:{}", url, e);return null;} finally {if (responseBody != null) {responseBody.close();}}}private static SSLSocketFactory createSSLSocketFactory() {SSLSocketFactory ssfFactory = null;try {SSLContext sc = SSLContext.getInstance("TLSv1.2");sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());ssfFactory = sc.getSocketFactory();} catch (Exception e) {e.printStackTrace();}return ssfFactory;}}class TrustAllCerts implements X509TrustManager {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}
}class RedirectInterceptor implements Interceptor {private static Logger logger = LoggerFactory.getLogger(RedirectInterceptor.class);@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();Response response = chain.proceed(request);int code = response.code();if (code == 307 || code == 301 || code == 302) {//获取重定向的地址String location = response.headers().get("Location");logger.info("重定向地址,location:{}", location);//重新构建请求Request newRequest = request.newBuilder().url(location).build();response = chain.proceed(newRequest);}return response;}
}

2.获取Ip地址

代码如下(示例):这个代码只能获取到省份地址,具体信息请看下面的详细访问

public String getIpAddress(String ip){try {String url = "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=" + ip;String responseJson = OKHttpUtils.getRequest(url);if(null == responseJson){return Constants.NO_ADDRESS;}Map<String,String> addressInfo = JsonUtils.convertJson2Obj(responseJson,Map.class);return addressInfo.get("pro");}catch (Exception e){logger.error("获取ip地址失败",e);}return Constants.NO_ADDRESS;}

 3.Controller层获取Ip地址

@RequestMapping("/login")public String login(HttpServletRequest request){String ip = getIpAddr(request)return getIpAddress(ip);}/*** 获取客户端IP地址* 由于客户端的IP地址可能通过多个代理层转发,因此需要检查多个HTTP头字段以获取真实IP。* 此方法首先检查“x-forwarded-for”头,这是最常用的代理头,然后尝试其他不那么常见的头字段。* 如果所有尝试都失败,则回退到使用请求的远程地址。** @param request HttpServletRequest对象,用于获取客户端IP地址。* @return 客户端的IP地址字符串。如果无法确定客户端IP,则返回请求的远程地址。*/protected String getIpAddr(HttpServletRequest request) {// 尝试获取“x-forwarded-for”头,这是最常用的代理头字段。String ip = request.getHeader("x-forwarded-for");// 检查“x-forwarded-for”头是否有效,并提取第一个IP地址。if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {// 多次反向代理后会有多个ip值,第一个ip才是真实ipif (ip.indexOf(",") != -1) {ip = ip.split(",")[0];}}// 如果“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.getHeader("X-Real-IP");}// 如果所有代理头字段都无效,回退到使用请求的远程地址作为客户端IP。if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}// 返回获取到的IP地址,无论它是通过代理头还是直接从请求中获取。return ip;}

 获取信息如上,可以自行获取其他信息


总结

本次项目总结如何获取Ip地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/37034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jmeter 进行http接口测试

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 本文主要针对http接口进行测试&#xff0c;使用 jmeter工具实现。 Jmeter工具设计之初是用于做性…

如何用Vue3和Plotly.js绘制动态3D图表?

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Plotly.js: 使用Vue.js动态加载数据并绘制图表 应用场景 在数据可视化应用中&#xff0c;需要将数据动态加载到图表中并进行实时更新。本文将展示如何使用Plotly.js和Vue.js实现这一功能&#xff0c;从加载外…

MobPush iOS端海外推送最佳实现

推送注册 在AppDelegate里进行SDK初始化&#xff08;也可以在Info.plist文件中进行AppKey&#xff0c;AppSecret的配置&#xff09;并对通知功能进行注册以及设置推送的环境和切换海外服务器等&#xff0c;参考如下步骤代码&#xff1a; <span style"background-colo…

【深度学习】图形模型基础(1):使用潜在变量模型进行数据分析的box循环

1.绪论 探索数据背后的隐藏规律&#xff0c;这不仅是数据分析的艺术&#xff0c;更是概率模型展现其威力的舞台。在这一过程中&#xff0c;潜在变量模型尤为关键&#xff0c;它成为了数据驱动问题解决的核心引擎。潜在变量模型的基本理念在于&#xff0c;那些看似复杂、杂乱无…

又是一篇关于GD32堆栈的梳理+FreeRTOS的空间

GD32F103CB&#xff1a;SRAM 20K&#xff08;0x5000&#xff09; 这篇文章主要想讲清楚几个事情&#xff1a; 1、启动文件Stack_Size、Heap_Size的大小设置有啥影响&#xff1b; 2、FreeRTOS的内存&#xff1a;FreeRTOSConfig.h文件configTOTAL_HEAP_SIZE&#xff1b; 问题2…

讯飞星火V4.0 发布,全面对标GPT-4 Turbo

6月27日&#xff0c;讯飞星火V4.0如期而至&#xff0c;升级成为更懂你的AI助手。 七大核心能力持续突破&#xff0c;全面对标GPT-4 Turbo。在8个国际主流测试集中排名第一&#xff0c;讯飞星火以一份惹眼的成绩单&#xff0c;成为国内大模型的先行者。 发布会现场&#xff0c…

用数组模拟栈实现递归函数模拟

做算法课设时候看到题目要求模拟函数递归时候栈的入栈出栈过程。本来想着直接调用系统递归函数即可&#xff0c;可是发现系统函数栈的空间非常小大约只有3000层&#xff0c;很容易爆栈。于是便有了用栈去模拟递归函数的想法&#xff0c;但是上网查了下貌似相关代码比较少&#…

小马搬运物品-第13届蓝桥杯省赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第89讲。 小马搬运物品&…

如何与Honda建立EDI连接?

你是本田Honda的新供应商&#xff0c;需要具备EDI电子数据交换功能吗&#xff1f;在与本田Honda交换EDI消息时需要帮助吗&#xff1f;本文将带你快速了解Honda的EDI需求&#xff0c;明确EDI对接需要完成的工作。 项目背景 本田是一家世界领先的汽车制造商&#xff0c;在全球2…

仓库选址问题【数学规划的应用(含代码)】阿里达院MindOpt

本文主要讲述使用MindOpt工具优化仓库选址的数学规划问题。 视频讲解&#x1f448;&#x1f448;&#x1f448;&#x1f448;&#x1f448;&#x1f448;&#x1f448;&#x1f448;&#x1f448; 一、案例场景 仓库选址问题在现代物流和供应链管理中具有重要的应用。因为仓库…

《数据结构与算法基础 by王卓老师》学习笔记——2.2线性表的案例引入

案例一&#xff1a;一元多项式的运算 案例二&#xff1a;稀疏多项式的运算 案例三&#xff1a;图书信息管理系统 总结

【Leetcode】520. 检测大写字母

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517;我们定义&#xff0c;在以下情况时&#xff0c;单词的大写用法是正确的&#xff1a; 全部字母都是大写&#xff0c;比如 “USA” 。单词中所有字母都不是大写&#xff0c;比如 “le…

同心创建 共践食安 | 赵梦澈荣获食品安全大使

“民族要复兴&#xff0c;乡村必振兴”&#xff0c;为深入贯彻落实国家乡村振兴战略&#xff0c;推进乡村全面振兴不断取得新成效&#xff0c;助力全国优质食品农产品的宣传推广、市场营销、品牌创建工作&#xff0c;由中国食品安全报社主办&#xff0c;商业发展中心、健康中国…

python数据分析与可视化一

公共部分 # 引入数据分析工具 Pandas import pandas as pd # 引入数据可视化工具 Matplotlib import matplotlib.pyplot as plt # 引入数据可视化工具 Seaborn (基于matplotlib) import seaborn as sns # 解决输出时的列名对齐问题 pd.set_option(display.unicode.east_…

如何申请免费SSL证书以消除访问网站显示连接不安全提醒

在当今互联网时代&#xff0c;网络安全已成为一个不可忽视的问题。当用户浏览一些网站时&#xff0c;有时会看到浏览器地址栏出现“不安全”的提示&#xff0c;这意味着该网站没有安装SSL证书&#xff0c;数据传输可能存在风险。那么&#xff0c;如何消除这种不安全提醒&#x…

仓库管理系统16--入库管理

原创不易&#xff0c;打字不易&#xff0c;截图不易&#xff0c;多多点赞&#xff0c;送人玫瑰&#xff0c;留有余香&#xff0c;财务自由明日实现。 1、创建物资入库用户控件 <UserControl x:Class"West.StoreMgr.View.InStoreView"xmlns"http://schema…

CAS自旋解析

CAS全称CompareAndSwap(比较并交换)&#xff0c;是cpu的指令&#xff0c;调用时不涉及上下文的切换。Java中属于乐观锁的一种&#xff0c;具体流程如下图&#xff1a; 具体的实现使用的是Unsafe类去调用native修饰的compareAndSwap方法&#xff0c;4个字段分别是对象实例&#…

PTA—C语言期末复习(判断题)

1. C语言程序是从源文件的第一条语句开始执行的 &#xff08;F&#xff09; 在 C 语言中&#xff0c;程序是从 main 函数开始执行的&#xff0c;而不是从源文件的第一条语句开始执行 2. 若变量定义为double x;&#xff0c;则x % 2是符合C语言语法的表达式 &#xff08;F&#…

HTML流星雨

目录 写在前面 完整代码 代码分析 系列文章 写在最后 写在前面 岁月如梭&#xff0c;光阴似箭&#xff0c;不知不觉暑假就要来喽&#xff0c;本期小编用HTML给大家手搓了一个炫酷的流星雨动画&#xff0c;一起来看看吧。 完整代码 <!DOCTYPE html> <html lang…

项目风险管理系统有哪些?分享11款主流项目管理系统

本文将分享11款主流项目管理系统&#xff1a;PingCode、Worktile、StandardFusion、MasterControl、ClickUp、SAI360、Netwrix Auditor、MetricStream、Wrike、Celoxis、Zoho Projects。 在项目管理中&#xff0c;风险管理不仅是一个挑战&#xff0c;也是保证项目顺利进行的关键…