diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java index d47ea95fc6..fe9246b4b2 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.messaging.simp.annotation.support; import java.lang.annotation.Annotation; +import java.security.Principal; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.AnnotationUtils; @@ -28,6 +29,7 @@ import org.springframework.messaging.handler.invocation.HandlerMethodReturnValue import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessageSendingOperations; import org.springframework.messaging.simp.annotation.SendToUser; +import org.springframework.messaging.simp.user.DestinationUserNameProvider; import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -124,13 +126,17 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH SendToUser sendToUser = returnType.getMethodAnnotation(SendToUser.class); if (sendToUser != null) { - if (inputHeaders.getUser() == null) { + Principal principal = inputHeaders.getUser(); + if (principal == null) { throw new MissingSessionUserException(inputMessage); } - String user = inputHeaders.getUser().getName(); + String userName = principal.getName(); + if (principal instanceof DestinationUserNameProvider) { + userName = ((DestinationUserNameProvider) principal).getDestinationUserName(); + } String[] destinations = getTargetDestinations(sendToUser, inputHeaders, this.defaultUserDestinationPrefix); for (String destination : destinations) { - this.messagingTemplate.convertAndSendToUser(user, destination, returnValue, postProcessor); + this.messagingTemplate.convertAndSendToUser(userName, destination, returnValue, postProcessor); } return; } diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandlerTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandlerTests.java index 11c7dd6268..fe35c9b149 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandlerTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,9 @@ import org.springframework.messaging.MessageChannel; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.messaging.simp.TestPrincipal; import org.springframework.messaging.simp.annotation.SendToUser; +import org.springframework.messaging.simp.user.DestinationUserNameProvider; import org.springframework.messaging.support.MessageBuilder; import org.springframework.messaging.converter.MessageConverter; @@ -126,7 +128,7 @@ public class SendToMethodReturnValueHandlerTests { } @Test - public void sendToMethod() throws Exception { + public void sendTo() throws Exception { when(this.messageChannel.send(any(Message.class))).thenReturn(true); @@ -150,7 +152,7 @@ public class SendToMethodReturnValueHandlerTests { } @Test - public void sendToDefaultDestinationMethod() throws Exception { + public void sendToDefaultDestination() throws Exception { when(this.messageChannel.send(any(Message.class))).thenReturn(true); @@ -168,7 +170,7 @@ public class SendToMethodReturnValueHandlerTests { } @Test - public void sendToUserMethod() throws Exception { + public void sendToUser() throws Exception { when(this.messageChannel.send(any(Message.class))).thenReturn(true); @@ -193,7 +195,26 @@ public class SendToMethodReturnValueHandlerTests { } @Test - public void sendToUserDefaultDestinationMethod() throws Exception { + public void sendToUserWithUserNameProvider() throws Exception { + + when(this.messageChannel.send(any(Message.class))).thenReturn(true); + + String sessionId = "sess1"; + TestUser user = new UniqueUser(); + Message inputMessage = createInputMessage(sessionId, "sub1", null, user); + this.handler.handleReturnValue(payloadContent, this.sendToUserReturnType, inputMessage); + + verify(this.messageChannel, times(2)).send(this.messageCaptor.capture()); + + SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(this.messageCaptor.getAllValues().get(0)); + assertEquals("/user/Me myself and I/dest1", headers.getDestination()); + + headers = SimpMessageHeaderAccessor.wrap(this.messageCaptor.getAllValues().get(1)); + assertEquals("/user/Me myself and I/dest2", headers.getDestination()); + } + + @Test + public void sendToUserDefaultDestination() throws Exception { when(this.messageChannel.send(any(Message.class))).thenReturn(true); @@ -236,6 +257,14 @@ public class SendToMethodReturnValueHandlerTests { } } + private static class UniqueUser extends TestUser implements DestinationUserNameProvider { + + @Override + public String getDestinationUserName() { + return "Me myself and I"; + } + } + public String handleNoAnnotations() { return payloadContent; } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/StompSubProtocolHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/StompSubProtocolHandler.java index aab7bebc6f..4e7f17f0e3 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/StompSubProtocolHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/StompSubProtocolHandler.java @@ -241,13 +241,13 @@ public class StompSubProtocolHandler implements SubProtocolHandler { if (principal != null) { headers.setNativeHeader(CONNECTED_USER_HEADER, principal.getName()); if (this.userSessionRegistry != null) { - String userName = getNameForUserSessionRegistry(principal); + String userName = resolveNameForUserSessionRegistry(principal); this.userSessionRegistry.registerSessionId(userName, session.getId()); } } } - private String getNameForUserSessionRegistry(Principal principal) { + private String resolveNameForUserSessionRegistry(Principal principal) { String userName = principal.getName(); if (principal instanceof DestinationUserNameProvider) { userName = ((DestinationUserNameProvider) principal).getDestinationUserName(); @@ -270,7 +270,7 @@ public class StompSubProtocolHandler implements SubProtocolHandler { Principal principal = session.getPrincipal(); if ((this.userSessionRegistry != null) && (principal != null)) { - String userName = getNameForUserSessionRegistry(principal); + String userName = resolveNameForUserSessionRegistry(principal); this.userSessionRegistry.unregisterSessionId(userName, session.getId()); }