SWS-297 (SWS-84)
This commit is contained in:
@@ -24,13 +24,13 @@ import org.springframework.ws.WebServiceException;
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class WsAddressingException extends WebServiceException {
|
||||
public class AddressingException extends WebServiceException {
|
||||
|
||||
public WsAddressingException(String msg) {
|
||||
public AddressingException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public WsAddressingException(String msg, Throwable ex) {
|
||||
public AddressingException(String msg, Throwable ex) {
|
||||
super(msg, ex);
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,9 @@ import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
|
||||
/**
|
||||
* Abstract base class for WS-Addressing <code>Action</code>-mapped {@link org.springframework.ws.server.EndpointMapping}
|
||||
* implementations. Provides infrastructure for mapping endpoints to actions.
|
||||
* <p/>
|
||||
* By default, this mapping creates a <code>Action</code> for reply messages based on the request message, plus the
|
||||
* extra {@link #setOutputActionSuffix(String) suffix}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.5.0
|
||||
@@ -36,11 +39,26 @@ import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
|
||||
public abstract class AbstractActionEndpointMapping extends AbstractAddressingEndpointMapping
|
||||
implements ApplicationContextAware {
|
||||
|
||||
/** The defaults suffix to add to request <code>Action</code> for reply messages. */
|
||||
public static final String DEFAULT_OUTPUT_ACTION_SUFFIX = "Response";
|
||||
|
||||
// keys are action URIs, values are endpoints
|
||||
private final Map endpointMap = new HashMap();
|
||||
|
||||
private String outputActionSuffix = DEFAULT_OUTPUT_ACTION_SUFFIX;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* Sets the suffix to add to request <code>Action</code>s for reply messages.
|
||||
*
|
||||
* @see #DEFAULT_OUTPUT_ACTION_SUFFIX
|
||||
*/
|
||||
public void setOutputActionSuffix(String outputActionSuffix) {
|
||||
Assert.hasText(outputActionSuffix, "'replyActionSuffix' must not be empty");
|
||||
this.outputActionSuffix = outputActionSuffix;
|
||||
}
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
@@ -116,5 +134,13 @@ public abstract class AbstractActionEndpointMapping extends AbstractAddressingEn
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected URI getResponseAction(Object endpoint, MessageAddressingProperties requestMap) {
|
||||
URI requestAction = requestMap.getAction();
|
||||
if (requestAction != null) {
|
||||
return URI.create(requestAction.toString() + outputActionSuffix);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.addressing.server;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.core.JdkVersion;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
|
||||
/**
|
||||
* Abstract base class for WS-Addressing <code>Action</code>-mapped {@link org.springframework.ws.server.EndpointMapping}
|
||||
* implementations that map to {@link MethodEndpoint}s. Provides infrastructure for mapping endpoint methods to
|
||||
* actions.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public abstract class AbstractActionMethodEndpointMapping extends AbstractActionEndpointMapping {
|
||||
|
||||
/**
|
||||
* Helper method that registers the methods of the given bean. This method iterates over the methods of the bean,
|
||||
* and calls {@link #getActionForMethod(java.lang.reflect.Method)} for each. If this returns a URI, the method is
|
||||
* registered using {@link #registerEndpoint(java.net.URI, Object)}.
|
||||
*
|
||||
* @see #getActionForMethod (java.lang.reflect.Method)
|
||||
*/
|
||||
protected void registerMethods(Object endpoint) {
|
||||
Assert.notNull(endpoint, "'endpoint' must not be null");
|
||||
Method[] methods = AopUtils.getTargetClass(endpoint).getMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (JdkVersion.isAtLeastJava15() && methods[i].isSynthetic() ||
|
||||
methods[i].getDeclaringClass().equals(Object.class)) {
|
||||
continue;
|
||||
}
|
||||
URI action = getActionForMethod(methods[i]);
|
||||
if (action != null) {
|
||||
registerEndpoint(action, new MethodEndpoint(endpoint, methods[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the action value for the specified method. */
|
||||
protected abstract URI getActionForMethod(Method method);
|
||||
|
||||
/**
|
||||
* Return the class or interface to use for method reflection.
|
||||
* <p/>
|
||||
* Default implementation delegates to {@link AopUtils#getTargetClass(Object)}.
|
||||
*
|
||||
* @param endpoint the bean instance (might be an AOP proxy)
|
||||
* @return the bean class to expose
|
||||
*/
|
||||
protected Class getEndpointClass(Object endpoint) {
|
||||
return AopUtils.getTargetClass(endpoint);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -184,7 +184,7 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec
|
||||
if (endpoint == null) {
|
||||
return null;
|
||||
}
|
||||
return getEndpointInvocationChain(endpoint, versions[i]);
|
||||
return getEndpointInvocationChain(endpoint, versions[i], requestMap);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -194,14 +194,15 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec
|
||||
* Creates a {@link SoapEndpointInvocationChain} based on the given endpoint and {@link
|
||||
* org.springframework.ws.soap.addressing.version.AddressingVersion}.
|
||||
*/
|
||||
private EndpointInvocationChain getEndpointInvocationChain(Object endpoint, AddressingVersion version) {
|
||||
URI responseAction = getResponseAction(endpoint);
|
||||
URI faultAction = getFaultAction(endpoint);
|
||||
private EndpointInvocationChain getEndpointInvocationChain(Object endpoint,
|
||||
AddressingVersion version,
|
||||
MessageAddressingProperties requestMap) {
|
||||
URI responseAction = getResponseAction(endpoint, requestMap);
|
||||
EndpointInterceptor[] interceptors =
|
||||
new EndpointInterceptor[preInterceptors.length + postInterceptors.length + 1];
|
||||
System.arraycopy(preInterceptors, 0, interceptors, 0, preInterceptors.length);
|
||||
AddressingEndpointInterceptor interceptor = new AddressingEndpointInterceptor(version, messageIdStrategy,
|
||||
messageSenders, responseAction, faultAction);
|
||||
AddressingEndpointInterceptor interceptor =
|
||||
new AddressingEndpointInterceptor(version, messageIdStrategy, messageSenders, responseAction, null);
|
||||
interceptors[preInterceptors.length] = interceptor;
|
||||
System.arraycopy(postInterceptors, 0, interceptors, preInterceptors.length + 1, postInterceptors.length);
|
||||
return new SoapEndpointInvocationChain(endpoint, interceptors, actorsOrRoles, isUltimateReceiver);
|
||||
@@ -229,12 +230,6 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec
|
||||
*/
|
||||
protected abstract Object getEndpointInternal(MessageAddressingProperties map);
|
||||
|
||||
protected URI getResponseAction(Object endpoint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected URI getFaultAction(Object endpoint) {
|
||||
return null;
|
||||
}
|
||||
protected abstract URI getResponseAction(Object endpoint, MessageAddressingProperties requestMap);
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,10 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
@@ -38,7 +41,7 @@ import org.springframework.ws.soap.SoapFault;
|
||||
import org.springframework.ws.soap.SoapHeader;
|
||||
import org.springframework.ws.soap.SoapHeaderElement;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.addressing.WsAddressingException;
|
||||
import org.springframework.ws.soap.addressing.AddressingException;
|
||||
import org.springframework.ws.soap.addressing.core.EndpointReference;
|
||||
import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
|
||||
import org.springframework.ws.soap.soap11.Soap11Body;
|
||||
@@ -58,6 +61,8 @@ import org.springframework.xml.xpath.XPathExpressionFactory;
|
||||
*/
|
||||
public abstract class AbstractAddressingVersion extends TransformerObjectSupport implements AddressingVersion {
|
||||
|
||||
private static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
|
||||
private final XPathExpression toExpression;
|
||||
|
||||
private final XPathExpression actionExpression;
|
||||
@@ -120,7 +125,7 @@ public abstract class AbstractAddressingVersion extends TransformerObjectSupport
|
||||
URI to = getUri(headerElement, toExpression);
|
||||
EndpointReference from = getEndpointReference(fromExpression.evaluateAsNode(headerElement));
|
||||
EndpointReference replyTo = getEndpointReference(replyToExpression.evaluateAsNode(headerElement));
|
||||
if (replyTo == null && getAnonymous() != null) {
|
||||
if (replyTo == null) {
|
||||
replyTo = getDefaultReplyTo(from);
|
||||
}
|
||||
EndpointReference faultTo = getEndpointReference(faultToExpression.evaluateAsNode(headerElement));
|
||||
@@ -160,7 +165,7 @@ public abstract class AbstractAddressingVersion extends TransformerObjectSupport
|
||||
return document.getDocumentElement();
|
||||
}
|
||||
catch (TransformerException ex) {
|
||||
throw new WsAddressingException("Could not transform SoapHeader to Document", ex);
|
||||
throw new AddressingException("Could not transform SoapHeader to Document", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,38 +185,92 @@ public abstract class AbstractAddressingVersion extends TransformerObjectSupport
|
||||
return new EndpointReference(address, referenceProperties, referenceParameters);
|
||||
}
|
||||
|
||||
public void addAddressingHeaders(SoapMessage message, MessageAddressingProperties map) {
|
||||
SoapHeader header = message.getSoapHeader();
|
||||
// To
|
||||
if (map.getTo() != null) {
|
||||
SoapHeaderElement to = header.addHeaderElement(getToName());
|
||||
to.setText(map.getTo().toString());
|
||||
to.setMustUnderstand(true);
|
||||
}
|
||||
// From
|
||||
if (map.getFrom() != null) {
|
||||
SoapHeaderElement from = header.addHeaderElement(getFromName());
|
||||
addEndpointReference(from, map.getFrom());
|
||||
}
|
||||
//ReplyTo
|
||||
if (map.getReplyTo() != null) {
|
||||
SoapHeaderElement replyTo = header.addHeaderElement(getReplyToName());
|
||||
addEndpointReference(replyTo, map.getReplyTo());
|
||||
}
|
||||
// FaultTo
|
||||
if (map.getFaultTo() != null) {
|
||||
SoapHeaderElement faultTo = header.addHeaderElement(getFaultToName());
|
||||
addEndpointReference(faultTo, map.getFaultTo());
|
||||
}
|
||||
// Action
|
||||
SoapHeaderElement action = header.addHeaderElement(getActionName());
|
||||
action.setText(map.getAction().toString());
|
||||
// MessageID
|
||||
if (map.getMessageId() != null) {
|
||||
SoapHeaderElement messageId = header.addHeaderElement(getMessageIdName());
|
||||
messageId.setText(map.getMessageId().toString());
|
||||
}
|
||||
// RelatesTo
|
||||
if (map.getRelatesTo() != null) {
|
||||
SoapHeaderElement relatesTo = header.addHeaderElement(getRelatesToName());
|
||||
relatesTo.setText(map.getRelatesTo().toString());
|
||||
}
|
||||
addReferenceNodes(header.getResult(), map.getReferenceParameters());
|
||||
addReferenceNodes(header.getResult(), map.getReferenceProperties());
|
||||
}
|
||||
|
||||
public final boolean understands(SoapHeaderElement headerElement) {
|
||||
return getNamespaceUri().equals(headerElement.getName().getNamespaceURI());
|
||||
}
|
||||
|
||||
public final void addAddressingHeaders(SoapMessage message, MessageAddressingProperties map) {
|
||||
SoapHeader header = message.getSoapHeader();
|
||||
SoapHeaderElement messageId = header.addHeaderElement(getMessageIdName());
|
||||
messageId.setText(map.getMessageId().toString());
|
||||
SoapHeaderElement relatesTo = header.addHeaderElement(getRelatesToName());
|
||||
relatesTo.setText(map.getRelatesTo().toString());
|
||||
SoapHeaderElement to = header.addHeaderElement(getToName());
|
||||
to.setText(map.getTo().toString());
|
||||
to.setMustUnderstand(true);
|
||||
if (map.getAction() != null) {
|
||||
SoapHeaderElement action = header.addHeaderElement(getActionName());
|
||||
action.setText(map.getAction().toString());
|
||||
/** Adds ReplyTo, FaultTo, or From EPR to the given header Element. */
|
||||
protected void addEndpointReference(SoapHeaderElement headerElement, EndpointReference epr) {
|
||||
if (epr == null || epr.getAddress() == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Transformer transformer = createTransformer();
|
||||
for (Iterator iterator = map.getReferenceParameters().iterator(); iterator.hasNext();) {
|
||||
Node node = (Node) iterator.next();
|
||||
DOMSource source = new DOMSource(node);
|
||||
transformer.transform(source, header.getResult());
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
Document document = documentBuilder.newDocument();
|
||||
Element address = document.createElementNS(getNamespaceUri(), QNameUtils.toQualifiedName(getAddressName()));
|
||||
address.setTextContent(epr.getAddress().toString());
|
||||
transform(new DOMSource(address), headerElement.getResult());
|
||||
if (getReferenceParametersName() != null && !epr.getReferenceParameters().isEmpty()) {
|
||||
Element referenceParams = document.createElementNS(getNamespaceUri(),
|
||||
QNameUtils.toQualifiedName(getReferenceParametersName()));
|
||||
addReferenceNodes(new DOMResult(referenceParams), epr.getReferenceParameters());
|
||||
transform(new DOMSource(referenceParams), headerElement.getResult());
|
||||
}
|
||||
for (Iterator iterator = map.getReferenceProperties().iterator(); iterator.hasNext();) {
|
||||
if (getReferencePropertiesName() != null && !epr.getReferenceProperties().isEmpty()) {
|
||||
Element referenceProps = document.createElementNS(getNamespaceUri(),
|
||||
QNameUtils.toQualifiedName(getReferencePropertiesName()));
|
||||
addReferenceNodes(new DOMResult(referenceProps), epr.getReferenceProperties());
|
||||
transform(new DOMSource(referenceProps), headerElement.getResult());
|
||||
}
|
||||
}
|
||||
catch (ParserConfigurationException ex) {
|
||||
throw new AddressingException("Could not add Endpoint Reference [" + epr + "] to header element", ex);
|
||||
}
|
||||
catch (TransformerException ex) {
|
||||
throw new AddressingException("Could not add reference properties/parameters to message", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addReferenceNodes(Result result, List nodes) {
|
||||
try {
|
||||
for (Iterator iterator = nodes.iterator(); iterator.hasNext();) {
|
||||
Node node = (Node) iterator.next();
|
||||
DOMSource source = new DOMSource(node);
|
||||
transformer.transform(source, header.getResult());
|
||||
transform(source, result);
|
||||
}
|
||||
}
|
||||
catch (TransformerException ex) {
|
||||
throw new WsAddressingException("Could not add reference properties/parameters to message", ex);
|
||||
throw new AddressingException("Could not add reference properties/parameters to message", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +359,11 @@ public abstract class AbstractAddressingVersion extends TransformerObjectSupport
|
||||
return QNameUtils.createQName(getNamespaceUri(), "RelatesTo", getNamespacePrefix());
|
||||
}
|
||||
|
||||
/** Returns the qualified name of the <code>RelatesTo</code> addressing header. */
|
||||
protected QName getRelationshipTypeName() {
|
||||
return new QName("RelationshipType");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the qualified name of the <code>ReferenceProperties</code> in the endpoint reference. Returns
|
||||
* <code>null</code> when reference properties are not supported by this version of the spec.
|
||||
|
||||
@@ -19,7 +19,10 @@ package org.springframework.ws.soap.addressing.version;
|
||||
import java.net.URI;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.addressing.core.EndpointReference;
|
||||
import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
|
||||
import org.springframework.xml.namespace.QNameUtils;
|
||||
|
||||
/**
|
||||
@@ -35,6 +38,11 @@ public class Addressing10 extends AbstractAddressingVersion {
|
||||
|
||||
private static final String NAMESPACE_URI = "http://www.w3.org/2005/08/addressing";
|
||||
|
||||
public void addAddressingHeaders(SoapMessage message, MessageAddressingProperties map) {
|
||||
Assert.notNull(map.getAction(), "'Action' is required");
|
||||
super.addAddressingHeaders(message, map);
|
||||
}
|
||||
|
||||
protected String getNamespaceUri() {
|
||||
return NAMESPACE_URI;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,10 @@ package org.springframework.ws.soap.addressing.version;
|
||||
import java.net.URI;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.addressing.core.EndpointReference;
|
||||
import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
|
||||
import org.springframework.xml.namespace.QNameUtils;
|
||||
|
||||
/**
|
||||
@@ -34,6 +37,12 @@ public class Addressing200408 extends AbstractAddressingVersion {
|
||||
|
||||
private static final String NAMESPACE_URI = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
|
||||
|
||||
public void addAddressingHeaders(SoapMessage message, MessageAddressingProperties map) {
|
||||
Assert.notNull(map.getAction(), "'Action' must not be null");
|
||||
Assert.notNull(map.getTo(), "'Action' must not be null");
|
||||
super.addAddressingHeaders(message, map);
|
||||
}
|
||||
|
||||
protected final URI getAnonymous() {
|
||||
return URI.create(NAMESPACE_URI + "/role/anonymous");
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@ public class SimpleActionEndpointMappingTest extends AbstractWsAddressingTestCas
|
||||
Map map = new HashMap();
|
||||
endpoint1 = new Endpoint1();
|
||||
Endpoint2 endpoint2 = new Endpoint2();
|
||||
map.put("http://fabrikam123.example/mail/Delete", endpoint1);
|
||||
map.put("http://fabrikam123.example/mail/Add", endpoint2);
|
||||
map.put("http://example.com/fabrikam/mail/Delete", endpoint1);
|
||||
map.put("http://example.com/fabrikam/mail/Add", endpoint2);
|
||||
mapping.setPreInterceptors(new EndpointInterceptor[]{new PayloadLoggingInterceptor()});
|
||||
mapping.setPostInterceptors(new EndpointInterceptor[]{new PayloadValidatingInterceptor()});
|
||||
mapping.setAddress(new URI("mailto:joe@fabrikam123.example"));
|
||||
mapping.setAddress(new URI("mailto:fabrikam@example.com"));
|
||||
mapping.setActionMap(map);
|
||||
mapping.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<wsa:ReplyTo>
|
||||
<wsa:Address>http://example.com/business/client1</wsa:Address>
|
||||
</wsa:ReplyTo>
|
||||
<wsa:To>mailto:fabrikam@example.com</wsa:To>
|
||||
<wsa:To S:mustUnderstand="true">mailto:fabrikam@example.com</wsa:To>
|
||||
<wsa:Action>http://example.com/fabrikam/mail/Delete</wsa:Action>
|
||||
</S:Header>
|
||||
<S:Body>
|
||||
<f:Delete xmlns:f="http://example.com/fabrikam">
|
||||
<maxCount>42</maxCount>
|
||||
<f:maxCount>42</f:maxCount>
|
||||
</f:Delete>
|
||||
</S:Body>
|
||||
</S:Envelope>
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:f123="http://www.fabrikam123.example/svc53">
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
|
||||
<S:Header>
|
||||
<wsa:MessageID>uuid:aaaabbbb-cccc-dddd-eeee-ffffffffffff</wsa:MessageID>
|
||||
<wsa:MessageID>http://example.com/someuniquestring</wsa:MessageID>
|
||||
<wsa:ReplyTo>
|
||||
<wsa:Address>http://example.com/business/client1</wsa:Address>
|
||||
</wsa:ReplyTo>
|
||||
<wsa:To S:mustUnderstand="true">mailto:joe@fabrikam123.example</wsa:To>
|
||||
<wsa:Action>http://fabrikam123.example/mail/Delete</wsa:Action>
|
||||
<wsa:To S:mustUnderstand="true">mailto:fabrikam@example.com</wsa:To>
|
||||
<wsa:Action>http://example.com/fabrikam/mail/Delete</wsa:Action>
|
||||
</S:Header>
|
||||
<S:Body>
|
||||
<f123:Delete>
|
||||
<maxCount>42</maxCount>
|
||||
</f123:Delete>
|
||||
<f:Delete xmlns:f="http://example.com/fabrikam">
|
||||
<f:maxCount>42</f:maxCount>
|
||||
</f:Delete>
|
||||
</S:Body>
|
||||
</S:Envelope>
|
||||
|
||||
Reference in New Issue
Block a user