SpringBoot?UserAgentUtils獲取用戶(hù)瀏覽器的用法
介紹
UserAgentUtils 是于處理用戶(hù)代理(User-Agent)字符串的工具類(lèi),一般用于解析和處理瀏覽器、操作系統(tǒng)以及設(shè)備等相關(guān)信息,這些信息通常包含在接口請(qǐng)求的 User-Agent 字符串中。
這個(gè)庫(kù)可以用于解析用戶(hù)代理頭,以提取有關(guān)所使用的瀏覽器、瀏覽器版本、平臺(tái)、平臺(tái)版本和設(shè)備類(lèi)型的信息。對(duì)于確定客戶(hù)端是否是臺(tái)式機(jī)、平板電腦或移動(dòng)設(shè)備,或者客戶(hù)端是否在Windows或Mac OS上(僅舉幾例)非常有用。
- 超過(guò)150種不同的瀏覽器;
- 7種不同的瀏覽器類(lèi)型;
- 超過(guò)60種不同的操作系統(tǒng);
- 6種不同的設(shè)備類(lèi)型;
- 9種不同的渲染引擎;
- 9種不同的Web應(yīng)用,如HttpClient、Bot。
官方文檔:https://www.bitwalker.eu/software/user-agent-utils
Github:https://github.com/HaraldWalker/user-agent-utils/tree/release-1.21
特別注意該項(xiàng)目已停止了維護(hù),但是功能還是挺好用的

效果圖

依賴(lài)
<!--解析瀏覽器字符串-->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.21</version>
</dependency>
<!--字符串工具-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<!--提供了大量的工具類(lèi),更方便地進(jìn)行字符串、日期、集合、反射等操作。-->封裝客戶(hù)端工具
public class ClientUtils {
/**
* 獲取當(dāng)前線程的請(qǐng)求
*/
public static ServletRequestAttributes getRequestAttributes()
{
//獲取當(dāng)前線程的請(qǐng)求
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
//提供了更具體的 Servlet 請(qǐng)求屬性
return (ServletRequestAttributes) attributes;
}
/**
* 獲取request信息
*/
public static HttpServletRequest getRequest()
{
return getRequestAttributes().getRequest();
}
}封裝IP工具
public class IpUtils {
/**
* 獲取客戶(hù)端IP
*
* @return IP地址
*/
public static String getIpAddr()
{
return getIpAddr(ClientUtils.getRequest());
}
/**
* 獲取客戶(hù)端IP
*
* @param request 請(qǐng)求對(duì)象
* @return 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) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
}
/**
* 從多級(jí)反向代理中獲得第一個(gè)非unknown IP地址
*
* @param ip 獲得的IP地址
* @return 第一個(gè)非unknown IP地址
*/
public static String getMultistageReverseProxyIp(String ip)
{
// 多級(jí)反向代理檢測(cè)
if (ip != null && ip.indexOf(",") > 0)
{
final String[] ips = ip.trim().split(",");
for (String subIp : ips)
{
if (false == isUnknown(subIp))
{
ip = subIp;
break;
}
}
}
return StringUtils.substring(ip, 0, 255);
}
/**
* 檢測(cè)給定字符串是否為未知,多用于檢測(cè)HTTP請(qǐng)求相關(guān)
*
* @param checkString 被檢測(cè)的字符串
* @return 是否未知
*/
public static boolean isUnknown(String checkString)
{
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
}
}實(shí)體類(lèi)
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("login_log")
public class LoginLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 編號(hào)
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 用戶(hù)名稱(chēng)
*/
@TableField("user_name")
private String userName;
/**
* IP
*/
@TableField("ip")
private String ip;
/**
* 瀏覽器
*/
@TableField("browser")
private String browser;
/**
* 操作系統(tǒng)
*/
@TableField("platform")
private String platform;
/**
* 登錄時(shí)間
*/
@TableField("login_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String loginTime;
}獲取設(shè)備信息入庫(kù)
public void recordLogin(LoginLog loginLog){
//獲取當(dāng)前線程中的請(qǐng)求
String s = ClientUtils.getRequest().getHeader("User-Agent");
//反向代理中獲取IP
loginLog.setIp(IpUtils.getIpAddr());
//異步執(zhí)行
CompletableFuture.runAsync(() -> {
// 獲取當(dāng)前線程請(qǐng)求頭的 "User-Agent"
UserAgent userAgent = UserAgent.parseUserAgentString(s);
// 獲取使用的瀏覽器
loginLog.setBrowser(userAgent.getBrowser().getName());
// 獲取使用的操作系統(tǒng)
loginLog.setPlatform(userAgent.getOperatingSystem().getName());
//數(shù)據(jù)入庫(kù)
mapper.insert(loginLog);
});
}效果圖

到此這篇關(guān)于SpringBoot UserAgentUtils獲取用戶(hù)瀏覽器 操作系統(tǒng)設(shè)備統(tǒng)計(jì) 信息統(tǒng)計(jì) 日志入庫(kù)的文章就介紹到這了,更多相關(guān)SpringBoot UserAgentUtils獲取用戶(hù)瀏覽器 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# 中Excel導(dǎo)入時(shí)判斷是否被占用三種方法
這篇文章主要介紹了C# 中Excel導(dǎo)入時(shí) 判斷是否被占用三種方法的相關(guān)資料,需要的朋友可以參考下2017-04-04
如何解決java.lang.ClassNotFoundException: com.mysql.jdbc.Dr
這篇文章主要介紹了如何解決java.lang.ClassNotFoundException: com.mysql.jdbc.Driver問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Spring Boot Filter 過(guò)濾器的使用方式
這篇文章主要介紹了Spring Boot Filter 過(guò)濾器的使用方式,文章通過(guò)圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
java?LockSupport實(shí)現(xiàn)原理示例解析
這篇文章主要為大家介紹了java?LockSupport實(shí)現(xiàn)原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
@Scheduled fixedDelayString 加載properties配置方式
這篇文章主要介紹了@Scheduled fixedDelayString 加載properties配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
Spring?cloud如何實(shí)現(xiàn)FeignClient指定Zone調(diào)用
這篇文章主要介紹了Spring?cloud如何實(shí)現(xiàn)FeignClient指定Zone調(diào)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Springboot中設(shè)置時(shí)間格式問(wèn)題小結(jié)
本文主要介紹了Springboot中設(shè)置時(shí)間格式問(wèn)題小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04
JAVA使用hutool工具實(shí)現(xiàn)查詢(xún)樹(shù)結(jié)構(gòu)數(shù)據(jù)(省市區(qū))
今天通過(guò)本文給大家分享JAVA使用hutool工具實(shí)現(xiàn)查詢(xún)樹(shù)結(jié)構(gòu)數(shù)據(jù)(省市區(qū)),代碼分為表結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu),代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-08-08

