Allow Validator config in XML websocket namespace
This commit adds a new "validator" XML attribute to the `<websocket:message-broker/>` element. This allows configuring a specific Validator to be used for payload validation. Issue: SPR-13996
This commit is contained in:
parent
8e24a4153c
commit
8ca6a18dae
|
|
@ -853,6 +853,7 @@ public class MvcNamespaceTests {
|
||||||
ContentNegotiationManager manager = (ContentNegotiationManager) accessor.getPropertyValue(beanName);
|
ContentNegotiationManager manager = (ContentNegotiationManager) accessor.getPropertyValue(beanName);
|
||||||
assertNotNull(manager);
|
assertNotNull(manager);
|
||||||
assertSame(manager, this.appContext.getBean(ContentNegotiationManager.class));
|
assertSame(manager, this.appContext.getBean(ContentNegotiationManager.class));
|
||||||
|
assertSame(manager, this.appContext.getBean("mvcContentNegotiationManager"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -109,6 +109,9 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
private static final boolean jackson2Present = ClassUtils.isPresent(
|
private static final boolean jackson2Present = ClassUtils.isPresent(
|
||||||
"com.fasterxml.jackson.databind.ObjectMapper", MessageBrokerBeanDefinitionParser.class.getClassLoader());
|
"com.fasterxml.jackson.databind.ObjectMapper", MessageBrokerBeanDefinitionParser.class.getClassLoader());
|
||||||
|
|
||||||
|
private static final boolean javaxValidationPresent =
|
||||||
|
ClassUtils.isPresent("javax.validation.Validator", MessageBrokerBeanDefinitionParser.class.getClassLoader());
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BeanDefinition parse(Element element, ParserContext context) {
|
public BeanDefinition parse(Element element, ParserContext context) {
|
||||||
|
|
@ -516,6 +519,11 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
beanDef.getPropertyValues().add("pathMatcher", new RuntimeBeanReference(pathMatcherRef));
|
beanDef.getPropertyValues().add("pathMatcher", new RuntimeBeanReference(pathMatcherRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RuntimeBeanReference validatorRef = getValidator(messageBrokerElement, source, context);
|
||||||
|
if (validatorRef != null) {
|
||||||
|
beanDef.getPropertyValues().add("validator", validatorRef);
|
||||||
|
}
|
||||||
|
|
||||||
Element resolversElement = DomUtils.getChildElementByTagName(messageBrokerElement, "argument-resolvers");
|
Element resolversElement = DomUtils.getChildElementByTagName(messageBrokerElement, "argument-resolvers");
|
||||||
if (resolversElement != null) {
|
if (resolversElement != null) {
|
||||||
values.add("customArgumentResolvers", extractBeanSubElements(resolversElement, context));
|
values.add("customArgumentResolvers", extractBeanSubElements(resolversElement, context));
|
||||||
|
|
@ -529,6 +537,24 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
registerBeanDef(beanDef, context, source);
|
registerBeanDef(beanDef, context, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RuntimeBeanReference getValidator(Element messageBrokerElement, Object source, ParserContext parserContext) {
|
||||||
|
if (messageBrokerElement.hasAttribute("validator")) {
|
||||||
|
return new RuntimeBeanReference(messageBrokerElement.getAttribute("validator"));
|
||||||
|
}
|
||||||
|
else if (javaxValidationPresent) {
|
||||||
|
RootBeanDefinition validatorDef = new RootBeanDefinition(
|
||||||
|
"org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean");
|
||||||
|
validatorDef.setSource(source);
|
||||||
|
validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||||
|
String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef);
|
||||||
|
parserContext.registerComponent(new BeanComponentDefinition(validatorDef, validatorName));
|
||||||
|
return new RuntimeBeanReference(validatorName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ManagedList<Object> extractBeanSubElements(Element parentElement, ParserContext parserContext) {
|
private ManagedList<Object> extractBeanSubElements(Element parentElement, ParserContext parserContext) {
|
||||||
ManagedList<Object> list = new ManagedList<Object>();
|
ManagedList<Object> list = new ManagedList<Object>();
|
||||||
list.setSource(parserContext.extractSource(parentElement));
|
list.setSource(parserContext.extractSource(parentElement));
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation><![CDATA[
|
<xsd:documentation><![CDATA[
|
||||||
A path that maps a particular request to a handler.
|
A path that maps a particular request to a handler.
|
||||||
Exact path mapping URIs (such as "/myPath") are supported as well as Ant-stype path patterns (such as /myPath/**).
|
Exact path mapping URIs (such as "/myPath") are supported as well as Ant-type path patterns (such as /myPath/**).
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
|
@ -916,9 +916,16 @@
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation><![CDATA[
|
<xsd:documentation><![CDATA[
|
||||||
The bean name of the UrlPathHelper to use for the HandlerMapping used to map handshake requests.
|
The bean name of the UrlPathHelper to use for the HandlerMapping used to map handshake requests.
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="validator" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The bean name of the Validator instance used for validating @Payload arguments.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
</xsd:schema>
|
</xsd:schema>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -60,6 +60,8 @@ import org.springframework.mock.web.test.MockServletContext;
|
||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||||
import org.springframework.util.MimeTypeUtils;
|
import org.springframework.util.MimeTypeUtils;
|
||||||
|
import org.springframework.validation.Errors;
|
||||||
|
import org.springframework.validation.Validator;
|
||||||
import org.springframework.web.HttpRequestHandler;
|
import org.springframework.web.HttpRequestHandler;
|
||||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
|
@ -356,6 +358,14 @@ public class MessageBrokerBeanDefinitionParserTests {
|
||||||
public void customChannels() {
|
public void customChannels() {
|
||||||
loadBeanDefinitions("websocket-config-broker-customchannels.xml");
|
loadBeanDefinitions("websocket-config-broker-customchannels.xml");
|
||||||
|
|
||||||
|
SimpAnnotationMethodMessageHandler annotationMethodMessageHandler =
|
||||||
|
this.appContext.getBean(SimpAnnotationMethodMessageHandler.class);
|
||||||
|
|
||||||
|
Validator validator = annotationMethodMessageHandler.getValidator();
|
||||||
|
assertNotNull(validator);
|
||||||
|
assertSame(this.appContext.getBean("myValidator"), validator);
|
||||||
|
assertThat(validator, Matchers.instanceOf(TestValidator.class));
|
||||||
|
|
||||||
List<Class<? extends MessageHandler>> subscriberTypes =
|
List<Class<? extends MessageHandler>> subscriberTypes =
|
||||||
Arrays.<Class<? extends MessageHandler>>asList(SimpAnnotationMethodMessageHandler.class,
|
Arrays.<Class<? extends MessageHandler>>asList(SimpAnnotationMethodMessageHandler.class,
|
||||||
UserDestinationMessageHandler.class, SimpleBrokerMessageHandler.class);
|
UserDestinationMessageHandler.class, SimpleBrokerMessageHandler.class);
|
||||||
|
|
@ -520,3 +530,13 @@ class TestWebSocketHandlerDecorator extends WebSocketHandlerDecorator {
|
||||||
|
|
||||||
class TestStompErrorHandler extends StompSubProtocolErrorHandler {
|
class TestStompErrorHandler extends StompSubProtocolErrorHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestValidator implements Validator {
|
||||||
|
@Override
|
||||||
|
public boolean supports(Class<?> clazz) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate(Object target, Errors errors) { }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||||
|
|
||||||
<websocket:message-broker application-destination-prefix="/app" user-destination-prefix="/personal">
|
<websocket:message-broker application-destination-prefix="/app" user-destination-prefix="/personal" validator="myValidator">
|
||||||
<websocket:stomp-endpoint path="/foo,/bar">
|
<websocket:stomp-endpoint path="/foo,/bar">
|
||||||
<websocket:handshake-handler ref="myHandler"/>
|
<websocket:handshake-handler ref="myHandler"/>
|
||||||
</websocket:stomp-endpoint>
|
</websocket:stomp-endpoint>
|
||||||
|
|
@ -31,4 +31,6 @@
|
||||||
|
|
||||||
<bean id="myInterceptor" class="org.springframework.web.socket.config.TestChannelInterceptor"/>
|
<bean id="myInterceptor" class="org.springframework.web.socket.config.TestChannelInterceptor"/>
|
||||||
|
|
||||||
|
<bean id="myValidator" class="org.springframework.web.socket.config.TestValidator"/>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue