diff --git a/build.gradle b/build.gradle
index efa4a43452e7e9a2bf2debfa357037c30d4465be..73893fa83c57fc92870ba2b25919711f7071e446 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,9 +24,13 @@ dependencies {
     implementation 'org.springframework.boot:spring-boot-starter-websocket'
     implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
     implementation 'org.jetbrains.kotlin:kotlin-reflect'
+    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+    implementation 'org.springframework.boot:spring-boot-starter-validation'
     testImplementation 'org.springframework.boot:spring-boot-starter-test'
     testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5'
     developmentOnly 'org.springframework.boot:spring-boot-devtools'
+    runtimeOnly 'com.h2database:h2'
+    runtimeOnly 'org.postgresql:postgresql'
     testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
 }
 
diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/configs/WebSocketsConfig.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/configs/WebSocketsConfig.kt
index 72d1e33087b7280f0ba96f4015d9c16e84c7b130..7ef2d66f6660a7a1ce676ee2599266fbee4949d8 100644
--- a/src/main/kotlin/de/thk/gm/websocketsdemo/configs/WebSocketsConfig.kt
+++ b/src/main/kotlin/de/thk/gm/websocketsdemo/configs/WebSocketsConfig.kt
@@ -1,5 +1,6 @@
 package de.thk.gm.websocketsdemo.configs
 
+import de.thk.gm.websocketsdemo.handlers.ChatRoomsHandler
 import de.thk.gm.websocketsdemo.handlers.EchoHandler
 import de.thk.gm.websocketsdemo.handlers.SimpleChatHandler
 import org.springframework.context.annotation.Configuration
@@ -14,5 +15,6 @@ class WebSocketsConfig(): WebSocketConfigurer {
     override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
         registry.addHandler(EchoHandler(), "/echo").setAllowedOrigins("*")
         registry.addHandler(SimpleChatHandler(), "/chat")
+        registry.addHandler(ChatRoomsHandler(),"/rooms")
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/controllers/ChatRoomsController.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/controllers/ChatRoomsController.kt
new file mode 100644
index 0000000000000000000000000000000000000000..36fdf8c044b4095146c63d2c081dc05807b63c89
--- /dev/null
+++ b/src/main/kotlin/de/thk/gm/websocketsdemo/controllers/ChatRoomsController.kt
@@ -0,0 +1,35 @@
+package de.thk.gm.websocketsdemo.controllers
+
+import de.thk.gm.websocketsdemo.dtos.ChatRoomDto
+import de.thk.gm.websocketsdemo.models.ChatRoom
+import de.thk.gm.websocketsdemo.services.ChatRoomsService
+import org.springframework.stereotype.Controller
+import org.springframework.ui.Model
+import org.springframework.web.bind.annotation.*
+import java.util.*
+
+@Controller
+@RequestMapping("/chatrooms")
+class ChatRoomsController (private val chatRoomsService: ChatRoomsService) {
+
+    @GetMapping
+    fun getChatRooms(model: Model): String {
+        model.addAttribute("chatRooms", chatRoomsService.getChatRooms())
+        return "chatRooms/showChatRooms"
+    }
+
+    @PostMapping
+    fun addChatRoom(chatRoomDto: ChatRoomDto): String {
+        var chatRoom = ChatRoom()
+        chatRoom.name = chatRoomDto.name
+        chatRoomsService.save(chatRoom)
+        return "redirect:/chatrooms/${chatRoom.id}"
+    }
+
+    @GetMapping("/{id}")
+    fun getChatRoom(@PathVariable("id") id: UUID, model: Model): String {
+        var chatRoom = chatRoomsService.getChatRoomById(id)
+        model.addAttribute("chatRoom", chatRoom)
+        return "chatRooms/showChatRoom"
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/dtos/ChatRoomDto.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/dtos/ChatRoomDto.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2d827a1b158aaa2230e251d8a8ccb3f5c8c54620
--- /dev/null
+++ b/src/main/kotlin/de/thk/gm/websocketsdemo/dtos/ChatRoomDto.kt
@@ -0,0 +1,10 @@
+package de.thk.gm.websocketsdemo.dtos
+
+import jakarta.validation.constraints.NotNull
+import jakarta.validation.constraints.Size
+
+class ChatRoomDto {
+    @NotNull
+    @Size(min = 1, max = 50)
+    var name: String = ""
+}
\ No newline at end of file
diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/handlers/ChatRoomsHandler.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/handlers/ChatRoomsHandler.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9d80ede0d367e539e7d17a78dd80fe5ca9b97ddf
--- /dev/null
+++ b/src/main/kotlin/de/thk/gm/websocketsdemo/handlers/ChatRoomsHandler.kt
@@ -0,0 +1,45 @@
+package de.thk.gm.websocketsdemo.handlers
+
+import org.springframework.web.socket.CloseStatus
+import org.springframework.web.socket.TextMessage
+import org.springframework.web.socket.WebSocketSession
+import org.springframework.web.socket.handler.TextWebSocketHandler
+import org.springframework.web.util.UriComponents
+import org.springframework.web.util.UriComponentsBuilder
+
+class ChatRoomsHandler : TextWebSocketHandler() {
+    private val hashMapOfSessions : HashMap<String, ArrayList<WebSocketSession>> = HashMap()
+    override fun afterConnectionEstablished(session: WebSocketSession) {
+        var uri : UriComponents = UriComponentsBuilder.fromUri(session.uri!!).build()
+        var id = uri.queryParams.getFirst("id")
+        if(id != null) {
+            var sessions = hashMapOfSessions[id]
+            if(sessions == null) {
+                sessions = ArrayList()
+            }
+            sessions.add(session)
+            hashMapOfSessions[id] = sessions
+        }
+    }
+
+    override fun handleTextMessage(session: WebSocketSession, message: TextMessage) {
+        var uri : UriComponents = UriComponentsBuilder.fromUri(session.uri!!).build()
+        var id = uri.queryParams.getFirst("id")
+        var sessions = hashMapOfSessions[id]
+        if(sessions != null) {
+            for (chatSession in sessions) {
+                chatSession.sendMessage(message)
+            }
+        }
+    }
+
+    override fun afterConnectionClosed(session: WebSocketSession, status: CloseStatus) {
+        var uri : UriComponents = UriComponentsBuilder.fromUri(session.uri!!).build()
+        var id = uri.queryParams.getFirst("id")
+        var sessions = hashMapOfSessions[id]
+        if(sessions != null) {
+            sessions.remove(session)
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/models/ChatRoom.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/models/ChatRoom.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8d98ce62940e968758e03077b922bf210524b444
--- /dev/null
+++ b/src/main/kotlin/de/thk/gm/websocketsdemo/models/ChatRoom.kt
@@ -0,0 +1,13 @@
+package de.thk.gm.websocketsdemo.models
+
+import jakarta.persistence.Entity
+import jakarta.persistence.Id
+import java.util.*
+
+@Entity
+class ChatRoom {
+    @Id
+    var id : UUID = UUID.randomUUID()
+
+    var name: String = ""
+}
\ No newline at end of file
diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/repositories/ChatRoomsRepository.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/repositories/ChatRoomsRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..96cc7f83b47d1f12ba96bffe20bacfe210bf7c6f
--- /dev/null
+++ b/src/main/kotlin/de/thk/gm/websocketsdemo/repositories/ChatRoomsRepository.kt
@@ -0,0 +1,10 @@
+package de.thk.gm.websocketsdemo.repositories
+
+import de.thk.gm.websocketsdemo.models.ChatRoom
+import org.springframework.data.repository.CrudRepository
+import org.springframework.stereotype.Repository
+import java.util.*
+
+@Repository
+interface ChatRoomsRepository : CrudRepository<ChatRoom, UUID> {
+}
\ No newline at end of file
diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/services/ChatRoomsService.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/services/ChatRoomsService.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fb6270b4b62ec8be8ada060589e24485bfd0f0b4
--- /dev/null
+++ b/src/main/kotlin/de/thk/gm/websocketsdemo/services/ChatRoomsService.kt
@@ -0,0 +1,10 @@
+package de.thk.gm.websocketsdemo.services
+
+import de.thk.gm.websocketsdemo.models.ChatRoom
+import java.util.*
+
+interface ChatRoomsService {
+    fun getChatRooms(): List<ChatRoom>
+    fun getChatRoomById(id: UUID): ChatRoom?
+    fun save(chatRoom: ChatRoom)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/services/ChatRoomsServiceImpl.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/services/ChatRoomsServiceImpl.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2ed307c6b07f5eb9600314377241920c1909e752
--- /dev/null
+++ b/src/main/kotlin/de/thk/gm/websocketsdemo/services/ChatRoomsServiceImpl.kt
@@ -0,0 +1,21 @@
+package de.thk.gm.websocketsdemo.services
+
+import de.thk.gm.websocketsdemo.models.ChatRoom
+import de.thk.gm.websocketsdemo.repositories.ChatRoomsRepository
+import org.springframework.stereotype.Service
+import java.util.*
+
+@Service
+class ChatRoomsServiceImpl (private val chatRoomsRepository: ChatRoomsRepository) : ChatRoomsService {
+    override fun getChatRooms(): List<ChatRoom> {
+        return chatRoomsRepository.findAll().toList()
+    }
+
+    override fun getChatRoomById(id: UUID): ChatRoom? {
+        return chatRoomsRepository.findById(id).orElse(null)
+    }
+
+    override fun save(chatRoom: ChatRoom) {
+        chatRoomsRepository.save(chatRoom)
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/templates/chatRooms/showChatRoom.ftlh b/src/main/resources/templates/chatRooms/showChatRoom.ftlh
new file mode 100644
index 0000000000000000000000000000000000000000..8aaac5ef50306699d218891571c335040fccdbcd
--- /dev/null
+++ b/src/main/resources/templates/chatRooms/showChatRoom.ftlh
@@ -0,0 +1,33 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport"
+          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <title>Chat Room</title>
+</head>
+<body>
+    <h1>Chat room ${chatRoom.name}</h1>
+    <input type="text" id="username" placeholder="username">
+    <input type="text" id="text" placeholder="message">
+    <br>
+    <button onclick="sendMessage()">Send</button>
+    <div id="chat"></div>
+    <script>
+        var ws = new WebSocket("/rooms?id=${chatRoom.id}")
+        var chat = document.getElementById("chat")
+        var message = {}
+        function sendMessage(){
+            message.username = document.getElementById("username").value
+            message.text = document.getElementById("text").value
+            ws.send(JSON.stringify(message))
+        }
+
+        ws.onmessage = function (msg) {
+            message = JSON.parse(msg.data)
+            chat.innerHTML += "<p><b>"+message.username+":</b>" + message.text + "</p>"
+        }
+    </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/resources/templates/chatRooms/showChatRooms.ftlh b/src/main/resources/templates/chatRooms/showChatRooms.ftlh
new file mode 100644
index 0000000000000000000000000000000000000000..69116bcc0f31e49c1871f3e8ed906c3915aa91fc
--- /dev/null
+++ b/src/main/resources/templates/chatRooms/showChatRooms.ftlh
@@ -0,0 +1,22 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport"
+          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <title>Chat Rooms</title>
+</head>
+<body>
+    <h1>Chat Rooms</h1>
+    <ul>
+    <#list chatRooms as room>
+       <li><a href="/chatrooms/${room.id}">${room.name}</a></li>
+    </#list>
+    </ul><br>
+    <form action="/chatrooms" method="post">
+        <input name="name" type="text"><br>
+        <button>Create chat room</button>
+    </form>
+</body>
+</html>
\ No newline at end of file