前言
我不是一个伟大的程序员,我只是一个具有良好习惯的优秀程序员。― Kent Beck
最近工作中,需要获取浏览器系统等信息,进行客户端的信息留存,首先想到的就是对user_agent进行解析,以从可获取的信息中提炼需要的信息,进行操作。
中间尝试了很多种可能
包括
- github: browscap4jFileReader
- github: browscap-java
- github: user-agent-utils
这三个都是针对user_agent可进行操作的jar包,user-agent-utils 早在18年就停止维护了,对于目前市面上的edge浏览器没有进行区分,所以选择了以上两款进行选用。这两种使用起来感觉也差不多,看活跃度,选择了browscap-java,但是其实没差。如果有小伙伴想要讨论,可以在评论区回复,互相学习。
user_agent的获取:
/**User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器
能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等*/
String agent= request.getHeader("user-agent");
一、browscap-java是什么?
browscap-java是一个速度极快且内存高效(线程安全)的 Java 客户端,位于 BrowsCap CSV 源文件之上。BrowsCap 当前对应版本是:6001000。
此库可用于解析用户代理标头,以便提取有关所用浏览器、浏览器版本、平台、平台版本和设备类型的信息。对于确定客户端是台式机,平板电脑还是移动设备或确定客户端是否在Windows或Mac OS上非常有用。
二、实现机制算法
我们收到了一些关于我们的算法如何以及为什么它“非常快速和高效”的问题。简而言之,这就是我们的算法的工作原理:
- 所有CSV行都在我们自己的数据结构中读取和解析(例如“规则”对象)。-- 这不涉及正则表达式(这会消耗内存且成本高昂),而是使用一种在 CSV 表达式上执行子字符串的智能方法。-- 子字符串操作(startsWith、endsWith、findIndices in SearchableString)的结果被缓存,因此后续调用非常快。
- 生成所有规则后,它们将按大小和字母顺序排序,因此可以立即返回第一个匹配项。
- 查找用户代理时,将根据表达式的“部分”筛选所有规则。大多数规则都很容易被丢弃,因为它们不包含特定的子字符串。
- 过滤机制基于位集操作,这对于大型数据集非常快。
三、注意事项
- 尽管此库非常快,但建议实现缓存。由于每个用例的缓存策略不同,因此此库不会附带一个开箱即用的。
- 所有 BrowsCap 字段都可通过配置获得,但默认情况下会加载以下字段:
–browser(例如谷歌)
–browserType(例如浏览器或应用程序)
–browserMajorVersion(例如,在Chrome的情况下为80)
–deviceType(例如手机、台式机、平板电脑、主机、电视设备)
–platform(例如 Android、iOS、Win7、Win8、Win10)
–platformVersion(例如 4.2,10 取决于平台是什么) - 这些字段可以通过在 UserAgentParser 的构造函数中指定 BrowsCapFields 列表来配置。
- CSV 文件以流式处理方式读取,因此会逐行处理。这使得它比首先将整体加载到内存中更有效。
- 在单元测试中测试了 1000 多个用户代理。
四、使用步骤
1.Maven引入
将其添加到 pom.xml中的依赖项。
<dependency>
<groupId>com.blueconic</groupId>
<artifactId>browscap-java</artifactId>
<version>1.3.12</version>
</dependency>
2.使用方法
// 引入需要类
import com.blueconic.browscap.BrowsCapField;
import com.blueconic.browscap.Capabilities;
import com.blueconic.browscap.ParseException;
import com.blueconic.browscap.UserAgentParser;
import com.blueconic.browscap.UserAgentService;
// 使用默认字段创建解析器
final UserAgentParser parser = new UserAgentService().loadParser(); // 需要进行IOException和ParseException处理,推荐try/c
// 使用自定义字段列表创建解析器 (注意,二者取一进行调用)
// 可用字段列表可以在BrowsCapField枚举中看到
final UserAgentParser parser =
new UserAgentService().loadParser(Arrays.asList(
BrowsCapField.BROWSER, //浏览器
BrowsCapField.BROWSER_TYPE, // 浏览器类型
BrowsCapField.BROWSER_MAJOR_VERSION, // 浏览器主要版本
BrowsCapField.DEVICE_TYPE, // 系统类型
BrowsCapField.PLATFORM, // 平台
BrowsCapField.PLATFORM_VERSION, // 平台版本
BrowsCapField.RENDERING_ENGINE_VERSION, // 渲染引擎版本
BrowsCapField.RENDERING_ENGINE_NAME, // 渲染引擎名称
BrowsCapField.PLATFORM_MAKER, // 平台制造商
BrowsCapField.RENDERING_ENGINE_MAKER)); //渲染引擎制造商
// 也可以通过在构造函数中提供ZIP文件的正确路径来提供自己的ZIP文件。
// 当新的BrowsCap版本发布时,可以使用该功能,该版本尚未捆绑在该软件包中。
// final UserAgentParser parser = new UserAgentService("E:\\anil\\browscap.zip").loadParser();
// 解析器可以重新用于多个查找调用
final String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36";
final Capabilities capabilities = parser.parse(userAgent);
// 默认字段具有getter
final String browser = capabilities.getBrowser();
final String browserType = capabilities.getBrowserType();
final String browserMajorVersion = capabilities.getBrowserMajorVersion();
final String deviceType = capabilities.getDeviceType();
final String platform = capabilities.getPlatform();
final String platformVersion = capabilities.getPlatformVersion();
// 自定义字段可用
final String renderingEngineMaker = capabilities.getValue(BrowsCapField.RENDERING_ENGINE_MAKER);
// 可以自定义进行拓展
总结
此工具类,可以大大提升开发效率,不用把工作放在复制的校验逻辑上,可以更多的放在业务上,有兴趣的可以看看源码,其实实现原理很简单。