Add MessageHandler destination prefix checks
This commit is contained in:
parent
2cdac267f7
commit
b3c7c18c1b
|
|
@ -42,6 +42,7 @@ import org.springframework.messaging.handler.annotation.MessageMapping;
|
|||
import org.springframework.messaging.handler.annotation.ReplyTo;
|
||||
import org.springframework.messaging.handler.annotation.support.ExceptionHandlerMethodResolver;
|
||||
import org.springframework.messaging.handler.annotation.support.MessageBodyMethodArgumentResolver;
|
||||
import org.springframework.messaging.handler.annotation.support.MessageMethodArgumentResolver;
|
||||
import org.springframework.messaging.handler.method.HandlerMethod;
|
||||
import org.springframework.messaging.handler.method.HandlerMethodArgumentResolverComposite;
|
||||
import org.springframework.messaging.handler.method.HandlerMethodReturnValueHandlerComposite;
|
||||
|
|
@ -75,6 +76,8 @@ public class AnnotationMethodMessageHandler implements MessageHandler, Applicati
|
|||
|
||||
private final SimpMessageSendingOperations webSocketSessionMessagingTemplate;
|
||||
|
||||
private List<String> destinationPrefixes;
|
||||
|
||||
private MessageConverter<?> messageConverter;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
|
@ -110,9 +113,15 @@ public class AnnotationMethodMessageHandler implements MessageHandler, Applicati
|
|||
this.webSocketSessionMessagingTemplate = new SimpMessagingTemplate(webSocketSessionChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: multiple converters with 'content-type' header
|
||||
*/
|
||||
|
||||
public void setDestinationPrefixes(List<String> destinationPrefixes) {
|
||||
this.destinationPrefixes = destinationPrefixes;
|
||||
}
|
||||
|
||||
public List<String> getDestinationPrefixes() {
|
||||
return this.destinationPrefixes;
|
||||
}
|
||||
|
||||
public void setMessageConverter(MessageConverter<?> converter) {
|
||||
this.messageConverter = converter;
|
||||
if (converter != null) {
|
||||
|
|
@ -120,6 +129,10 @@ public class AnnotationMethodMessageHandler implements MessageHandler, Applicati
|
|||
}
|
||||
}
|
||||
|
||||
public MessageConverter<?> getMessageConverter() {
|
||||
return this.messageConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
|
|
@ -131,6 +144,7 @@ public class AnnotationMethodMessageHandler implements MessageHandler, Applicati
|
|||
initHandlerMethods();
|
||||
|
||||
this.argumentResolvers.addResolver(new PrincipalMethodArgumentResolver());
|
||||
this.argumentResolvers.addResolver(new MessageMethodArgumentResolver());
|
||||
this.argumentResolvers.addResolver(new MessageBodyMethodArgumentResolver(this.messageConverter));
|
||||
|
||||
this.returnValueHandlers.addHandler(new ReplyToMethodReturnValueHandler(this.dispatchMessagingTemplate));
|
||||
|
|
@ -147,8 +161,7 @@ public class AnnotationMethodMessageHandler implements MessageHandler, Applicati
|
|||
}
|
||||
|
||||
protected boolean isHandler(Class<?> beanType) {
|
||||
return ((AnnotationUtils.findAnnotation(beanType, Controller.class) != null) ||
|
||||
(AnnotationUtils.findAnnotation(beanType, MessageMapping.class) != null));
|
||||
return (AnnotationUtils.findAnnotation(beanType, Controller.class) != null);
|
||||
}
|
||||
|
||||
protected void detectHandlerMethods(Object handler) {
|
||||
|
|
@ -220,11 +233,19 @@ public class AnnotationMethodMessageHandler implements MessageHandler, Applicati
|
|||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
|
||||
String destination = headers.getDestination();
|
||||
|
||||
if (!checkDestinationPrefix(destination)) {
|
||||
return;
|
||||
}
|
||||
|
||||
HandlerMethod match = getHandlerMethod(destination, handlerMethods);
|
||||
if (match == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Processing message: " + message);
|
||||
}
|
||||
|
||||
HandlerMethod handlerMethod = match.createWithResolvedBean();
|
||||
|
||||
InvocableHandlerMethod invocableHandlerMethod = new InvocableHandlerMethod(handlerMethod);
|
||||
|
|
@ -248,6 +269,17 @@ public class AnnotationMethodMessageHandler implements MessageHandler, Applicati
|
|||
}
|
||||
}
|
||||
|
||||
private boolean checkDestinationPrefix(String destination) {
|
||||
if ((destination != null) && (this.destinationPrefixes != null)) {
|
||||
for (String prefix : this.destinationPrefixes) {
|
||||
if (destination.startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void invokeExceptionHandler(Message<?> message, HandlerMethod handlerMethod, Exception ex) {
|
||||
|
||||
InvocableHandlerMethod exceptionHandlerMethod;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.messaging.simp.handler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.messaging.Message;
|
||||
|
|
@ -39,6 +41,8 @@ public class SimpleBrokerMessageHandler implements MessageHandler {
|
|||
|
||||
private final MessageChannel messageChannel;
|
||||
|
||||
private List<String> destinationPrefixes;
|
||||
|
||||
private SubscriptionRegistry subscriptionRegistry = new DefaultSubscriptionRegistry();
|
||||
|
||||
|
||||
|
|
@ -51,6 +55,14 @@ public class SimpleBrokerMessageHandler implements MessageHandler {
|
|||
}
|
||||
|
||||
|
||||
public void setDestinationPrefixes(List<String> destinationPrefixes) {
|
||||
this.destinationPrefixes = destinationPrefixes;
|
||||
}
|
||||
|
||||
public List<String> getDestinationPrefixes() {
|
||||
return this.destinationPrefixes;
|
||||
}
|
||||
|
||||
public void setSubscriptionRegistry(SubscriptionRegistry subscriptionRegistry) {
|
||||
Assert.notNull(subscriptionRegistry, "subscriptionRegistry is required");
|
||||
this.subscriptionRegistry = subscriptionRegistry;
|
||||
|
|
@ -65,6 +77,11 @@ public class SimpleBrokerMessageHandler implements MessageHandler {
|
|||
|
||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
|
||||
SimpMessageType messageType = headers.getMessageType();
|
||||
String destination = headers.getDestination();
|
||||
|
||||
if (!checkDestinationPrefix(destination)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SimpMessageType.SUBSCRIBE.equals(messageType)) {
|
||||
preProcessMessage(message);
|
||||
|
|
@ -85,6 +102,17 @@ public class SimpleBrokerMessageHandler implements MessageHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean checkDestinationPrefix(String destination) {
|
||||
if ((destination != null) && (this.destinationPrefixes != null)) {
|
||||
for (String prefix : this.destinationPrefixes) {
|
||||
if (destination.startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void preProcessMessage(Message<?> message) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Processing " + message);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
|||
import org.springframework.messaging.simp.SimpMessageType;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -48,7 +47,7 @@ public class UserDestinationMessageHandler implements MessageHandler {
|
|||
|
||||
private final MessageSendingOperations<String> messagingTemplate;
|
||||
|
||||
private String prefix = "/user/";
|
||||
private String destinationPrefix = "/user/";
|
||||
|
||||
private UserQueueSuffixResolver userQueueSuffixResolver = new SimpleUserQueueSuffixResolver();
|
||||
|
||||
|
|
@ -72,16 +71,16 @@ public class UserDestinationMessageHandler implements MessageHandler {
|
|||
* <p>The default prefix is "/user".
|
||||
* @param prefix the prefix to set
|
||||
*/
|
||||
public void setPrefix(String prefix) {
|
||||
public void setDestinationPrefix(String prefix) {
|
||||
Assert.hasText(prefix, "prefix is required");
|
||||
this.prefix = prefix.endsWith("/") ? prefix : prefix + "/";
|
||||
this.destinationPrefix = prefix.endsWith("/") ? prefix : prefix + "/";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the prefix
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return this.prefix;
|
||||
public String getDestinationPrefix() {
|
||||
return this.destinationPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -101,12 +100,17 @@ public class UserDestinationMessageHandler implements MessageHandler {
|
|||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
|
||||
if (!shouldHandle(message)) {
|
||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
|
||||
SimpMessageType messageType = headers.getMessageType();
|
||||
String destination = headers.getDestination();
|
||||
|
||||
if (!SimpMessageType.MESSAGE.equals(messageType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
|
||||
String destination = headers.getDestination();
|
||||
if (!checkDestination(destination)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Processing message to destination " + destination);
|
||||
|
|
@ -117,7 +121,7 @@ public class UserDestinationMessageHandler implements MessageHandler {
|
|||
|
||||
if (user == null) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Ignoring message, expected destination \"" + this.prefix
|
||||
logger.error("Ignoring message, expected destination pattern \"" + this.destinationPrefix
|
||||
+ "{userId}/**\": " + destination);
|
||||
}
|
||||
return;
|
||||
|
|
@ -136,27 +140,13 @@ public class UserDestinationMessageHandler implements MessageHandler {
|
|||
}
|
||||
}
|
||||
|
||||
protected boolean shouldHandle(Message<?> message) {
|
||||
|
||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
|
||||
SimpMessageType messageType = headers.getMessageType();
|
||||
String destination = headers.getDestination();
|
||||
|
||||
if (!SimpMessageType.MESSAGE.equals(messageType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(destination)) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Ignoring message, no destination: " + headers);
|
||||
private boolean checkDestination(String destination) {
|
||||
if (destination != null) {
|
||||
if (destination.startsWith(this.destinationPrefix)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (!destination.startsWith(this.prefix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -169,7 +159,7 @@ public class UserDestinationMessageHandler implements MessageHandler {
|
|||
|
||||
public UserDestinationParser(String destination) {
|
||||
|
||||
int userStartIndex = prefix.length();
|
||||
int userStartIndex = destinationPrefix.length();
|
||||
int userEndIndex = destination.indexOf('/', userStartIndex);
|
||||
|
||||
if (userEndIndex > 0) {
|
||||
|
|
|
|||
|
|
@ -285,13 +285,9 @@ public class StompBrokerRelayMessageHandler implements MessageHandler, SmartLife
|
|||
logger.error("Ignoring message, no sessionId: " + message);
|
||||
return;
|
||||
}
|
||||
if (command.requiresDestination() && (destination == null)) {
|
||||
logger.error("Ignoring " + command + " message, no destination: " + message);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if ((destination == null) || supportsDestination(destination)) {
|
||||
if (checkDestinationPrefix(command, destination)) {
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Processing message: " + message);
|
||||
|
|
@ -329,7 +325,13 @@ public class StompBrokerRelayMessageHandler implements MessageHandler, SmartLife
|
|||
}
|
||||
}
|
||||
|
||||
protected boolean supportsDestination(String destination) {
|
||||
protected boolean checkDestinationPrefix(StompCommand command, String destination) {
|
||||
if (!command.requiresDestination()) {
|
||||
return true;
|
||||
}
|
||||
else if (destination == null) {
|
||||
return false;
|
||||
}
|
||||
for (String prefix : this.destinationPrefixes) {
|
||||
if (destination.startsWith(prefix)) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public class MappingJackson2MessageConverter implements MessageConverter<Object>
|
|||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new MessageConversionException("Could not read JSON: " + ex.getMessage(), ex);
|
||||
throw new MessageConversionException(message, "Could not read JSON: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue