From 811f0852df4813d4ad8fda1312b6a537f829cafe Mon Sep 17 00:00:00 2001 From: PEDSF Date: Thu, 5 Nov 2020 18:25:17 +0100 Subject: [PATCH] Starting WebSocket --- .../configuration/WebSocketConfig.java | 12 ++-- .../WebSocketSchedulerConfiguration.java | 5 +- .../petclinic/controller/OwnerController.java | 10 ++- .../petclinic/controller/PetController.java | 5 +- .../petclinic/controller/VetController.java | 1 + .../petclinic/controller/VisitController.java | 4 +- .../controller/common/UserController.java | 19 ------ .../common/WebSocketController.java | 7 +-- .../common/WebSocketEventListener.java | 6 +- .../controller/common/WebSocketSender.java | 31 ++++++++++ .../samples/petclinic/model/common/User.java | 10 --- .../model/common/WebSocketMessage.java | 3 +- .../model/common/WebSocketMessageType.java | 6 +- .../resources/messages/messages.properties | 4 ++ .../resources/messages/messages_de.properties | 4 ++ .../resources/messages/messages_es.properties | 8 ++- .../resources/messages/messages_fr.properties | 12 ++++ src/main/resources/static/css/style.css | 7 +++ src/main/resources/static/js/websocket.js | 62 +++++++++++++++++++ .../resources/templates/fragments/layout.html | 45 ++++++++++++-- 20 files changed, 201 insertions(+), 60 deletions(-) delete mode 100644 src/main/java/org/springframework/samples/petclinic/controller/common/UserController.java create mode 100644 src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketSender.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/model/common/User.java create mode 100644 src/main/resources/messages/messages_fr.properties create mode 100644 src/main/resources/static/css/style.css create mode 100644 src/main/resources/static/js/websocket.js diff --git a/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java index c7b1734cc..8d488690b 100644 --- a/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java +++ b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java @@ -17,16 +17,14 @@ import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerCo public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override - public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/websocket") - .withSockJS(); + public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { + stompEndpointRegistry.addEndpoint("/websocket").withSockJS(); } @Override - public void configureMessageBroker(MessageBrokerRegistry config) { - config.setApplicationDestinationPrefixes("/app"); - config.enableSimpleBroker("/topic/"); + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.enableSimpleBroker("/topic"); + registry.setApplicationDestinationPrefixes("/app"); } - } diff --git a/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketSchedulerConfiguration.java b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketSchedulerConfiguration.java index db13377f6..5ee8213ad 100644 --- a/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketSchedulerConfiguration.java +++ b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketSchedulerConfiguration.java @@ -14,9 +14,10 @@ public class WebSocketSchedulerConfiguration { @Autowired SimpMessagingTemplate simpMessagingTemplate; - @Scheduled(fixedDelay = 3000) + //@Scheduled(fixedDelay = 3000) public void sendMessages() { - simpMessagingTemplate.convertAndSend("/topic/user", new WebSocketMessage("Fixed Delay Scheduler")); + simpMessagingTemplate.convertAndSend("/topic/public", new WebSocketMessage("Fixed Delay Scheduler")); } + } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java index 23d0959ef..307c56fd7 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java @@ -19,6 +19,7 @@ import org.springframework.samples.petclinic.common.CommonAttribute; import org.springframework.samples.petclinic.common.CommonEndPoint; import org.springframework.samples.petclinic.common.CommonError; import org.springframework.samples.petclinic.common.CommonView; +import org.springframework.samples.petclinic.controller.common.WebSocketSender; import org.springframework.samples.petclinic.dto.*; import org.springframework.samples.petclinic.service.OwnerService; import org.springframework.samples.petclinic.service.VisitService; @@ -41,7 +42,7 @@ import java.util.Map; * @author Paul-Emmanuel DOS SANTOS FACAO */ @Controller -class OwnerController { +class OwnerController extends WebSocketSender { private final OwnerService ownerService; @@ -68,10 +69,12 @@ class OwnerController { public String processCreationForm(@ModelAttribute(CommonAttribute.OWNER) @Valid OwnerDTO owner, BindingResult result) { if (result.hasErrors()) { + sendMessages(CommonView.OWNER_CREATE_OR_UPDATE); return CommonView.OWNER_CREATE_OR_UPDATE; } else { owner = this.ownerService.save(owner); + sendMessages(OWNER_CREATED); return CommonView.OWNER_OWNERS_R + owner.getId(); } } @@ -79,6 +82,7 @@ class OwnerController { @GetMapping(CommonEndPoint.OWNERS_FIND) public String initFindForm(Map model) { model.put(CommonAttribute.OWNER, new OwnerDTO()); + return CommonView.OWNER_FIND_OWNERS; } @@ -107,7 +111,8 @@ class OwnerController { else { // multiple owners found model.put(CommonAttribute.SELECTIONS, results); - return CommonView.OWNER_OWNERS_LIST; + + return CommonView.OWNER_OWNERS_LIST; } } @@ -127,6 +132,7 @@ class OwnerController { else { owner.setId(ownerId); this.ownerService.save(owner); + sendMessages(OWNER_UPDATED); return CommonView.OWNER_OWNERS_ID_R; } } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java index fa7aed54e..873508f7b 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java @@ -20,6 +20,7 @@ import org.springframework.samples.petclinic.common.CommonAttribute; import org.springframework.samples.petclinic.common.CommonEndPoint; import org.springframework.samples.petclinic.common.CommonError; import org.springframework.samples.petclinic.common.CommonView; +import org.springframework.samples.petclinic.controller.common.WebSocketSender; import org.springframework.samples.petclinic.dto.*; import org.springframework.samples.petclinic.validator.PetDTOValidator; import org.springframework.samples.petclinic.service.*; @@ -41,7 +42,7 @@ import java.util.Collection; */ @Controller @RequestMapping(CommonEndPoint.OWNERS_ID) -class PetController { +class PetController extends WebSocketSender { private final OwnerService ownerService; @@ -100,6 +101,7 @@ class PetController { } else { this.petService.save(pet); + sendMessages(PET_CREATED); return CommonView.OWNER_OWNERS_ID_R; } } @@ -122,6 +124,7 @@ class PetController { else { owner.addPet(pet); this.petService.save(pet); + sendMessages(PET_UPDATED); return CommonView.OWNER_OWNERS_ID_R; } } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/VetController.java b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java index 1cb496e31..fe70ecc9e 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java @@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.controller; import org.springframework.samples.petclinic.common.CommonAttribute; import org.springframework.samples.petclinic.common.CommonEndPoint; import org.springframework.samples.petclinic.common.CommonView; +import org.springframework.samples.petclinic.controller.common.WebSocketSender; import org.springframework.samples.petclinic.dto.VetsDTO; import org.springframework.samples.petclinic.service.VetService; import org.springframework.stereotype.Controller; diff --git a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java index 25c445352..53b88605b 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java @@ -22,6 +22,7 @@ import javax.validation.Valid; import org.springframework.samples.petclinic.common.CommonAttribute; import org.springframework.samples.petclinic.common.CommonEndPoint; import org.springframework.samples.petclinic.common.CommonView; +import org.springframework.samples.petclinic.controller.common.WebSocketSender; import org.springframework.samples.petclinic.dto.PetDTO; import org.springframework.samples.petclinic.dto.VisitDTO; import org.springframework.samples.petclinic.service.PetService; @@ -46,7 +47,7 @@ import org.springframework.web.bind.annotation.PostMapping; * @author Paul-Emmanuel DOS SANTOS FACAO */ @Controller -class VisitController { +class VisitController extends WebSocketSender { private final VisitService visitService; @@ -99,6 +100,7 @@ class VisitController { } else { this.visitService.save(visit); + sendMessages(VISIT_CREATED); return CommonView.OWNER_OWNERS_ID_R; } } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/common/UserController.java b/src/main/java/org/springframework/samples/petclinic/controller/common/UserController.java deleted file mode 100644 index fe16663c7..000000000 --- a/src/main/java/org/springframework/samples/petclinic/controller/common/UserController.java +++ /dev/null @@ -1,19 +0,0 @@ -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()); - } -} diff --git a/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketController.java b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketController.java index 5074205b7..00bcc059d 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketController.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketController.java @@ -7,11 +7,10 @@ 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") + @MessageMapping("/user") + @SendTo("/topic/user") public WebSocketMessage sendMessage(@Payload final WebSocketMessage message) { return message; } @@ -19,7 +18,7 @@ public class WebSocketController { @MessageMapping("/websocket.newUser") @SendTo("/topic/public") public WebSocketMessage newUser(@Payload final WebSocketMessage message, SimpMessageHeaderAccessor headerAccessor) { - headerAccessor.getSessionAttributes().put("usqername", message.getSender()); + headerAccessor.getSessionAttributes().put("username", message.getSender()); return message; } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketEventListener.java b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketEventListener.java index 0ddfbc523..e13ae5e70 100644 --- a/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketEventListener.java +++ b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketEventListener.java @@ -26,8 +26,10 @@ public class WebSocketEventListener { final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage()); - final String username = (String) headerAccessor.getSessionAttributes().get("username"); + // final String username = (String) + // headerAccessor.getSessionAttributes().get("username"); - sendingOperations.convertAndSend("/topic/public", new WebSocketMessage("Hello" + username)); + sendingOperations.convertAndSend("/topic/user", new WebSocketMessage("Hello in event lmistener")); } + } diff --git a/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketSender.java b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketSender.java new file mode 100644 index 000000000..fafcda13f --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketSender.java @@ -0,0 +1,31 @@ +package org.springframework.samples.petclinic.controller.common; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.samples.petclinic.model.common.WebSocketMessage; + +public class WebSocketSender { + public static final String OWNER_CREATED = "Owner created"; + public static final String OWNER_UPDATED = "Owner updated"; + public static final String OWNER_DELETED = "Owner deleted"; + + public static final String PET_CREATED = "Pet created"; + public static final String PET_UPDATED = "Pet updated"; + public static final String PET_DELETED = "Pet deleted"; + + public static final String VET_CREATED = "Vet created"; + public static final String VET_UPDATED = "Vet updated"; + public static final String VET_DELETED = "Vet deleted"; + + public static final String VISIT_CREATED = "Visit created"; + public static final String VISIT_UPDATED = "Visit updated"; + public static final String VISIT_DELETED = "Visit deleted"; + + + @Autowired + SimpMessagingTemplate simpMessagingTemplate; + + public void sendMessages(String message) { + simpMessagingTemplate.convertAndSend("/topic/public", new WebSocketMessage(message)); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/model/common/User.java b/src/main/java/org/springframework/samples/petclinic/model/common/User.java deleted file mode 100644 index 6cad7820e..000000000 --- a/src/main/java/org/springframework/samples/petclinic/model/common/User.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.springframework.samples.petclinic.model.common; - -import org.springframework.samples.petclinic.model.Person; - -public class User extends Person { - - public User() { - super(); - } -} diff --git a/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessage.java b/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessage.java index 916cf3df6..357c3f7d0 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessage.java +++ b/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessage.java @@ -1,6 +1,5 @@ package org.springframework.samples.petclinic.model.common; - import java.time.LocalDate; public class WebSocketMessage { @@ -11,7 +10,6 @@ public class WebSocketMessage { private String content; - public WebSocketMessage(String content) { this.time = LocalDate.now().toString(); this.content = content; @@ -40,4 +38,5 @@ public class WebSocketMessage { public void setContent(String content) { this.content = content; } + } diff --git a/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessageType.java b/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessageType.java index 52d946eaf..423c82152 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessageType.java +++ b/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessageType.java @@ -1,7 +1,7 @@ package org.springframework.samples.petclinic.model.common; public enum WebSocketMessageType { - MESSAGE, - CONNECT, - DISCONNECT + + MESSAGE, CONNECT, DISCONNECT + } diff --git a/src/main/resources/messages/messages.properties b/src/main/resources/messages/messages.properties index 173417a10..ec1b9befd 100644 --- a/src/main/resources/messages/messages.properties +++ b/src/main/resources/messages/messages.properties @@ -6,3 +6,7 @@ nonNumeric=must be all numeric duplicateFormSubmission=Duplicate form submission is not allowed typeMismatch.date=invalid date typeMismatch.birthDate=invalid date +english=English +french=French +german=German +spanish=Spanish diff --git a/src/main/resources/messages/messages_de.properties b/src/main/resources/messages/messages_de.properties index 124bee48b..1de602f81 100644 --- a/src/main/resources/messages/messages_de.properties +++ b/src/main/resources/messages/messages_de.properties @@ -6,3 +6,7 @@ nonNumeric=darf nur numerisch sein duplicateFormSubmission=Wiederholtes Absenden des Formulars ist nicht erlaubt typeMismatch.date=ungültiges Datum typeMismatch.birthDate=ungültiges Datum +english=Englisch +french=Französisch +german=Deutsche +spanish=Spanisch diff --git a/src/main/resources/messages/messages_es.properties b/src/main/resources/messages/messages_es.properties index 33ee867b5..f4a72d44c 100644 --- a/src/main/resources/messages/messages_es.properties +++ b/src/main/resources/messages/messages_es.properties @@ -1,8 +1,12 @@ welcome=Bienvenido -required=Es requerido +required=es requerido notFound=No ha sido encontrado duplicate=Ya se encuentra en uso nonNumeric=Sólo debe contener numeros duplicateFormSubmission=No se permite el envío de formularios duplicados -typeMismatch.date=Fecha invalida +typeMismatch.date=fecha invalida typeMismatch.birthDate=Fecha invalida +english=Ingl\u00E9s +french=Franc\u00E9s +german=Alemán +spanish=Espa\u00F1ol diff --git a/src/main/resources/messages/messages_fr.properties b/src/main/resources/messages/messages_fr.properties new file mode 100644 index 000000000..164aefcd8 --- /dev/null +++ b/src/main/resources/messages/messages_fr.properties @@ -0,0 +1,12 @@ +welcome=Bienvenue +required=est requis +notFound=n'a pas \u00E9t\u00E9 trouv\u00E9 +duplicate=d\u00E9jà utilis\u00E9 +nonNumeric=doit être num\u00E9rique +duplicateFormSubmission=La duplication de formulaire n'est pas autoris\u00E9e +typeMismatch.date=date non valide +typeMismatch.birthDate=date non valide +english=Anglais +french=Fran\u00E7ais +german=Allemand +spanish=Espagnol diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css new file mode 100644 index 000000000..59c3f0594 --- /dev/null +++ b/src/main/resources/static/css/style.css @@ -0,0 +1,7 @@ +#footer { + position:absolute; + bottom:0; + width:100%; + height:60px; /* Height of the footer */ + background:#6cf; +} diff --git a/src/main/resources/static/js/websocket.js b/src/main/resources/static/js/websocket.js new file mode 100644 index 000000000..0afb5e6f1 --- /dev/null +++ b/src/main/resources/static/js/websocket.js @@ -0,0 +1,62 @@ +var stompClient = null; + +function setConnected(connected) { + $("#connect").prop("disabled", connected); + $("#disconnect").prop("disabled", !connected); + if (connected) { + $("#conversation").show(); + } + else { + $("#conversation").hide(); + } + $("#userinfo").html(""); +} + +function displayMessage() { + var socket = new SockJS('/websocket'); + stompClient = Stomp.over(socket); + stompClient.connect({}, function (frame) { + setConnected(true); + stompClient.subscribe('/topic/public', function (greeting) { + showGreeting(JSON.parse(greeting.body).content); + }); + }); +} + + +function connect() { + var socket = new SockJS('/websocket'); + stompClient = Stomp.over(socket); + stompClient.connect({}, function (frame) { + setConnected(true); + console.log('Connected: ' + frame); + stompClient.subscribe('/topic/public', function (greeting) { + $("#userinfo").text(JSON.parse(greeting.body).content); + }); + }); +} + +function disconnect() { + if (stompClient !== null) { + stompClient.disconnect(); + } + setConnected(false); + console.log("Disconnected"); +} + +function sendName() { + stompClient.send("/app/user", {}, JSON.stringify({'name': $("#name").val()})); +} + +function showGreeting(message) { + $("#userinfo").text(message); +} + +$(function () { + $("form").on('submit', function (e) { + e.preventDefault(); + }); + $( "#connect" ).click(function() { connect(); }); + $( "#disconnect" ).click(function() { disconnect(); }); + $( "#send" ).click(function() { sendName(); }); +}); diff --git a/src/main/resources/templates/fragments/layout.html b/src/main/resources/templates/fragments/layout.html index f3b207483..621ec8976 100755 --- a/src/main/resources/templates/fragments/layout.html +++ b/src/main/resources/templates/fragments/layout.html @@ -18,6 +18,7 @@ + @@ -78,6 +79,8 @@ + +
@@ -86,18 +89,50 @@

-
-
- Sponsored by Pivotal
-
+
+
+
+
+
+
+ +
+
+ Sponsored by Pivotal +
+
+
+
+ +
+ + + + +