SpringBoot獲取訪問介面裝置的ip地址以及裝置型別

原文連線:https://blog。csdn。net/lovely__RR/article/details/109315369

1。前言

相信大家都看到別人寫的專案裡面都有日誌管理這一塊,就如下圖所示:

SpringBoot獲取訪問介面裝置的ip地址以及裝置型別

可以看到基本上日誌這一塊都是會顯示訪問裝置的ip地址的,所以自己今天也是嘗試了一下,試了一下,發現還是比較簡單的,中間也出現了一些小的問題,我也會在下面提到。希望能夠對你有幫助。

不說廢話,直接上程式碼

2。步驟

2。1裝置ip

2。1。1首先建立獲取ip地址的工具類IpUtil

package ams。web。device。util;import lombok。extern。slf4j。Slf4j;import javax。servlet。http。HttpServletRequest;import java。net。*;import java。util。Enumeration;@Slf4jpublic class IpUtil { private static final String LOCAL_IP = “127。0。0。1”; /** * 獲取IP地址 * * 使用Nginx等反向代理軟體, 則不能透過request。getRemoteAddr()獲取IP地址 * 如果使用了多級反向代理的話,X-Forwarded-For的值並不止一個,而是一串IP地址,X-Forwarded-For中第一個非unknown的有效IP字串,則為真實IP地址 */ public static String getIpAddr(HttpServletRequest request) { if (request == null) { return “unknown”; } 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(“X-Forwarded-For”); } 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(“X-Real-IP”); } if (ip == null || ip。length() == 0 || “unknown”。equalsIgnoreCase(ip)) { ip = request。getRemoteAddr(); } return “0:0:0:0:0:0:0:1”。equals(ip) ? LOCAL_IP : ip; } public static boolean internalIp(String ip) { boolean res = false; byte[] addr = textToNumericFormatV4(ip); if (addr != null && ip != null) { res = internalIp(addr) || LOCAL_IP。equals(ip); } return res; } private static boolean internalIp(byte[] addr) { final byte b0 = addr[0]; final byte b1 = addr[1]; // 10。x。x。x/8 final byte SECTION_1 = 0x0A; // 172。16。x。x/12 final byte SECTION_2 = (byte) 0xAC; final byte SECTION_3 = (byte) 0x10; final byte SECTION_4 = (byte) 0x1F; // 192。168。x。x/16 final byte SECTION_5 = (byte) 0xC0; final byte SECTION_6 = (byte) 0xA8; boolean flag = false; switch (b0) { case SECTION_1: flag = true; break; case SECTION_2: if (b1 >= SECTION_3 && b1 <= SECTION_4) { flag = true; } break; case SECTION_5: if (b1 == SECTION_6) { flag = true; } break; default: break; } return flag; } /** * 將IPv4地址轉換成位元組 *IPv4地址 * @param text * @return byte 位元組 */ public static byte[] textToNumericFormatV4(String text) { if (text。length() == 0) { return null; } byte[] bytes = new byte[4]; String[] elements = text。split(“\\。”, -1); try { long l; int i; switch (elements。length) { case 1: l = Long。parseLong(elements[0]); if ((l < 0L) || (l > 4294967295L)) return null; bytes[0] = (byte) (int) (l >> 24 & 0xFF); bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); bytes[3] = (byte) (int) (l & 0xFF); break; case 2: l = Integer。parseInt(elements[0]); if ((l < 0L) || (l > 255L)) return null; bytes[0] = (byte) (int) (l & 0xFF); l = Integer。parseInt(elements[1]); if ((l < 0L) || (l > 16777215L)) return null; bytes[1] = (byte) (int) (l >> 16 & 0xFF); bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); bytes[3] = (byte) (int) (l & 0xFF); break; case 3: for (i = 0; i < 2; ++i) { l = Integer。parseInt(elements[i]); if ((l < 0L) || (l > 255L)) return null; bytes[i] = (byte) (int) (l & 0xFF); } l = Integer。parseInt(elements[2]); if ((l < 0L) || (l > 65535L)) return null; bytes[2] = (byte) (int) (l >> 8 & 0xFF); bytes[3] = (byte) (int) (l & 0xFF); break; case 4: for (i = 0; i < 4; ++i) { l = Integer。parseInt(elements[i]); if ((l < 0L) || (l > 255L)) return null; bytes[i] = (byte) (int) (l & 0xFF); } break; default: return null; } } catch (NumberFormatException e) { log。error(“數字格式化異常”,e); return null; } return bytes; } public static String getLocalIP() { String ip = “”; if (System。getProperty(“os。name”)。toLowerCase()。startsWith(“windows”)) { InetAddress addr; try { addr = InetAddress。getLocalHost(); ip = addr。getHostAddress(); } catch (UnknownHostException e) { log。error(“獲取失敗”,e); } return ip; } else { try { Enumeration<?> e1 = (Enumeration<?>) NetworkInterface 。getNetworkInterfaces(); while (e1。hasMoreElements()) { NetworkInterface ni = (NetworkInterface) e1。nextElement(); if (!ni。getName()。equals(“eth0”)) { continue; } else { Enumeration<?> e2 = ni。getInetAddresses(); while (e2。hasMoreElements()) { InetAddress ia = (InetAddress) e2。nextElement(); if (ia instanceof Inet6Address) continue; ip = ia。getHostAddress(); return ip; } break; } } } catch (SocketException e) { log。error(“獲取失敗”,e); } } return “”; }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190

2。1。2在controller中測試使用

@GetMapping(“/testipaddress”)public String queryAllByHour(HttpServletRequest request) { String ip = IpUtil。getIpAddr(request); return ip;}12345

這樣我們便能獲取到訪問介面裝置的ip地址了。

為了測試他的真實性,我透過電腦和手機分別訪問了一下我的介面,發現的確是能夠識別的,如下圖所示:

電腦訪問介面

SpringBoot獲取訪問介面裝置的ip地址以及裝置型別

手機訪問介面

SpringBoot獲取訪問介面裝置的ip地址以及裝置型別

資料庫中插入的資料

SpringBoot獲取訪問介面裝置的ip地址以及裝置型別

可以看到這裡的確將裝置的ip地址讀取到了。

有一個

小BUG

,但是大家仔細看時間那一塊會發現,好像上面的時間都比最下的一個時間慢了8個小時,這個主要是我們設定的時區有問題,修改application。yaml檔案中這兩處配置即可解決問題:

datasource: driver-class-name: com。mysql。cj。jdbc。Driver url: jdbc:mysql://ip地址:3306/資料庫?useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=utf-8#serverTimezone修改成東八區即可jackson: time-zone: GMT+812345

獲取到裝置的IP地址之後,我又想了想能不能獲取到裝置型別了,查閱了網上的資料發現,spring已經幫我們整合好了一個外掛,我們引用進來,配置一下就可以直接用了,不多說了,spring牛逼。

2。2裝置型別

2。2。1匯入依賴

org。springframework。mobile spring-mobile-device 1。1。3。RELEASE12345

2。2。2將Bean注入spring容器之中

一般是在你的MVC配置檔案新增以下程式碼

@Beanpublic DeviceResolverHandlerInterceptor deviceResolverHandlerInterceptor() { return new DeviceResolverHandlerInterceptor();}@Beanpublic DeviceHandlerMethodArgumentResolverdeviceHandlerMethodArgumentResolver() { return new DeviceHandlerMethodArgumentResolver();}@Overridepublic void addInterceptors(InterceptorRegistry registry) { registry。addInterceptor(new DeviceResolverHandlerInterceptor());}@Overridepublic void addArgumentResolvers(List argumentResolvers) { argumentResolvers。add(new DeviceHandlerMethodArgumentResolver());}1234567891011121314151617181920

2。2。3編寫獲取裝置型別的工具類DeviceUtil

import org。springframework。mobile。device。Device;public class DeviceUtil { public static String getdevice(Device device){ if (device。isMobile()) { System。out。println(“========請求來源裝置是手機!========”); return “手機”; } else if (device。isTablet()) { System。out。println(“========請求來源裝置是平板!========”); return “平板”; } else if(device。isNormal()){ System。out。println(“========請求來源裝置是PC!========”); return “PC”; }else { System。out。println(“========請求來源裝置是其它!========”); return “其他”; } }}123456789101112131415161718

2。2。4在controller中測試

@GetMapping(“/testdevice”)public String testdevice(Device device) { String name=DeviceUtil。getdevice(device); return name;}12345

PC端測試

SpringBoot獲取訪問介面裝置的ip地址以及裝置型別

手機端測試

SpringBoot獲取訪問介面裝置的ip地址以及裝置型別