mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-22 15:25:49 +00:00
Starting WebSocket
This commit is contained in:
parent
8755ca9cf1
commit
ad9d5f513c
9 changed files with 280 additions and 24 deletions
102
pom.xml
102
pom.xml
|
@ -14,6 +14,9 @@
|
|||
<version>2.3.3.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- PROPERTIES -->
|
||||
<!-- ===================================================================== -->
|
||||
<properties>
|
||||
<!-- Generic properties -->
|
||||
<java.version>1.8</java.version>
|
||||
|
@ -26,13 +29,22 @@
|
|||
<webjars-jquery.version>2.2.4</webjars-jquery.version>
|
||||
<wro4j.version>1.8.0</wro4j.version>
|
||||
|
||||
<checkstyle.version>8.32</checkstyle.version>
|
||||
<jacoco.version>0.8.5</jacoco.version>
|
||||
<junit.version>4.13</junit.version>
|
||||
<lifecycle-mapping.version>1.0.0</lifecycle-mapping.version>
|
||||
<lombok.version>1.18.12</lombok.version>
|
||||
<maven-checkstyle-plugin.version>3.1.1</maven-checkstyle-plugin.version>
|
||||
<modelmapper.version>2.3.8</modelmapper.version>
|
||||
<nohttp-checkstyle.version>0.0.4.RELEASE</nohttp-checkstyle.version>
|
||||
<spring-format.version>0.0.25</spring-format.version>
|
||||
</properties>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- DEPENDENCIES -->
|
||||
<!-- ===================================================================== -->
|
||||
<dependencies>
|
||||
<!-- Spring and Spring Boot dependencies -->
|
||||
<!-- ============================================================ SPRING -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
|
@ -57,6 +69,10 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
@ -69,15 +85,7 @@
|
|||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- ================================================== MODELMAPPER -->
|
||||
<dependency>
|
||||
<groupId>org.modelmapper</groupId>
|
||||
<artifactId>modelmapper</artifactId>
|
||||
<version>2.3.8</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Databases - Uses H2 by default -->
|
||||
<!-- ========================================================= DATABASES -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
|
@ -89,6 +97,15 @@
|
|||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- ======================================================= MODELMAPPER -->
|
||||
<dependency>
|
||||
<groupId>org.modelmapper</groupId>
|
||||
<artifactId>modelmapper</artifactId>
|
||||
<version>${modelmapper.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- caching -->
|
||||
<dependency>
|
||||
<groupId>javax.cache</groupId>
|
||||
|
@ -100,6 +117,12 @@
|
|||
</dependency>
|
||||
|
||||
<!-- webjars -->
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>webjars-locator</artifactId>
|
||||
<version>0.40</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>webjars-locator-core</artifactId>
|
||||
|
@ -119,9 +142,35 @@
|
|||
<artifactId>bootstrap</artifactId>
|
||||
<version>${webjars-bootstrap.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>stomp-websocket</artifactId>
|
||||
<version>2.3.3-1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>sockjs-client</artifactId>
|
||||
<version>1.1.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- end of webjars -->
|
||||
|
||||
<!-- Testing -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.10.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.10.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- =========================================================== TESTING -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
|
@ -141,17 +190,20 @@
|
|||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.12</version>
|
||||
<scope>test</scope>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- BUILD -->
|
||||
<!-- ===================================================================== -->
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
@ -170,12 +222,12 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>${maven-checkstyle-plugin.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>8.32</version>
|
||||
<version>${checkstyle.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.spring.nohttp</groupId>
|
||||
|
@ -297,7 +349,7 @@
|
|||
</dependencies>
|
||||
</plugin>
|
||||
|
||||
<!-- ===================================================== SUREFIRE -->
|
||||
<!-- ======================================================== SUREFIRE -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
|
@ -349,6 +401,9 @@
|
|||
</plugins>
|
||||
</build>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- LICENCIES -->
|
||||
<!-- ===================================================================== -->
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
|
@ -356,6 +411,9 @@
|
|||
</license>
|
||||
</licenses>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- REPOSITORIES -->
|
||||
<!-- ===================================================================== -->
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
|
@ -375,6 +433,9 @@
|
|||
</repository>
|
||||
</repositories>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- PLUGIN REPOSITORIES -->
|
||||
<!-- ===================================================================== -->
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
|
@ -394,7 +455,11 @@
|
|||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- PROFILES -->
|
||||
<!-- ===================================================================== -->
|
||||
<profiles>
|
||||
<!-- =============================================================== M2E -->
|
||||
<profile>
|
||||
<id>m2e</id>
|
||||
<activation>
|
||||
|
@ -410,7 +475,7 @@
|
|||
<plugin>
|
||||
<groupId>org.eclipse.m2e</groupId>
|
||||
<artifactId>lifecycle-mapping</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>${lifecycle-mapping.version}</version>
|
||||
<configuration>
|
||||
<lifecycleMappingMetadata>
|
||||
<pluginExecutions>
|
||||
|
@ -450,5 +515,4 @@
|
|||
</profile>
|
||||
</profiles>
|
||||
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package org.springframework.samples.petclinic.configuration;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
|
||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
|
||||
|
||||
/**
|
||||
* Configuration class to enable WebSocket and STOMP messaging.
|
||||
*
|
||||
* @author Paul-Emmanuel DOS SANTOS FACAO
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
registry.addEndpoint("/websocket")
|
||||
.withSockJS();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry config) {
|
||||
config.setApplicationDestinationPrefixes("/app");
|
||||
config.enableSimpleBroker("/topic/");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.springframework.samples.petclinic.configuration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||
import org.springframework.samples.petclinic.model.common.WebSocketMessage;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class WebSocketSchedulerConfiguration {
|
||||
|
||||
@Autowired
|
||||
SimpMessagingTemplate simpMessagingTemplate;
|
||||
|
||||
@Scheduled(fixedDelay = 3000)
|
||||
public void sendMessages() {
|
||||
|
||||
simpMessagingTemplate.convertAndSend("/topic/user", new WebSocketMessage("Fixed Delay Scheduler"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.springframework.samples.petclinic.controller.common;
|
||||
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
import org.springframework.samples.petclinic.model.common.User;
|
||||
import org.springframework.samples.petclinic.model.common.WebSocketMessage;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
@Controller
|
||||
public class UserController {
|
||||
|
||||
|
||||
@MessageMapping("/user")
|
||||
@SendTo("/topic/user")
|
||||
public WebSocketMessage getUser(User user) {
|
||||
|
||||
return new WebSocketMessage("Hi " + user.getFirstName() + user.getLastName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.springframework.samples.petclinic.controller.common;
|
||||
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
import org.springframework.samples.petclinic.model.common.WebSocketMessage;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
@Controller
|
||||
public class WebSocketController {
|
||||
|
||||
@MessageMapping("/websocket.send")
|
||||
@SendTo("/topic/public")
|
||||
public WebSocketMessage sendMessage(@Payload final WebSocketMessage message) {
|
||||
return message;
|
||||
}
|
||||
|
||||
@MessageMapping("/websocket.newUser")
|
||||
@SendTo("/topic/public")
|
||||
public WebSocketMessage newUser(@Payload final WebSocketMessage message, SimpMessageHeaderAccessor headerAccessor) {
|
||||
headerAccessor.getSessionAttributes().put("usqername", message.getSender());
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.springframework.samples.petclinic.controller.common;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
||||
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
|
||||
import org.springframework.samples.petclinic.model.common.WebSocketMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.messaging.SessionConnectedEvent;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class WebSocketEventListener {
|
||||
|
||||
@Autowired
|
||||
private SimpMessageSendingOperations sendingOperations;
|
||||
|
||||
@EventListener
|
||||
public void handlewebSocketConnectListener(final SessionConnectedEvent event) {
|
||||
log.info("Ding dong. We have a new connection!");
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void handlewebSocketDisconnectListener(final SessionConnectedEvent event) {
|
||||
|
||||
final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());
|
||||
|
||||
final String username = (String) headerAccessor.getSessionAttributes().get("username");
|
||||
|
||||
sendingOperations.convertAndSend("/topic/public", new WebSocketMessage("Hello" + username));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.springframework.samples.petclinic.model.common;
|
||||
|
||||
import org.springframework.samples.petclinic.model.Person;
|
||||
|
||||
public class User extends Person {
|
||||
|
||||
public User() {
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package org.springframework.samples.petclinic.model.common;
|
||||
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class WebSocketMessage {
|
||||
|
||||
private String sender;
|
||||
|
||||
private String time;
|
||||
|
||||
private String content;
|
||||
|
||||
|
||||
public WebSocketMessage(String content) {
|
||||
this.time = LocalDate.now().toString();
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public void setSender(String sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(String time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package org.springframework.samples.petclinic.model.common;
|
||||
|
||||
public enum WebSocketMessageType {
|
||||
MESSAGE,
|
||||
CONNECT,
|
||||
DISCONNECT
|
||||
}
|
Loading…
Reference in a new issue