Working on client-side stuff.

This commit is contained in:
Arjen Poutsma
2007-01-06 23:29:49 +00:00
parent 4e2c7db738
commit bc4581adc0
13 changed files with 244 additions and 90 deletions

View File

@@ -19,19 +19,25 @@ package org.springframework.ws.client;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.endpoint.TransformerObjectSupport;
import org.springframework.ws.transport.MessageSender;
import org.springframework.ws.transport.WebServiceMessageSender;
/**
* Base class for <code>WebServiceTemplate</code> and other WS-accessing helpers.
* Base class for <code>WebServiceTemplate</code> and other WS-accessing helpers. Defines common properties like the
* {@link org.springframework.ws.WebServiceMessageFactory} and {@link org.springframework.ws.transport.WebServiceMessageSender}.
* <p/>
* Not intended to be used directly. See {@link org.springframework.ws.client.WebServiceTemplate}.
*
* @author Arjen Poutsma
* @see org.springframework.ws.client.WebServiceTemplate
*/
public abstract class WebServiceAccessor extends TransformerObjectSupport implements InitializingBean {
private WebServiceMessageFactory messageFactory;
private MessageSender messageSender;
private WebServiceMessageSender messageSender;
/**
* Returns the message factory used for creating messages.
@@ -50,17 +56,27 @@ public abstract class WebServiceAccessor extends TransformerObjectSupport implem
/**
* Returns the message sender.
*/
public MessageSender getMessageSender() {
public WebServiceMessageSender getMessageSender() {
return messageSender;
}
/**
* Sets the message sender.
*/
public void setMessageSender(MessageSender messageSender) {
public void setMessageSender(WebServiceMessageSender messageSender) {
this.messageSender = messageSender;
}
/**
* Returns a <code>MessageContext</code> with an empty message, and the defined
* <code>WebServiceMessageFactory</code>.
*
* @return the created message context
*/
protected MessageContext createMessageContext() {
return new DefaultMessageContext(getMessageFactory());
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(getMessageFactory(), "messageFactory is required");
Assert.notNull(getMessageSender(), "messageSender is required");

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2007 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.client;
import org.springframework.ws.WebServiceException;
/**
* @author Arjen Poutsma
*/
public class WebServiceClientException extends WebServiceException {
public WebServiceClientException(String msg) {
super(msg);
}
public WebServiceClientException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006 the original author or authors.
* Copyright 2007 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.
@@ -16,6 +16,8 @@
package org.springframework.ws.client;
import java.io.IOException;
import org.springframework.ws.WebServiceMessage;
/**
@@ -23,5 +25,5 @@ import org.springframework.ws.WebServiceMessage;
*/
public interface WebServiceMessageCallback {
void doInWebServiceMessage(WebServiceMessage message) throws Exception;
void doInMessage(WebServiceMessage message) throws IOException;
}

View File

@@ -16,8 +16,12 @@
package org.springframework.ws.client;
import java.io.IOException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import org.springframework.ws.WebServiceMessage;
/**
* @author Arjen Poutsma
*/
@@ -27,19 +31,21 @@ public interface WebServiceOperations {
* Sends a web service message that contains the given payload. Returns the payload of the response message, if
* any.
*
* @param payload the payload of the message.
* @param requestPayload the payload of the request message
* @return the payload of the response message, or <code>null</code> if no response is given
*/
Source send(Source payload);
Source sendAndReceive(Source requestPayload) throws IOException;
/**
* Sends a web service message that contains the given payload, marshalled by the configured
* <code>Marshaller</code>. Returns the unmarshalled payload of the response message, if any.
*
* @param payload the object to marshal into a message payload
* @param requestPayload the object to marshal into the request message payload
* @return the unmarshalled payload of the response message, or <code>null</code> if no response is given
*/
Object marshalAndSend(Object payload);
Object marshalAndSend(Object requestPayload) throws IOException;
Object send(WebServiceMessageCallback callback, WebServiceMessageExtractor extractor);
WebServiceMessage sendAndReceive(WebServiceMessageCallback callback) throws IOException;
void sendAndReceive(Source requestPayload, Result result) throws IOException;
}

View File

@@ -17,14 +17,15 @@
package org.springframework.ws.client;
import java.io.IOException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceException;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
/**
* @author Arjen Poutsma
@@ -63,30 +64,61 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
this.unmarshaller = unmarshaller;
}
public Object marshalAndSend(final Object payload) {
public Object marshalAndSend(final Object requestPayload) throws IOException {
checkMarshallerAndUnmarshaller();
return send(new WebServiceMessageCallback() {
public void doInWebServiceMessage(WebServiceMessage message) throws IOException {
getMarshaller().marshal(payload, message.getPayloadResult());
WebServiceMessage response = sendAndReceive(new WebServiceMessageCallback() {
public void doInMessage(WebServiceMessage message) throws IOException {
getMarshaller().marshal(requestPayload, message.getPayloadResult());
}
}, new WebServiceMessageExtractor() {
public Object extractData(WebServiceMessage message) throws IOException {
return getUnmarshaller().unmarshal(message.getPayloadSource());
});
if (response != null) {
return getUnmarshaller().unmarshal(response.getPayloadSource());
}
else {
return null;
}
}
public void sendAndReceive(final Source requestPayload, Result result) throws IOException {
Source responsePayload = sendAndReceive(requestPayload);
if (responsePayload != null) {
try {
Transformer transformer = createTransformer();
transformer.transform(responsePayload, result);
}
catch (TransformerException e) {
throw new WebServiceClientException("Could not transform payload of responsePayload message");
}
}
}
public Source sendAndReceive(final Source requestPayload) throws IOException {
return (Source) sendAndReceive(new WebServiceMessageCallback() {
public void doInMessage(WebServiceMessage message) {
try {
Transformer transformer = createTransformer();
transformer.transform(requestPayload, message.getPayloadResult());
}
catch (TransformerException ex) {
throw new WebServiceClientException("Could not transform payload to request message", ex);
}
}
});
}
public Source send(final Source payload) {
return (Source) send(new WebServiceMessageCallback() {
public void doInWebServiceMessage(WebServiceMessage message) throws Exception {
Transformer transformer = createTransformer();
transformer.transform(payload, message.getPayloadResult());
}
}, new WebServiceMessageExtractor() {
public Object extractData(WebServiceMessage message) throws WebServiceException {
return message.getPayloadSource();
}
});
public WebServiceMessage sendAndReceive(WebServiceMessageCallback requestCallback) throws IOException {
MessageContext messageContext = createMessageContext();
if (requestCallback != null) {
requestCallback.doInMessage(messageContext.getRequest());
}
getMessageSender().sendAndReceive(messageContext);
if (messageContext.hasResponse()) {
return messageContext.getResponse();
}
else {
return null;
}
}
private void checkMarshallerAndUnmarshaller() throws IllegalStateException {
@@ -98,31 +130,4 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
}
}
public WebServiceMessage send(WebServiceMessageCallback callback) {
return (WebServiceMessage) send(callback, new WebServiceMessageExtractor() {
public Object extractData(WebServiceMessage message) throws Exception {
return message;
}
});
}
public Object send(WebServiceMessageCallback callback, WebServiceMessageExtractor extractor) {
Assert.notNull(callback, "callback must not be null");
Assert.notNull(extractor, "extractor must not be null");
WebServiceMessage request = getMessageFactory().createWebServiceMessage();
try {
callback.doInWebServiceMessage(request);
WebServiceMessage response = null; //getMessageSender().send(request);
if (response == null) {
return null;
}
else {
return extractor.extractData(response);
}
}
catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
return null;
}
}
}

View File

@@ -7,13 +7,14 @@ import org.springframework.ws.context.MessageContext;
/**
* @author Arjen Poutsma
*/
public interface MessageSender {
public interface WebServiceMessageSender {
/**
* Sends the given message context. The response message, if any, is stored in the context.
*
* @param messageContext the message to be sent
* @throws IOException in case of I/O errors
*/
void send(MessageContext messageContext) throws IOException;
void sendAndReceive(MessageContext messageContext) throws IOException;
}

View File

@@ -25,11 +25,11 @@ import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.transport.MessageSender;
import org.springframework.ws.transport.TransportInputStream;
import org.springframework.ws.transport.WebServiceMessageSender;
/**
* <code>MessageSender</code> implementation that uses <a href="http://jakarta.apache.org/commons/httpclient">Jakarta
* <code>WebServiceMessageSender</code> implementation that uses <a href="http://jakarta.apache.org/commons/httpclient">Jakarta
* Commons HttpClient</a> to execute POST requests.
* <p/>
* Allows to use a preconfigured HttpClient instance, potentially with authentication, HTTP connection pooling, etc.
@@ -38,7 +38,7 @@ import org.springframework.ws.transport.TransportInputStream;
* @author Arjen Poutsma
* @see org.springframework.ws.transport.http.HttpUrlConnectionMessageSender
*/
public class CommonsHttpMessageSender implements MessageSender {
public class CommonsHttpMessageSender implements WebServiceMessageSender {
private HttpClient httpClient;
@@ -69,7 +69,7 @@ public class CommonsHttpMessageSender implements MessageSender {
this.httpClient = httpClient;
}
public void send(MessageContext messageContext) throws IOException {
public void sendAndReceive(MessageContext messageContext) throws IOException {
PostMethod postMethod = createPostMethod();
try {
writeRequestMessage(postMethod, messageContext.getRequest());

View File

@@ -23,13 +23,13 @@ import java.net.URLConnection;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.transport.MessageSender;
import org.springframework.ws.transport.TransportInputStream;
import org.springframework.ws.transport.TransportOutputStream;
import org.springframework.ws.transport.WebServiceMessageSender;
/**
* <code>MessageSender</code> implementation that uses standard J2SE facilities to execute POST requests, without
* support for HTTP authentication or advanced configuration options.
* <code>WebServiceMessageSender</code> implementation that uses standard J2SE facilities to execute POST requests,
* without support for HTTP authentication or advanced configuration options.
* <p/>
* Designed for easy subclassing, customizing specific template methods. However, consider {@link
* org.springframework.ws.transport.http.CommonsHttpMessageSender} for more sophisticated needs: the J2SE
@@ -38,7 +38,7 @@ import org.springframework.ws.transport.TransportOutputStream;
* @author Arjen Poutsma
* @see java.net.HttpURLConnection
*/
public class HttpUrlConnectionMessageSender implements MessageSender {
public class HttpUrlConnectionMessageSender implements WebServiceMessageSender {
private static final String HTTP_METHOD_POST = "POST";
@@ -58,7 +58,7 @@ public class HttpUrlConnectionMessageSender implements MessageSender {
this.url = url;
}
public void send(MessageContext messageContext) throws IOException {
public void sendAndReceive(MessageContext messageContext) throws IOException {
HttpURLConnection connection = openConnection();
try {
prepareConnection(connection);

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2007 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.client;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.context.MessageContext;
public class WebServiceAccessorTest extends TestCase {
private WebServiceAccessor accessor;
protected void setUp() throws Exception {
accessor = new MyWebServiceAccessor();
}
public void testCreateMessageContext() throws Exception {
MockControl factoryControl = MockControl.createControl(WebServiceMessageFactory.class);
WebServiceMessageFactory factoryMock = (WebServiceMessageFactory) factoryControl.getMock();
accessor.setMessageFactory(factoryMock);
MockControl messageControl = MockControl.createControl(WebServiceMessage.class);
WebServiceMessage messageMock = (WebServiceMessage) messageControl.getMock();
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), messageMock);
factoryControl.replay();
messageControl.replay();
MessageContext messageContext = accessor.createMessageContext();
assertNotNull("No MesageContext created", messageContext);
factoryControl.verify();
messageControl.verify();
}
private static class MyWebServiceAccessor extends WebServiceAccessor {
}
}

View File

@@ -16,35 +16,42 @@
package org.springframework.ws.client;
import java.io.IOException;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.transport.WebServiceMessageSender;
public class WebServiceTemplateTest extends TestCase {
private WebServiceTemplate template;
private MockControl marshallerControl;
private MockControl factoryControl;
private Marshaller marshallerMock;
private WebServiceMessageFactory factoryMock;
private MockControl unmarshallerControl;
private MockControl messageControl;
private Unmarshaller unmarshallerMock;
private WebServiceMessage requestMock;
private WebServiceMessage responseMock;
protected void setUp() throws Exception {
template = new WebServiceTemplate();
marshallerControl = MockControl.createControl(Marshaller.class);
marshallerMock = (Marshaller) marshallerControl.getMock();
template.setMarshaller(marshallerMock);
unmarshallerControl = MockControl.createControl(Unmarshaller.class);
unmarshallerMock = (Unmarshaller) unmarshallerControl.getMock();
template.setUnmarshaller(unmarshallerMock);
factoryControl = MockControl.createControl(WebServiceMessageFactory.class);
factoryMock = (WebServiceMessageFactory) factoryControl.getMock();
template.setMessageFactory(factoryMock);
messageControl = MockControl.createControl(WebServiceMessage.class);
requestMock = (WebServiceMessage) messageControl.getMock();
responseMock = (WebServiceMessage) messageControl.getMock();
}
public void testMarshalAndSendNoMarshallerSet() throws Exception {
template.setMarshaller(null);
replayMockControls();
try {
template.marshalAndSend(new Object());
fail("IllegalStateException expected");
@@ -52,10 +59,12 @@ public class WebServiceTemplateTest extends TestCase {
catch (IllegalStateException ex) {
// expected behavior
}
verifyMockControls();
}
public void testMarshalAndSendNoUnmarshallerSet() throws Exception {
template.setUnmarshaller(null);
replayMockControls();
try {
template.marshalAndSend(new Object());
fail("IllegalStateException expected");
@@ -63,5 +72,38 @@ public class WebServiceTemplateTest extends TestCase {
catch (IllegalStateException ex) {
// expected behavior
}
verifyMockControls();
}
public void testSendAndReceiveMessageResponse() throws Exception {
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), requestMock);
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), responseMock);
template.setMessageSender(new WebServiceMessageSender() {
public void sendAndReceive(MessageContext messageContext) throws IOException {
assertEquals("Invalid request message", requestMock, messageContext.getRequest());
messageContext.getResponse();
}
});
replayMockControls();
WebServiceMessage response = template.sendAndReceive(new WebServiceMessageCallback() {
public void doInMessage(WebServiceMessage message) throws IOException {
assertEquals("Invalid request message", requestMock, message);
}
});
assertEquals("No response", responseMock, response);
verifyMockControls();
}
private void replayMockControls() {
factoryControl.replay();
messageControl.replay();
}
private void verifyMockControls() {
factoryControl.verify();
messageControl.verify();
}
}

View File

@@ -22,7 +22,6 @@ import javax.xml.soap.SOAPMessage;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
public class CommonsHttpMessageSenderTest extends AbstractHttpWebServiceMessageSenderTestCase {
@@ -40,11 +39,8 @@ public class CommonsHttpMessageSenderTest extends AbstractHttpWebServiceMessageS
public void testSend() throws Exception {
SOAPMessage message = messageFactory.createMessage();
message.getMimeHeaders().addHeader(HEADER_NAME, HEADER_VALUE);
SaajSoapMessage request = new SaajSoapMessage(message);
MessageContext context = new DefaultMessageContext(request, new SaajSoapMessageFactory(messageFactory));
// AxiomSoapMessageFactory soapMessageFactory = new AxiomSoapMessageFactory();
// MessageContext context = new DefaultMessageContext(soapMessageFactory);
sender.send(context);
MessageContext context = new DefaultMessageContext(new SaajSoapMessageFactory(messageFactory));
sender.sendAndReceive(context);
assertTrue("No response", context.hasResponse());
context.getResponse().writeTo(System.out);

View File

@@ -44,7 +44,7 @@ public class HttpUrlConnectionMessageSenderTest extends AbstractHttpWebServiceMe
MessageContext context = new DefaultMessageContext(request, new SaajSoapMessageFactory(messageFactory));
// AxiomSoapMessageFactory soapMessageFactory = new AxiomSoapMessageFactory();
// MessageContext context = new DefaultMessageContext(soapMessageFactory);
sender.send(context);
sender.sendAndReceive(context);
assertTrue("No response", context.hasResponse());
context.getResponse().writeTo(System.out);

View File

@@ -94,7 +94,7 @@ public class MessageEndpointMessageListenerTest extends TestCase {
request.reset();
sessionControl.expectAndReturn(sessionMock.createBytesMessage(), response);
sessionControl.expectAndReturn(sessionMock.createProducer(replyTo), producerMock);
producerMock.send(response);
producerMock.sendAndReceive(response);
sessionControl.replay();
producerControl.replay();