{"id":513,"date":"2024-11-21T11:09:01","date_gmt":"2024-11-21T10:09:01","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=513"},"modified":"2024-12-03T11:14:39","modified_gmt":"2024-12-03T10:14:39","slug":"user-agent-parsing-mit-der-yauaa-library-in-einer-spring-boot-anwendung","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=513","title":{"rendered":"User-Agent-Parsing mit der Yauaa-Library in einer Spring-Boot-Anwendung"},"content":{"rendered":"\n<p>Der User-Agent-String ist eine Zeichenkette, die von einem Client (z. B. Browser oder Mobile-App) an den Server gesendet wird, um dessen Eigenschaften wie Ger\u00e4tetyp, Betriebssystem, Browser und Version mitzuteilen. Die Analyse des User-Agent-Strings kann n\u00fctzlich sein, um Inhalte oder Dienste gezielt an verschiedene Ger\u00e4te anzupassen, Statistiken zu erstellen oder Sicherheitsfunktionen zu implementieren.<\/p>\n\n\n\n<p>Die Library <strong>Yauaa<\/strong> (Yet Another User-Agent Analyzer) ist eine leistungsf\u00e4hige und leicht integrierbare Open-Source-Bibliothek, die sich speziell f\u00fcr das Parsen und Analysieren von User-Agent-Strings eignet. In diesem Artikel zeige ich, wie die Yauaa-Library in eine Spring-Boot-Anwendung integriert wird und wie sie genutzt werden kann, um die User-Agent-Daten serverseitig auszuwerten.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">1. Einf\u00fchrung in Yauaa<\/h3>\n\n\n\n<p>Yauaa bietet eine flexible M\u00f6glichkeit, User-Agent-Strings in strukturierte Daten umzuwandeln. Die Library liefert detaillierte Informationen \u00fcber:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Betriebssystem (inklusive Version)<\/li>\n\n\n\n<li>Browser (inklusive Version)<\/li>\n\n\n\n<li>Ger\u00e4tetyp (z. B. Smartphone, Tablet, Desktop)<\/li>\n\n\n\n<li>Marke und Modell<\/li>\n\n\n\n<li>Bots oder Crawler (z. B. Googlebot)<\/li>\n<\/ul>\n\n\n\n<p>Mit Yauaa lassen sich diese Informationen durch eine einfache API abrufen und weiterverarbeiten.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">2. Integration in eine Spring-Boot-Anwendung<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 1: Maven-Abh\u00e4ngigkeit hinzuf\u00fcgen<\/h4>\n\n\n\n<p>Um Yauaa in ein Spring-Boot-Projekt zu integrieren, muss die Abh\u00e4ngigkeit in der <code>pom.xml<\/code> des Projekts hinzugef\u00fcgt werden:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>nl.basjes.parse.useragent<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>yauaa<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>7.26<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Schritt 2: Konfiguration der Yauaa-Instanz<\/h4>\n\n\n\n<p>Yauaa verwendet einen <code>UserAgentAnalyzer<\/code>, der die User-Agent-Strings analysiert. Dieser kann als Bean in einer Spring-Boot-Anwendung definiert werden:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">nl<\/span><span class=\"hljs-selector-class\">.basjes<\/span><span class=\"hljs-selector-class\">.parse<\/span><span class=\"hljs-selector-class\">.useragent<\/span><span class=\"hljs-selector-class\">.UserAgentAnalyzer<\/span>;\n<span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">org<\/span><span class=\"hljs-selector-class\">.springframework<\/span><span class=\"hljs-selector-class\">.context<\/span><span class=\"hljs-selector-class\">.annotation<\/span><span class=\"hljs-selector-class\">.Bean<\/span>;\n<span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">org<\/span><span class=\"hljs-selector-class\">.springframework<\/span><span class=\"hljs-selector-class\">.context<\/span><span class=\"hljs-selector-class\">.annotation<\/span><span class=\"hljs-selector-class\">.Configuration<\/span>;\n\n<span class=\"hljs-keyword\">@Configuration<\/span>\npublic class YauaaConfig {\n\n    <span class=\"hljs-keyword\">@Bean<\/span>\n    public UserAgentAnalyzer userAgentAnalyzer() {\n        <span class=\"hljs-selector-tag\">return<\/span> <span class=\"hljs-selector-tag\">UserAgentAnalyzer<\/span><span class=\"hljs-selector-class\">.newBuilder<\/span>()<span class=\"hljs-selector-class\">.hideMatcherLoadStats<\/span>()<span class=\"hljs-selector-class\">.withCache<\/span>(10000)<span class=\"hljs-selector-class\">.build<\/span>();\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Mit dieser Konfiguration wird ein <code>UserAgentAnalyzer<\/code> erstellt, der einen internen Cache f\u00fcr bis zu 10.000 Eintr\u00e4ge verwendet.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3. Auslesen des User-Agent-Strings in einem Controller<\/h3>\n\n\n\n<p>Um den User-Agent-String eines Requests auszulesen, kann der Wert des <code>User-Agent<\/code>-Headers genutzt werden. Dies wird in einem Spring-Boot-Controller wie folgt umgesetzt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> nl.basjes.parse.useragent.UserAgent;\n<span class=\"hljs-keyword\">import<\/span> nl.basjes.parse.useragent.UserAgentAnalyzer;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.web.bind.annotation.GetMapping;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.web.bind.annotation.RequestHeader;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.web.bind.annotation.RestController;\n\n<span class=\"hljs-keyword\">import<\/span> java.util.HashMap;\n<span class=\"hljs-keyword\">import<\/span> java.util.Map;\n\n@RestController\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserAgentController<\/span> <\/span>{\n\n    private final UserAgentAnalyzer userAgentAnalyzer;\n\n    @Autowired\n    public UserAgentController(UserAgentAnalyzer userAgentAnalyzer) {\n        <span class=\"hljs-keyword\">this<\/span>.userAgentAnalyzer = userAgentAnalyzer;\n    }\n\n    @GetMapping(<span class=\"hljs-string\">\"\/user-agent\"<\/span>)\n    public <span class=\"hljs-built_in\">Map<\/span>&lt;<span class=\"hljs-built_in\">String<\/span>, <span class=\"hljs-built_in\">String<\/span>&gt; parseUserAgent(@RequestHeader(value = <span class=\"hljs-string\">\"User-Agent\"<\/span>, defaultValue = <span class=\"hljs-string\">\"Unknown\"<\/span>) <span class=\"hljs-built_in\">String<\/span> userAgentHeader) {\n        UserAgent userAgent = userAgentAnalyzer.parse(userAgentHeader);\n\n        <span class=\"hljs-comment\">\/\/ Extrahieren einzelner Attribute<\/span>\n        <span class=\"hljs-built_in\">Map<\/span>&lt;<span class=\"hljs-built_in\">String<\/span>, <span class=\"hljs-built_in\">String<\/span>&gt; userAgentDetails = <span class=\"hljs-keyword\">new<\/span> HashMap&lt;&gt;();\n        userAgentDetails.put(<span class=\"hljs-string\">\"Browser\"<\/span>, userAgent.getValue(<span class=\"hljs-string\">\"AgentName\"<\/span>));\n        userAgentDetails.put(<span class=\"hljs-string\">\"BrowserVersion\"<\/span>, userAgent.getValue(<span class=\"hljs-string\">\"AgentVersion\"<\/span>));\n        userAgentDetails.put(<span class=\"hljs-string\">\"OS\"<\/span>, userAgent.getValue(<span class=\"hljs-string\">\"OperatingSystemName\"<\/span>));\n        userAgentDetails.put(<span class=\"hljs-string\">\"OSVersion\"<\/span>, userAgent.getValue(<span class=\"hljs-string\">\"OperatingSystemVersion\"<\/span>));\n        userAgentDetails.put(<span class=\"hljs-string\">\"DeviceClass\"<\/span>, userAgent.getValue(<span class=\"hljs-string\">\"DeviceClass\"<\/span>));\n\n        <span class=\"hljs-keyword\">return<\/span> userAgentDetails;\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dieser Controller verarbeitet den User-Agent-Header eines HTTP-Requests und gibt die analysierten Details als JSON zur\u00fcck.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4. Beispielausgabe und Verwendung<\/h3>\n\n\n\n<p>Wenn ein Client diesen Endpunkt aufruft, sendet er seinen User-Agent-String mit. Ein Beispielaufruf mit <strong>curl<\/strong> k\u00f6nnte so aussehen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -H <span class=\"hljs-string\">\"User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/114.0.5735.134 Safari\/537.36\"<\/span> http:<span class=\"hljs-comment\">\/\/localhost:8080\/user-agent<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die Ausgabe k\u00f6nnte etwa wie folgt aussehen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JSON \/ JSON mit Kommentaren\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json\">{\n    <span class=\"hljs-attr\">\"Browser\"<\/span>: <span class=\"hljs-string\">\"Chrome\"<\/span>,\n    <span class=\"hljs-attr\">\"BrowserVersion\"<\/span>: <span class=\"hljs-string\">\"114.0.5735.134\"<\/span>,\n    <span class=\"hljs-attr\">\"OS\"<\/span>: <span class=\"hljs-string\">\"Windows\"<\/span>,\n    <span class=\"hljs-attr\">\"OSVersion\"<\/span>: <span class=\"hljs-string\">\"10.0\"<\/span>,\n    <span class=\"hljs-attr\">\"DeviceClass\"<\/span>: <span class=\"hljs-string\">\"Desktop\"<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON mit Kommentaren<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">5. Erweiterung: Nutzung in der Anwendung<\/h3>\n\n\n\n<p>Die analysierten Daten k\u00f6nnen in der Anwendung vielf\u00e4ltig verwendet werden:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">5.1. Anpassung von Inhalten<\/h4>\n\n\n\n<p>Abh\u00e4ngig vom Ger\u00e4tetyp oder der Browser-Version k\u00f6nnen Inhalte dynamisch angepasst werden, z. B.:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Desktop-Nutzer erhalten eine optimierte Desktop-Oberfl\u00e4che.<\/li>\n\n\n\n<li>Mobile-Nutzer werden auf eine responsive Version umgeleitet.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">5.2. Analyse und Monitoring<\/h4>\n\n\n\n<p>Die gesammelten Daten k\u00f6nnen in eine Datenbank geschrieben und zur Erstellung von Statistiken genutzt werden. Dies hilft, die Nutzung der Webanwendung besser zu verstehen und die Zielgruppe zu analysieren.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> org.springframework.web.bind.annotation.PostMapping;\n\n@PostMapping(<span class=\"hljs-string\">\"\/log-user-agent\"<\/span>)\npublic <span class=\"hljs-keyword\">void<\/span> logUserAgent(@RequestHeader(value = <span class=\"hljs-string\">\"User-Agent\"<\/span>) <span class=\"hljs-built_in\">String<\/span> userAgentHeader) {\n    UserAgent userAgent = userAgentAnalyzer.parse(userAgentHeader);\n\n    <span class=\"hljs-comment\">\/\/ Beispiel: Speichern in der Konsole<\/span>\n    System.out.println(<span class=\"hljs-string\">\"Browser: \"<\/span> + userAgent.getValue(<span class=\"hljs-string\">\"AgentName\"<\/span>));\n    System.out.println(<span class=\"hljs-string\">\"OS: \"<\/span> + userAgent.getValue(<span class=\"hljs-string\">\"OperatingSystemName\"<\/span>));\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">5.3. Sicherheitsma\u00dfnahmen<\/h4>\n\n\n\n<p>Crawler oder verd\u00e4chtige User-Agent-Strings k\u00f6nnen erkannt und blockiert werden. Dies wird oft verwendet, um Bots von gesch\u00fctzten Bereichen fernzuhalten.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">6. Fazit<\/h3>\n\n\n\n<p>Die Yauaa-Library ist ein einfach zu verwendendes Werkzeug, das in Spring-Boot-Anwendungen m\u00fchelos integriert werden kann. Sie erm\u00f6glicht eine pr\u00e4zise Analyse von User-Agent-Strings und liefert wertvolle Informationen \u00fcber die Clients einer Webanwendung. Mit diesen Daten k\u00f6nnen Entwickler Inhalte gezielt anpassen, Statistiken erstellen oder Sicherheitsma\u00dfnahmen implementieren. Dank der Flexibilit\u00e4t und Performance von Yauaa eignet sich die Library sowohl f\u00fcr kleine Projekte als auch f\u00fcr gro\u00dfe, skalierbare Systeme.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Der User-Agent-String ist eine Zeichenkette, die von einem Client (z. B. Browser oder Mobile-App) an den Server gesendet wird, um dessen Eigenschaften wie Ger\u00e4tetyp, Betriebssystem, Browser und Version mitzuteilen. Die Analyse des User-Agent-Strings kann n\u00fctzlich sein, um Inhalte oder Dienste gezielt an verschiedene Ger\u00e4te anzupassen, Statistiken zu erstellen oder Sicherheitsfunktionen zu implementieren. Die Library Yauaa [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-513","post","type-post","status-publish","format-standard","hentry","category-spring"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/513","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=513"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/513\/revisions"}],"predecessor-version":[{"id":514,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/513\/revisions\/514"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=513"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=513"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=513"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}