{"id":166,"date":"2024-01-13T13:03:00","date_gmt":"2024-01-13T12:03:00","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=166"},"modified":"2024-01-24T00:17:14","modified_gmt":"2024-01-23T23:17:14","slug":"serialisierung-und-deserialisierung-von-datums-und-zeitangaben-mit-jackson-in-java","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=166","title":{"rendered":"Serialisierung und Deserialisierung von Datums- und Zeitangaben mit Jackson in Java"},"content":{"rendered":"\n<p>Die Serialisierung und Deserialisierung von Datums- und Zeitangaben sind entscheidende Aspekte beim Umgang mit Daten in Java-Anwendungen. In diesem Artikel werden wir uns auf die Verwendung der Jackson-Bibliothek konzentrieren, um Datums- und Zeitangaben zu serialisieren und zu deserialisieren. Dabei werden sowohl die traditionelle <code>java.util.Date<\/code>-Klasse als auch die neuen DateTime-Objekte aus Java 8 ber\u00fccksichtigt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Einleitung zu Jackson<\/h2>\n\n\n\n<p>Jackson ist eine leistungsstarke Java-Bibliothek zur Verarbeitung von JSON-Daten. Sie bietet eine einfache M\u00f6glichkeit, Java-Objekte in JSON umzuwandeln (Serialisierung) und umgekehrt (Deserialisierung). Jackson unterst\u00fctzt verschiedene Datentypen, einschlie\u00dflich Datums- und Zeitangaben.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Serialisierung von Datums- und Zeitangaben<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Serialisierung von <code>java.util.Date<\/code><\/h3>\n\n\n\n<p>Um ein <code>java.util.Date<\/code>-Objekt in ein JSON-Format zu serialisieren, verwenden wir die Jackson-Annotationen. Hier ein einfaches Beispiel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> com.fasterxml.jackson.databind.ObjectMapper;\n<span class=\"hljs-keyword\">import<\/span> com.fasterxml.jackson.databind.SerializationFeature;\n<span class=\"hljs-keyword\">import<\/span> java.util.Date;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">DateSerializationExample<\/span> <\/span>{\n\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) throws Exception {\n        ObjectMapper objectMapper = <span class=\"hljs-keyword\">new<\/span> ObjectMapper();\n        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, <span class=\"hljs-literal\">false<\/span>);\n\n        <span class=\"hljs-built_in\">Date<\/span> currentDate = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>();\n        <span class=\"hljs-built_in\">String<\/span> jsonDate = objectMapper.writeValueAsString(currentDate);\n\n        System.out.println(<span class=\"hljs-string\">\"Serialisiertes Datum: \"<\/span> + jsonDate);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><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>In diesem Beispiel wird die <code>ObjectMapper<\/code>-Klasse von Jackson verwendet. Die Konfiguration <code>WRITE_DATES_AS_TIMESTAMPS<\/code> wird auf <code>false<\/code> gesetzt, um das Datum nicht als Zeitstempel, sondern im lesbaren String-Format zu serialisieren.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Serialisierung von Java 8 DateTime-Objekten<\/h3>\n\n\n\n<p>F\u00fcr Java 8 und sp\u00e4tere Versionen bietet Jackson native Unterst\u00fctzung f\u00fcr die Serialisierung von DateTime-Objekten. Hier ein Beispiel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> com.fasterxml.jackson.databind.ObjectMapper;\n<span class=\"hljs-keyword\">import<\/span> com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;\n<span class=\"hljs-keyword\">import<\/span> java.time.LocalDateTime;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">DateTimeSerializationExample<\/span> <\/span>{\n\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) throws Exception {\n        ObjectMapper objectMapper = <span class=\"hljs-keyword\">new<\/span> ObjectMapper();\n        objectMapper.registerModule(<span class=\"hljs-keyword\">new<\/span> JavaTimeModule());\n\n        LocalDateTime currentDateTime = LocalDateTime.now();\n        <span class=\"hljs-built_in\">String<\/span> jsonDateTime = objectMapper.writeValueAsString(currentDateTime);\n\n        System.out.println(<span class=\"hljs-string\">\"Serialisiertes DateTime: \"<\/span> + jsonDateTime);\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\">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>Durch Hinzuf\u00fcgen des <code>JavaTimeModule<\/code> zum <code>ObjectMapper<\/code> kann Jackson <code>LocalDateTime<\/code>-Objekte ohne zus\u00e4tzliche Konfiguration serialisieren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Deserialisierung von Datums- und Zeitangaben<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Deserialisierung von <code>java.util.Date<\/code><\/h3>\n\n\n\n<p>Um ein JSON-String mit einem Datumsformat in ein <code>java.util.Date<\/code>-Objekt zu deserialisieren, verwenden wir erneut Jackson-Annotationen:<\/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> com.fasterxml.jackson.databind.ObjectMapper;\n<span class=\"hljs-keyword\">import<\/span> java.text.SimpleDateFormat;\n<span class=\"hljs-keyword\">import<\/span> java.util.Date;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">DateDeserializationExample<\/span> <\/span>{\n\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) throws Exception {\n        ObjectMapper objectMapper = <span class=\"hljs-keyword\">new<\/span> ObjectMapper();\n\n        <span class=\"hljs-built_in\">String<\/span> jsonDate = <span class=\"hljs-string\">\"\\\"2024-01-24T12:30:45\\\"\"<\/span>; <span class=\"hljs-comment\">\/\/ Beispiel-Datum im ISO-Format<\/span>\n        <span class=\"hljs-built_in\">Date<\/span> deserializedDate = objectMapper.readValue(jsonDate, <span class=\"hljs-built_in\">Date<\/span>.class);\n\n        System.out.println(<span class=\"hljs-string\">\"Deserialisiertes Datum: \"<\/span> + deserializedDate);\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>Hier wird der JSON-String im ISO-Format bereitgestellt, und Jackson k\u00fcmmert sich um die Deserialisierung in ein <code>java.util.Date<\/code>-Objekt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Deserialisierung von Java 8 DateTime-Objekten<\/h3>\n\n\n\n<p>Die Deserialisierung von Java 8 DateTime-Objekten ist ebenfalls unkompliziert:<\/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\"><span class=\"hljs-keyword\">import<\/span> com.fasterxml.jackson.databind.ObjectMapper;\n<span class=\"hljs-keyword\">import<\/span> com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;\n<span class=\"hljs-keyword\">import<\/span> java.time.LocalDateTime;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">DateTimeDeserializationExample<\/span> <\/span>{\n\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) throws Exception {\n        ObjectMapper objectMapper = <span class=\"hljs-keyword\">new<\/span> ObjectMapper();\n        objectMapper.registerModule(<span class=\"hljs-keyword\">new<\/span> JavaTimeModule());\n\n        <span class=\"hljs-built_in\">String<\/span> jsonDateTime = <span class=\"hljs-string\">\"\\\"2024-01-24T12:30:45\\\"\"<\/span>;\n        LocalDateTime deserializedDateTime = objectMapper.readValue(jsonDateTime, LocalDateTime.class);\n\n        System.out.println(<span class=\"hljs-string\">\"Deserialisiertes DateTime: \"<\/span> + deserializedDateTime);\n    }\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>Durch das Registrieren des <code>JavaTimeModule<\/code> kann Jackson den JSON-String in ein <code>LocalDateTime<\/code>-Objekt umwandeln.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Serialisierung und Deserialisierung von <code>OffsetDateTime<\/code><\/h2>\n\n\n\n<p>Neben den bereits behandelten <code>java.util.Date<\/code>&#8211; und Java 8 DateTime-Objekten bietet Jackson auch Unterst\u00fctzung f\u00fcr <code>OffsetDateTime<\/code>. <code>OffsetDateTime<\/code> ist eine Klasse aus dem <code>java.time<\/code>-Paket und repr\u00e4sentiert einen Datum und Uhrzeit mit einem festen Offset von der UTC-Zeit.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Serialisierung von <code>OffsetDateTime<\/code><\/h3>\n\n\n\n<p>Die Serialisierung von <code>OffsetDateTime<\/code> ist \u00e4hnlich wie bei anderen DateTime-Objekten. Es ist jedoch wichtig sicherzustellen, dass der Offset im JSON-Format erhalten bleibt. Hier ein Beispiel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> com.fasterxml.jackson.databind.ObjectMapper;\n<span class=\"hljs-keyword\">import<\/span> com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;\n<span class=\"hljs-keyword\">import<\/span> java.time.OffsetDateTime;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OffsetDateTimeSerializationExample<\/span> <\/span>{\n\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) throws Exception {\n        ObjectMapper objectMapper = <span class=\"hljs-keyword\">new<\/span> ObjectMapper();\n        objectMapper.registerModule(<span class=\"hljs-keyword\">new<\/span> JavaTimeModule());\n\n        OffsetDateTime currentOffsetDateTime = OffsetDateTime.now();\n        <span class=\"hljs-built_in\">String<\/span> jsonOffsetDateTime = objectMapper.writeValueAsString(currentOffsetDateTime);\n\n        System.out.println(<span class=\"hljs-string\">\"Serialisiertes OffsetDateTime: \"<\/span> + jsonOffsetDateTime);\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\">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>Durch das Hinzuf\u00fcgen des <code>JavaTimeModule<\/code> kann Jackson <code>OffsetDateTime<\/code> korrekt serialisieren, einschlie\u00dflich des Offset-Teils.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Deserialisierung von <code>OffsetDateTime<\/code><\/h3>\n\n\n\n<p>Die Deserialisierung von <code>OffsetDateTime<\/code> erfordert ebenfalls die Beachtung des Offset-Teils im JSON-Format:<\/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> com.fasterxml.jackson.databind.ObjectMapper;\n<span class=\"hljs-keyword\">import<\/span> com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;\n<span class=\"hljs-keyword\">import<\/span> java.time.OffsetDateTime;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OffsetDateTimeDeserializationExample<\/span> <\/span>{\n\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) throws Exception {\n        ObjectMapper objectMapper = <span class=\"hljs-keyword\">new<\/span> ObjectMapper();\n        objectMapper.registerModule(<span class=\"hljs-keyword\">new<\/span> JavaTimeModule());\n\n        <span class=\"hljs-built_in\">String<\/span> jsonOffsetDateTime = <span class=\"hljs-string\">\"\\\"2024-01-24T12:30:45+03:00\\\"\"<\/span>;\n        OffsetDateTime deserializedOffsetDateTime = objectMapper.readValue(jsonOffsetDateTime, OffsetDateTime.class);\n\n        System.out.println(<span class=\"hljs-string\">\"Deserialisiertes OffsetDateTime: \"<\/span> + deserializedOffsetDateTime);\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<p>Hier wird der Offset im JSON-String im ISO-Format (z.B., <code>+03:00<\/code> f\u00fcr eine Zeitzone mit einem Offset von 3 Stunden) angegeben, und Jackson kann das <code>OffsetDateTime<\/code>-Objekt entsprechend deserialisieren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Problematik von Zeit-Offsets zwischen Rechnern in unterschiedlichen Zeitzonen<\/h2>\n\n\n\n<p>Bei der \u00dcbertragung von <code>OffsetDateTime<\/code> zwischen Rechnern in unterschiedlichen Zeitzonen besteht oft die Anforderung, dass der Offset genau so erhalten bleibt, wie er auf dem Quellsystem vorliegt. In solchen F\u00e4llen kann die Jackson-Option <code>ADJUST_DATES_TO_CONTEXT_TIME_ZONE<\/code> hilfreich sein. Diese Option wird verwendet, um sicherzustellen, dass der Offset im <code>OffsetDateTime<\/code>-Objekt unver\u00e4ndert bleibt und nicht an den Zeitzone-Kontext des Zielsystems angepasst wird.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">ObjectMapper objectMapper = <span class=\"hljs-keyword\">new<\/span> ObjectMapper();\nobjectMapper.registerModule(<span class=\"hljs-keyword\">new<\/span> JavaTimeModule());\nobjectMapper.configure(SerializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, <span class=\"hljs-literal\">false<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><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>Durch das Deaktivieren der Anpassung an die Zeitzone des Kontexts wird gew\u00e4hrleistet, dass der Offset im <code>OffsetDateTime<\/code>-Objekt erhalten bleibt und nicht durch den Zeitzone-Kontext des Zielsystems ver\u00e4ndert wird.<\/p>\n\n\n\n<p>Es ist jedoch wichtig zu beachten, dass diese Vorgehensweise zu potenziellen Problemen f\u00fchren kann, wenn die Anwendung auf dem Zielsystem nicht in der Lage ist, den Offset korrekt zu interpretieren. Daher sollte dies nur dann verwendet werden, wenn sicher gestellt ist, dass beide Systeme den Offset eindeutig verstehen und interpretieren k\u00f6nnen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p>Die Serialisierung und Deserialisierung von Datums- und Zeitangaben mit Jackson in Java erlauben eine einfache und effiziente Handhabung von Zeitinformationen in JSON-Format. Durch die Verwendung von Jackson-Annotationen und -Modulen k\u00f6nnen sowohl die traditionelle <code>java.util.Date<\/code>-Klasse als auch die neuen Java 8 DateTime-Objekte problemlos integriert werden. Dies erleichtert die Interoperabilit\u00e4t zwischen Java-Anwendungen und externen Systemen, die JSON als Datenformat verwenden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die Serialisierung und Deserialisierung von Datums- und Zeitangaben sind entscheidende Aspekte beim Umgang mit Daten in Java-Anwendungen. In diesem Artikel werden wir uns auf die Verwendung der Jackson-Bibliothek konzentrieren, um Datums- und Zeitangaben zu serialisieren und zu deserialisieren. Dabei werden sowohl die traditionelle java.util.Date-Klasse als auch die neuen DateTime-Objekte aus Java 8 ber\u00fccksichtigt. Einleitung zu [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-166","post","type-post","status-publish","format-standard","hentry","category-plain_java"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/166","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=166"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/166\/revisions"}],"predecessor-version":[{"id":167,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/166\/revisions\/167"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}