GH-3180: Add encoding-mode to WS outbound gateway (#3191)
* GH-3180: Add encoding-mode to WS outbound gateway Fixes https://github.com/spring-projects/spring-integration/issues/3180 * Deprecate `encode-uri` in favor of newly introduced `encoding-mode` * Add new property to XML and DSL configurations * Fix tests according a new behavior * Document the feature * Fix docs for deprecated `encode-uri` * Mention also WS from `http.adoc` * * Fix typos in docs
This commit is contained in:
@@ -18,7 +18,6 @@ package org.springframework.integration.ws;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -35,8 +34,7 @@ import org.springframework.messaging.MessageDeliveryException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.client.core.FaultMessageResolver;
|
||||
@@ -60,11 +58,13 @@ import org.springframework.xml.transform.TransformerObjectSupport;
|
||||
*/
|
||||
public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyProducingMessageHandler {
|
||||
|
||||
protected final DefaultUriBuilderFactory uriFactory = new DefaultUriBuilderFactory(); // NOSONAR - final
|
||||
|
||||
private final String uri;
|
||||
|
||||
private final DestinationProvider destinationProvider;
|
||||
|
||||
private final Map<String, Expression> uriVariableExpressions = new HashMap<String, Expression>();
|
||||
private final Map<String, Expression> uriVariableExpressions = new HashMap<>();
|
||||
|
||||
private StandardEvaluationContext evaluationContext;
|
||||
|
||||
@@ -74,8 +74,6 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
|
||||
private boolean ignoreEmptyResponses = true;
|
||||
|
||||
private boolean encodeUri = true;
|
||||
|
||||
private SoapHeaderMapper headerMapper = new DefaultSoapHeaderMapper();
|
||||
|
||||
private boolean webServiceTemplateExplicitlySet;
|
||||
@@ -89,6 +87,7 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
|
||||
public AbstractWebServiceOutboundGateway(DestinationProvider destinationProvider,
|
||||
WebServiceMessageFactory messageFactory) {
|
||||
|
||||
Assert.notNull(destinationProvider, "DestinationProvider must not be null");
|
||||
this.webServiceTemplate = new WebServiceTemplate(messageFactory);
|
||||
this.destinationProvider = destinationProvider;
|
||||
@@ -99,6 +98,7 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
}
|
||||
|
||||
public void setHeaderMapper(SoapHeaderMapper headerMapper) {
|
||||
Assert.notNull(headerMapper, "'headerMapper' must not be null");
|
||||
this.headerMapper = headerMapper;
|
||||
}
|
||||
|
||||
@@ -120,13 +120,29 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
* @param encodeUri true if the URI should be encoded.
|
||||
* @see org.springframework.web.util.UriComponentsBuilder
|
||||
* @since 4.1
|
||||
* @deprecated since 5.3 in favor of {@link #setEncodingMode}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setEncodeUri(boolean encodeUri) {
|
||||
this.encodeUri = encodeUri;
|
||||
setEncodingMode(
|
||||
encodeUri
|
||||
? DefaultUriBuilderFactory.EncodingMode.TEMPLATE_AND_VALUES
|
||||
: DefaultUriBuilderFactory.EncodingMode.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the encoding mode to use.
|
||||
* By default this is set to {@link DefaultUriBuilderFactory.EncodingMode#TEMPLATE_AND_VALUES}.
|
||||
* @param encodingMode the mode to use for uri encoding
|
||||
* @since 5.3
|
||||
*/
|
||||
public void setEncodingMode(DefaultUriBuilderFactory.EncodingMode encodingMode) {
|
||||
Assert.notNull(encodingMode, "'encodingMode' must not be null");
|
||||
this.uriFactory.setEncodingMode(encodingMode);
|
||||
}
|
||||
|
||||
public void setReplyChannel(MessageChannel replyChannel) {
|
||||
this.setOutputChannel(replyChannel);
|
||||
setOutputChannel(replyChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,40 +216,33 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
|
||||
@Override
|
||||
public final Object handleRequestMessage(Message<?> requestMessage) {
|
||||
URI uriWithVariables = null;
|
||||
try {
|
||||
uriWithVariables = this.prepareUri(requestMessage);
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
URI uriWithVariables = prepareUri(requestMessage);
|
||||
if (uriWithVariables == null) {
|
||||
throw new MessageDeliveryException(requestMessage, "Failed to determine URI for " +
|
||||
"Web Service request in outbound gateway: " + this.getComponentName());
|
||||
}
|
||||
Object responsePayload = this.doHandle(uriWithVariables.toString(), requestMessage, this.requestCallback);
|
||||
if (responsePayload != null) {
|
||||
boolean shouldIgnore = (this.ignoreEmptyResponses
|
||||
&& responsePayload instanceof String && !StringUtils.hasText((String) responsePayload));
|
||||
if (!shouldIgnore) {
|
||||
return responsePayload;
|
||||
}
|
||||
Object responsePayload = doHandle(uriWithVariables.toString(), requestMessage, this.requestCallback);
|
||||
if (responsePayload != null && !(this.ignoreEmptyResponses
|
||||
&& responsePayload instanceof String
|
||||
&& !StringUtils.hasText((String) responsePayload))) {
|
||||
|
||||
return responsePayload;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private URI prepareUri(Message<?> requestMessage) throws URISyntaxException {
|
||||
private URI prepareUri(Message<?> requestMessage) {
|
||||
if (this.destinationProvider != null) {
|
||||
return this.destinationProvider.getDestination();
|
||||
}
|
||||
|
||||
Map<String, Object> uriVariables = ExpressionEvalMap.from(this.uriVariableExpressions)
|
||||
.usingEvaluationContext(this.evaluationContext)
|
||||
.withRoot(requestMessage)
|
||||
.build();
|
||||
Map<String, Object> uriVariables =
|
||||
ExpressionEvalMap.from(this.uriVariableExpressions)
|
||||
.usingEvaluationContext(this.evaluationContext)
|
||||
.withRoot(requestMessage)
|
||||
.build();
|
||||
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(this.uri).buildAndExpand(uriVariables);
|
||||
return this.encodeUri ? uriComponents.toUri() : new URI(uriComponents.toUriString());
|
||||
return this.uriFactory.expand(this.uri, uriVariables);
|
||||
}
|
||||
|
||||
|
||||
@@ -282,7 +291,7 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
if (resultObject != null && message instanceof SoapMessage) {
|
||||
Map<String, Object> mappedMessageHeaders =
|
||||
AbstractWebServiceOutboundGateway.this.headerMapper.toHeadersFromReply((SoapMessage) message);
|
||||
return AbstractWebServiceOutboundGateway.this.getMessageBuilderFactory()
|
||||
return getMessageBuilderFactory()
|
||||
.withPayload(resultObject)
|
||||
.copyHeaders(mappedMessageHeaders)
|
||||
.build();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -52,7 +52,7 @@ public class WebServiceOutboundGatewayParser extends AbstractOutboundGatewayPars
|
||||
|
||||
@Override
|
||||
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.getGatewayClassName(element));
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(getGatewayClassName(element));
|
||||
String uri = element.getAttribute("uri");
|
||||
String destinationProvider = element.getAttribute("destination-provider");
|
||||
List<Element> uriVariableElements = DomUtils.getChildElementsByTagName(element, "uri-variable");
|
||||
@@ -70,7 +70,7 @@ public class WebServiceOutboundGatewayParser extends AbstractOutboundGatewayPars
|
||||
else {
|
||||
builder.addConstructorArgValue(uri);
|
||||
if (!CollectionUtils.isEmpty(uriVariableElements)) {
|
||||
ManagedMap<String, Object> uriVariableExpressions = new ManagedMap<String, Object>();
|
||||
ManagedMap<String, Object> uriVariableExpressions = new ManagedMap<>();
|
||||
for (Element uriVariableElement : uriVariableElements) {
|
||||
String name = uriVariableElement.getAttribute("name");
|
||||
String expression = uriVariableElement.getAttribute("expression");
|
||||
@@ -87,9 +87,11 @@ public class WebServiceOutboundGatewayParser extends AbstractOutboundGatewayPars
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "requires-reply");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-empty-responses");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "encode-uri");
|
||||
this.postProcessGateway(builder, element, parserContext);
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "encoding-mode");
|
||||
postProcessGateway(builder, element, parserContext);
|
||||
|
||||
IntegrationNamespaceUtils.configureHeaderMapper(element, builder, parserContext, DefaultSoapHeaderMapper.class, null);
|
||||
IntegrationNamespaceUtils.configureHeaderMapper(element, builder, parserContext,
|
||||
DefaultSoapHeaderMapper.class, null);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.integration.dsl.MessageHandlerSpec;
|
||||
import org.springframework.integration.util.JavaUtils;
|
||||
import org.springframework.integration.ws.AbstractWebServiceOutboundGateway;
|
||||
import org.springframework.integration.ws.SoapHeaderMapper;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.client.core.FaultMessageResolver;
|
||||
import org.springframework.ws.client.core.WebServiceMessageCallback;
|
||||
@@ -39,6 +40,8 @@ import org.springframework.ws.transport.WebServiceMessageSender;
|
||||
* @param <E> the target {@link AbstractWebServiceOutboundGateway} implementation type.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 5.3
|
||||
*
|
||||
*/
|
||||
@@ -58,7 +61,7 @@ public abstract class BaseWsOutboundGatewaySpec<
|
||||
|
||||
private SoapHeaderMapper headerMapper;
|
||||
|
||||
private boolean encodeUri = true;
|
||||
private DefaultUriBuilderFactory.EncodingMode encodingMode;
|
||||
|
||||
private boolean ignoreEmptyResponses = true;
|
||||
|
||||
@@ -114,14 +117,12 @@ public abstract class BaseWsOutboundGatewaySpec<
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the URI should be encoded after any <code>uriVariables</code>
|
||||
* are expanded and before sending the request. The default value is <code>true</code>.
|
||||
* @param encodeUri true if the URI should be encoded.
|
||||
* @return the spec.
|
||||
* @see org.springframework.web.util.UriComponentsBuilder
|
||||
* Specify a {@link DefaultUriBuilderFactory.EncodingMode} for uri construction.
|
||||
* @param encodingMode to use for uri construction.
|
||||
* @return the spec
|
||||
*/
|
||||
public S encodeUri(boolean encodeUri) {
|
||||
this.encodeUri = encodeUri;
|
||||
public S encodingMode(DefaultUriBuilderFactory.EncodingMode encodingMode) {
|
||||
this.encodingMode = encodingMode;
|
||||
return _this();
|
||||
}
|
||||
|
||||
@@ -158,7 +159,7 @@ public abstract class BaseWsOutboundGatewaySpec<
|
||||
gateway.setUriVariableExpressions(this.uriVariableExpressions);
|
||||
JavaUtils.INSTANCE
|
||||
.acceptIfNotNull(this.headerMapper, gateway::setHeaderMapper);
|
||||
gateway.setEncodeUri(this.encodeUri);
|
||||
gateway.setEncodingMode(this.encodingMode);
|
||||
gateway.setIgnoreEmptyResponses(this.ignoreEmptyResponses);
|
||||
gateway.setRequestCallback(this.requestCallback);
|
||||
return gateway;
|
||||
|
||||
@@ -127,15 +127,26 @@
|
||||
<xsd:attribute name="encode-uri" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
When set to "false", the URI won't be encoded before the request is sent. This may be useful
|
||||
[DEPRECATED] When set to "false", the URI won't be encoded before the request is sent. This may be useful
|
||||
in some scenarios as it allows user control over the encoding, if needed. Default is "true".
|
||||
This attribute is ignored, if 'destination-provider' is specified.
|
||||
Deprecated since 5.3 in favor of 'encoding-mode'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="encoding-mode" default="TEMPLATE_AND_VALUES">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Set the encoding mode during URI building.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="encodingModeEnumeration xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="destination-provider" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
@@ -531,4 +542,13 @@ this list can also be simple patterns to be matched against the header names (e.
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="encodingModeEnumeration">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="TEMPLATE_AND_VALUES"/>
|
||||
<xsd:enumeration value="VALUES_ONLY"/>
|
||||
<xsd:enumeration value="URI_COMPONENT"/>
|
||||
<xsd:enumeration value="NONE"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<!--Email Transport-->
|
||||
<ws:outbound-gateway request-channel="inputEmail"
|
||||
uri="mailto:{to}?subject={subject}"
|
||||
encoding-mode="VALUES_ONLY"
|
||||
interceptor="emailInterceptor"
|
||||
message-sender="emailMessageSender">
|
||||
<ws:uri-variable name="to" expression="headers.to"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -37,8 +37,7 @@ import javax.jms.Session;
|
||||
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@@ -52,8 +51,7 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.ws.client.WebServiceClientException;
|
||||
import org.springframework.ws.client.WebServiceIOException;
|
||||
import org.springframework.ws.client.core.WebServiceMessageCallback;
|
||||
@@ -74,8 +72,7 @@ import org.springframework.ws.transport.mail.MailSenderConnection;
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@SpringJUnitConfig
|
||||
public class UriVariableTests {
|
||||
|
||||
@Autowired
|
||||
@@ -134,7 +131,7 @@ public class UriVariableTests {
|
||||
assertThatExceptionOfType(MessagingException.class)
|
||||
.isThrownBy(() -> this.inputHttp.send(message))
|
||||
.withCauseInstanceOf(WebServiceIOException.class); // offline
|
||||
assertThat(uri.get()).isEqualTo("http://localhost/spring-integration?param=test1%20&%20test2");
|
||||
assertThat(uri.get()).isEqualTo("http://localhost/spring-integration?param=test1%20%26%20test2");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
<ws:outbound-gateway id="gatewayWithJmsUri"
|
||||
request-channel="inputChannel"
|
||||
encode-uri="false"
|
||||
encoding-mode="NONE"
|
||||
uri="jms:wsQueue" />
|
||||
|
||||
<bean id="sourceExtractor" class="org.springframework.integration.ws.config.StubSourceExtractor"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.integration.ws.config;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -24,8 +25,7 @@ import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
@@ -49,7 +49,8 @@ import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.client.core.FaultMessageResolver;
|
||||
import org.springframework.ws.client.core.SourceExtractor;
|
||||
@@ -66,7 +67,7 @@ import org.springframework.ws.transport.WebServiceMessageSender;
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringJUnitConfig
|
||||
public class WebServiceOutboundGatewayParserTests {
|
||||
|
||||
private static volatile int adviceCalled;
|
||||
@@ -173,7 +174,8 @@ public class WebServiceOutboundGatewayParserTests {
|
||||
|
||||
@Test
|
||||
public void simpleGatewayWithCustomSourceExtractorAndMessageFactory() {
|
||||
AbstractEndpoint endpoint = context.getBean("gatewayWithCustomSourceExtractorAndMessageFactory", AbstractEndpoint.class);
|
||||
AbstractEndpoint endpoint = context.getBean("gatewayWithCustomSourceExtractorAndMessageFactory",
|
||||
AbstractEndpoint.class);
|
||||
SourceExtractor<?> sourceExtractor = (SourceExtractor<?>) context.getBean("sourceExtractor");
|
||||
assertThat(endpoint.getClass()).isEqualTo(EventDrivenConsumer.class);
|
||||
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
|
||||
@@ -187,7 +189,8 @@ public class WebServiceOutboundGatewayParserTests {
|
||||
|
||||
@Test
|
||||
public void simpleGatewayWithCustomFaultMessageResolver() {
|
||||
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomFaultMessageResolver", AbstractEndpoint.class);
|
||||
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomFaultMessageResolver",
|
||||
AbstractEndpoint.class);
|
||||
assertThat(endpoint.getClass()).isEqualTo(EventDrivenConsumer.class);
|
||||
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
|
||||
assertThat(gateway.getClass()).isEqualTo(SimpleWebServiceOutboundGateway.class);
|
||||
@@ -387,7 +390,7 @@ public class WebServiceOutboundGatewayParserTests {
|
||||
AbstractEndpoint endpoint = this.context.getBean("gatewayWithAdvice", AbstractEndpoint.class);
|
||||
assertThat(endpoint.getClass()).isEqualTo(EventDrivenConsumer.class);
|
||||
MessageHandler handler = TestUtils.getPropertyValue(endpoint, "handler", MessageHandler.class);
|
||||
handler.handleMessage(new GenericMessage<String>("foo"));
|
||||
handler.handleMessage(new GenericMessage<>("foo"));
|
||||
assertThat(adviceCalled).isEqualTo(1);
|
||||
}
|
||||
|
||||
@@ -395,18 +398,20 @@ public class WebServiceOutboundGatewayParserTests {
|
||||
public void testInt2718AdvisedInsideAChain() {
|
||||
adviceCalled = 0;
|
||||
MessageChannel channel = context.getBean("gatewayWithAdviceInsideAChain", MessageChannel.class);
|
||||
channel.send(new GenericMessage<String>("foo"));
|
||||
channel.send(new GenericMessage<>("foo"));
|
||||
assertThat(adviceCalled).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void jmsUri() {
|
||||
AbstractEndpoint endpoint = this.context.getBean("gatewayWithJmsUri", AbstractEndpoint.class);
|
||||
assertThat(endpoint.getClass()).isEqualTo(EventDrivenConsumer.class);
|
||||
MessageHandler handler = TestUtils.getPropertyValue(endpoint, "handler", MessageHandler.class);
|
||||
assertThat(TestUtils.getPropertyValue(handler, "destinationProvider")).isNull();
|
||||
assertThat(TestUtils.getPropertyValue(handler, "encodeUri", Boolean.class)).isFalse();
|
||||
assertThat(
|
||||
TestUtils.getPropertyValue(handler, "uriFactory.encodingMode",
|
||||
DefaultUriBuilderFactory.EncodingMode.class))
|
||||
.isEqualTo(DefaultUriBuilderFactory.EncodingMode.NONE);
|
||||
|
||||
WebServiceTemplate webServiceTemplate = TestUtils.getPropertyValue(handler, "webServiceTemplate",
|
||||
WebServiceTemplate.class);
|
||||
@@ -418,23 +423,27 @@ public class WebServiceOutboundGatewayParserTests {
|
||||
|
||||
new DirectFieldAccessor(handler).setPropertyValue("webServiceTemplate", webServiceTemplate);
|
||||
|
||||
handler.handleMessage(new GenericMessage<String>("foo"));
|
||||
handler.handleMessage(new GenericMessage<>("foo"));
|
||||
|
||||
verify(webServiceTemplate).sendAndReceive(eq("jms:wsQueue"),
|
||||
any(WebServiceMessageCallback.class),
|
||||
ArgumentMatchers.<WebServiceMessageExtractor<Object>>any());
|
||||
}
|
||||
|
||||
@Test(expected = BeanDefinitionParsingException.class)
|
||||
@Test
|
||||
public void invalidGatewayWithBothUriAndDestinationProvider() {
|
||||
new ClassPathXmlApplicationContext("invalidGatewayWithBothUriAndDestinationProvider.xml", this.getClass())
|
||||
.close();
|
||||
assertThatExceptionOfType(BeanDefinitionParsingException.class)
|
||||
.isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext("invalidGatewayWithBothUriAndDestinationProvider.xml",
|
||||
getClass()));
|
||||
}
|
||||
|
||||
@Test(expected = BeanDefinitionParsingException.class)
|
||||
@Test
|
||||
public void invalidGatewayWithNeitherUriNorDestinationProvider() {
|
||||
new ClassPathXmlApplicationContext("invalidGatewayWithNeitherUriNorDestinationProvider.xml", this.getClass())
|
||||
.close();
|
||||
assertThatExceptionOfType(BeanDefinitionParsingException.class)
|
||||
.isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext("invalidGatewayWithNeitherUriNorDestinationProvider.xml",
|
||||
getClass()));
|
||||
}
|
||||
|
||||
public static class FooAdvice extends AbstractRequestHandlerAdvice {
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.springframework.integration.ws.SimpleWebServiceOutboundGateway;
|
||||
import org.springframework.integration.ws.SoapHeaderMapper;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.client.core.FaultMessageResolver;
|
||||
import org.springframework.ws.client.core.SourceExtractor;
|
||||
@@ -45,6 +46,8 @@ import org.springframework.ws.transport.WebServiceMessageSender;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 5.3
|
||||
*
|
||||
*/
|
||||
@@ -93,7 +96,7 @@ public class WsDslTests {
|
||||
.marshaller(marshaller)
|
||||
.unmarshaller(unmarshaller)
|
||||
.messageFactory(messageFactory)
|
||||
.encodeUri(true)
|
||||
.encodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY)
|
||||
.faultMessageResolver(faultMessageResolver)
|
||||
.headerMapper(headerMapper)
|
||||
.ignoreEmptyResponses(true)
|
||||
@@ -111,7 +114,7 @@ public class WsDslTests {
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.interceptors", ClientInterceptor[].class)[0])
|
||||
.isSameAs(interceptor);
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.messageSenders",
|
||||
WebServiceMessageSender[].class)[0])
|
||||
WebServiceMessageSender[].class)[0])
|
||||
.isSameAs(messageSender);
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "requestCallback")).isSameAs(requestCallback);
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "uriVariableExpressions")).isEqualTo(uriVariableExpressions);
|
||||
@@ -134,7 +137,7 @@ public class WsDslTests {
|
||||
.destinationProvider(destinationProvider)
|
||||
.sourceExtractor(sourceExtractor)
|
||||
.messageFactory(messageFactory)
|
||||
.encodeUri(true)
|
||||
.encodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY)
|
||||
.faultMessageResolver(faultMessageResolver)
|
||||
.headerMapper(headerMapper)
|
||||
.ignoreEmptyResponses(true)
|
||||
@@ -151,7 +154,7 @@ public class WsDslTests {
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.interceptors", ClientInterceptor[].class)[0])
|
||||
.isSameAs(interceptor);
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.messageSenders",
|
||||
WebServiceMessageSender[].class)[0])
|
||||
WebServiceMessageSender[].class)[0])
|
||||
.isSameAs(messageSender);
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "requestCallback")).isSameAs(requestCallback);
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "uriVariableExpressions")).isEqualTo(uriVariableExpressions);
|
||||
@@ -169,7 +172,7 @@ public class WsDslTests {
|
||||
MarshallingWebServiceOutboundGateway gateway =
|
||||
Ws.marshallingOutboundGateway(template)
|
||||
.uri(uri)
|
||||
.encodeUri(true)
|
||||
.encodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY)
|
||||
.headerMapper(headerMapper)
|
||||
.ignoreEmptyResponses(true)
|
||||
.requestCallback(requestCallback)
|
||||
@@ -194,7 +197,7 @@ public class WsDslTests {
|
||||
Ws.simpleOutboundGateway(template)
|
||||
.uri(uri)
|
||||
.sourceExtractor(sourceExtractor)
|
||||
.encodeUri(true)
|
||||
.encodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY)
|
||||
.headerMapper(headerMapper)
|
||||
.ignoreEmptyResponses(true)
|
||||
.requestCallback(requestCallback)
|
||||
@@ -205,6 +208,10 @@ public class WsDslTests {
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "requestCallback")).isSameAs(requestCallback);
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "uriVariableExpressions")).isEqualTo(uriVariableExpressions);
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "extractPayload", Boolean.class)).isFalse();
|
||||
assertThat(
|
||||
TestUtils.getPropertyValue(gateway, "uriFactory.encodingMode",
|
||||
DefaultUriBuilderFactory.EncodingMode.class))
|
||||
.isEqualTo(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
|
||||
}
|
||||
|
||||
interface Both extends Marshaller, Unmarshaller {
|
||||
|
||||
@@ -715,7 +715,7 @@ If you wish to partially encode some of the URL, use an `expression` within a `<
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<http:outbound-gateway url="https://somehost/%2f/fooApps?bar={param}" encode-uri="false">
|
||||
<http:outbound-gateway url="https://somehost/%2f/fooApps?bar={param}" encoding-mode="NONE">
|
||||
<http:uri-variable name="param"
|
||||
expression="T(org.apache.commons.httpclient.util.URIUtil)
|
||||
.encodeWithinQuery('Hello World!')"/>
|
||||
@@ -724,7 +724,7 @@ If you wish to partially encode some of the URL, use an `expression` within a `<
|
||||
====
|
||||
|
||||
With Java DSL this option can be controlled by the `BaseHttpMessageHandlerSpec.encodingMode()` option.
|
||||
Same configuration applies for similar outbound components in the <<./webflux.adoc/[webflux,WebFlux module>>.
|
||||
The same configuration applies for similar outbound components in the <<./webflux.adoc#webflux,WebFlux module>> and <<./ws.adoc#ws,Web Services module>>.
|
||||
For much sophisticated scenarios it is recommended to configure an `UriTemplateHandler` on the externally provided `RestTemplate`; or in case of WebFlux - `WebClient` with it `UriBuilderFactory`.
|
||||
|
||||
[[http-java-config]]
|
||||
|
||||
@@ -68,9 +68,11 @@ See <<./amqp.adoc#amqp-inbound-channel-adapter,AMQP Inbound Channel Adapter>>
|
||||
The `encodeUri` property on the `AbstractHttpRequestExecutingMessageHandler` has been deprecated in favor of newly introduced `encodingMode`.
|
||||
See `DefaultUriBuilderFactory.EncodingMode` JavaDocs and <<./http.adoc#http-uri-encoding,Controlling URI Encoding>> for more information.
|
||||
This also affects `WebFluxRequestExecutingMessageHandler`, respective Java DSL and XML configuration.
|
||||
The same option is added into an `AbstractWebServiceOutboundGateway`.
|
||||
|
||||
[[x5.3-ws]]
|
||||
=== Web Services Changes
|
||||
|
||||
Java DSL support has been added for Web Service components.
|
||||
The `encodeUri` property on the `AbstractWebServiceOutboundGateway` has been deprecated in favor of newly introduced `encodingMode` - similar to HTTP changes above.
|
||||
See <<./ws.adoc#ws,Web Services Support>> for more information.
|
||||
|
||||
@@ -233,7 +233,7 @@ Examples:
|
||||
.handle(Ws.simpleOutboundGateway(template)
|
||||
.uri(uri)
|
||||
.sourceExtractor(sourceExtractor)
|
||||
.encodeUri(true)
|
||||
.encodingMode(DefaultUriBuilderFactory.EncodingMode.NONE)
|
||||
.headerMapper(headerMapper)
|
||||
.ignoreEmptyResponses(true)
|
||||
.requestCallback(requestCallback)
|
||||
@@ -251,7 +251,7 @@ Examples:
|
||||
.marshaller(marshaller)
|
||||
.unmarshaller(unmarshaller)
|
||||
.messageFactory(messageFactory)
|
||||
.encodeUri(true)
|
||||
.encodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY)
|
||||
.faultMessageResolver(faultMessageResolver)
|
||||
.headerMapper(headerMapper)
|
||||
.ignoreEmptyResponses(true)
|
||||
@@ -267,7 +267,7 @@ Examples:
|
||||
----
|
||||
.handle(Ws.marshallingOutboundGateway(template)
|
||||
.uri(uri)
|
||||
.encodeUri(true)
|
||||
.encodingMode(DefaultUriBuilderFactory.EncodingMode.URI_COMPONENT)
|
||||
.headerMapper(headerMapper)
|
||||
.ignoreEmptyResponses(true)
|
||||
.requestCallback(requestCallback)
|
||||
@@ -305,14 +305,14 @@ If you supply a `DestinationProvider`, variable substitution is not supported an
|
||||
|
||||
By default, the URL string is encoded (see https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/util/UriComponentsBuilder.html[`UriComponentsBuilder`]) to the URI object before sending the request.
|
||||
In some scenarios with a non-standard URI, it is undesirable to perform the encoding.
|
||||
Since version 4.1, the `<ws:outbound-gateway/>` element provides an `encode-uri` attribute.
|
||||
To disable encoding the URL, set this attribute `false` (it defaults to `true`).
|
||||
The `<ws:outbound-gateway/>` element provides an `encoding-mode` attribute.
|
||||
To disable encoding the URL, set this attribute to `NONE` (by default, it is `TEMPLATE_AND_VALUES`).
|
||||
If you wish to partially encode some of the URL, you can do so by using an `expression` within a `<uri-variable/>`, as the following example shows:
|
||||
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<ws:outbound-gateway url="https://somehost/%2f/fooApps?bar={param}" encode-uri="false">
|
||||
<ws:outbound-gateway url="https://somehost/%2f/fooApps?bar={param}" encoding-mode="NONE">
|
||||
<http:uri-variable name="param"
|
||||
expression="T(org.apache.commons.httpclient.util.URIUtil)
|
||||
.encodeWithinQuery('Hello World!')"/>
|
||||
@@ -320,7 +320,7 @@ If you wish to partially encode some of the URL, you can do so by using an `expr
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: If you set `DestinationProvider`, `encode-uri` is ignored.
|
||||
NOTE: If you set `DestinationProvider`, `encoding-mode` is ignored.
|
||||
|
||||
[[ws-message-headers]]
|
||||
=== WS Message Headers
|
||||
|
||||
Reference in New Issue
Block a user