WebServiceConnection is now container for TransportInputStream and TransportOutputStream, used on both client- and server-side.
This commit is contained in:
@@ -31,6 +31,9 @@ import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.client.WebServiceClientException;
|
||||
import org.springframework.ws.client.support.WebServiceAccessor;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
import org.springframework.ws.transport.WebServiceMessageSender;
|
||||
|
||||
@@ -76,44 +79,32 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
|
||||
setMessageSender(messageSender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the marshaller for this template.
|
||||
*/
|
||||
/** Returns the marshaller for this template. */
|
||||
public Marshaller getMarshaller() {
|
||||
return marshaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the marshaller for this template.
|
||||
*/
|
||||
/** Sets the marshaller for this template. */
|
||||
public void setMarshaller(Marshaller marshaller) {
|
||||
this.marshaller = marshaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unmarshaller for this template.
|
||||
*/
|
||||
/** Returns the unmarshaller for this template. */
|
||||
public Unmarshaller getUnmarshaller() {
|
||||
return unmarshaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the unmarshaller for this template.
|
||||
*/
|
||||
/** Sets the unmarshaller for this template. */
|
||||
public void setUnmarshaller(Unmarshaller unmarshaller) {
|
||||
this.unmarshaller = unmarshaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fault resolver for this template.
|
||||
*/
|
||||
/** Returns the fault resolver for this template. */
|
||||
public FaultResolver getFaultResolver() {
|
||||
return faultResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fault resolver for this template.
|
||||
*/
|
||||
/** Sets the fault resolver for this template. */
|
||||
public void setFaultResolver(FaultResolver faultResolver) {
|
||||
Assert.notNull(faultResolver, "faultResolver must not be null");
|
||||
this.faultResolver = faultResolver;
|
||||
@@ -185,36 +176,6 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
|
||||
/*
|
||||
* Source-handling methods
|
||||
*/
|
||||
/*
|
||||
public Source sendAndReceive(final Source requestPayload) throws IOException {
|
||||
return sendAndReceive(requestPayload, (WebServiceMessageCallback) null);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public Source sendAndReceive(final Source requestPayload, final WebServiceMessageCallback requestCallback)
|
||||
throws IOException {
|
||||
return (Source) sendAndReceive(new WebServiceMessageCallback() {
|
||||
public void doInMessage(WebServiceMessage message) throws IOException {
|
||||
try {
|
||||
Transformer transformer = createTransformer();
|
||||
transformer.transform(requestPayload, message.getPayloadResult());
|
||||
if (requestCallback != null) {
|
||||
requestCallback.doInMessage(message);
|
||||
}
|
||||
}
|
||||
catch (TransformerException ex) {
|
||||
throw new WebServiceClientException("Could not transform payload to request message", ex);
|
||||
}
|
||||
}
|
||||
}, new WebServiceMessageExtractor() {
|
||||
|
||||
public Object extractData(WebServiceMessage message) throws IOException {
|
||||
return message.getPayloadSource();
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
public Object sendAndReceive(final Source requestPayload, final SourceExtractor responseExtractor)
|
||||
throws IOException {
|
||||
@@ -254,8 +215,8 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
|
||||
}
|
||||
|
||||
/*
|
||||
* WebServiceMessage-handling methods
|
||||
*/
|
||||
* WebServiceMessage-handling methods
|
||||
*/
|
||||
|
||||
public void sendAndReceive(WebServiceMessageCallback requestCallback, WebServiceMessageCallback responseCallback)
|
||||
throws IOException {
|
||||
@@ -266,33 +227,64 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
|
||||
public Object sendAndReceive(WebServiceMessageCallback requestCallback,
|
||||
WebServiceMessageExtractor responseExtractor) throws IOException {
|
||||
Assert.notNull(responseExtractor, "response extractor must not be null");
|
||||
WebServiceConnection connection = getMessageSender().createConnection();
|
||||
MessageContext messageContext = createMessageContext();
|
||||
WebServiceConnection connection = getMessageSender().createConnection();
|
||||
try {
|
||||
WebServiceMessage request = messageContext.getRequest();
|
||||
if (requestCallback != null) {
|
||||
requestCallback.doInMessage(messageContext.getRequest());
|
||||
requestCallback.doInMessage(request);
|
||||
}
|
||||
connection.sendAndReceive(messageContext);
|
||||
if (!messageContext.hasResponse()) {
|
||||
return null;
|
||||
}
|
||||
WebServiceMessage response = messageContext.getResponse();
|
||||
if (response.hasFault()) {
|
||||
getFaultResolver().resolveFault(response);
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return responseExtractor.extractData(response);
|
||||
sendRequest(connection, messageContext);
|
||||
TransportInputStream tis = connection.getTransportInputStream();
|
||||
if (tis != null) {
|
||||
try {
|
||||
messageContext.readResponse(tis);
|
||||
if (messageContext.hasResponse()) {
|
||||
WebServiceMessage response = messageContext.getResponse();
|
||||
if (!hasFault(connection, messageContext)) {
|
||||
// normal response
|
||||
return responseExtractor.extractData(response);
|
||||
}
|
||||
else {
|
||||
// fault response
|
||||
getFaultResolver().resolveFault(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
tis.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter to enable use of a WebServiceMessageCallback inside a WebServiceMessageExtractor.
|
||||
*/
|
||||
/** Sends the request in the given message context over the connection. */
|
||||
private void sendRequest(WebServiceConnection connection, MessageContext messageContext) throws IOException {
|
||||
TransportOutputStream tos = connection.getTransportOutputStream();
|
||||
try {
|
||||
messageContext.getRequest().writeTo(tos);
|
||||
tos.flush();
|
||||
}
|
||||
finally {
|
||||
tos.close();
|
||||
}
|
||||
}
|
||||
|
||||
/** Determines whether the given connection or message context has a fault. */
|
||||
private boolean hasFault(WebServiceConnection connection, MessageContext messageContext) throws IOException {
|
||||
if (connection instanceof FaultAwareWebServiceConnection) {
|
||||
return ((FaultAwareWebServiceConnection) connection).hasFault();
|
||||
}
|
||||
else {
|
||||
return messageContext.getResponse().hasFault();
|
||||
}
|
||||
}
|
||||
|
||||
/** Adapter to enable use of a WebServiceMessageCallback inside a WebServiceMessageExtractor. */
|
||||
private static class WebServiceMessageCallbackMessageExtractor implements WebServiceMessageExtractor {
|
||||
|
||||
private final WebServiceMessageCallback callback;
|
||||
@@ -307,9 +299,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter to enable use of a SourceExtractor inside a WebServiceMessageExtractor.
|
||||
*/
|
||||
/** Adapter to enable use of a SourceExtractor inside a WebServiceMessageExtractor. */
|
||||
private static class SourceExtractorMessageExtractor implements WebServiceMessageExtractor {
|
||||
|
||||
private final SourceExtractor sourceExtractor;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Sub-interface of {@link WebServiceConnection} that is aware of any Faults received. Typically, fault detection is
|
||||
* done by inspecting connection error codes, etc.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public interface FaultAwareWebServiceConnection extends WebServiceConnection {
|
||||
|
||||
/**
|
||||
* Indicates whether this connection has a fault.
|
||||
*
|
||||
* @return <code>true</code> if this connection has a fault; <code>false</code> otherwise.
|
||||
*/
|
||||
boolean hasFault() throws IOException;
|
||||
|
||||
}
|
||||
@@ -19,33 +19,59 @@ package org.springframework.ws.transport;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.transport.http.HttpServletConnection;
|
||||
|
||||
/**
|
||||
* Represents a point-to-point connection that a client can use for sending {@link WebServiceMessage} objects directly
|
||||
* to a remote party.
|
||||
* <p/>
|
||||
* A <code>WebServiceConnection</code> can be obtained using a {@link WebServiceMessageSender}.
|
||||
* <p/>
|
||||
* On the receiving side, the typical usage scenario for this connection is: <ol> <li>Create concrete connection
|
||||
* implementation (eg. {@link HttpServletConnection}) <li>Read request from {@link #getTransportInputStream() the input
|
||||
* stream}. <li>{@link TransportInputStream#close() Close} the input stream <li>Write response to {@link
|
||||
* #getTransportOutputStream() the output stream}. <li>{@link TransportOutputStream#flush() Flush} the output stream
|
||||
* <li>{@link TransportOutputStream#close() Close} the output stream <li>{@link #close() Close the connection} </ol>
|
||||
* <p/>
|
||||
* On the sending side, the typical usage scenario for this connection is: <ol> <li>Create connection with {@link
|
||||
* WebServiceMessageSender#createConnection()} <li>Write request to {@link #getTransportOutputStream() the output
|
||||
* stream}. <li>{@link TransportOutputStream#flush() Flush} the output stream <li>{@link TransportOutputStream#close()
|
||||
* Close} the output stream <li> <li>Read request from {@link #getTransportInputStream() the input stream}. <li>{@link
|
||||
* TransportInputStream#close() Close} the input stream <li>{@link #close() Close the connection} </ol>
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see WebServiceMessageSender#createConnection()
|
||||
* @see #getTransportInputStream()
|
||||
* @see #getTransportOutputStream()
|
||||
*/
|
||||
public interface WebServiceConnection {
|
||||
|
||||
/**
|
||||
* Sends the given message and blocks until it has returned the response. The response message, if any, is stored in
|
||||
* the context.
|
||||
* Returns a transport input stream for this connection.
|
||||
* <p/>
|
||||
* Returns <code>null</code> if no transport input stream is available (eg. a request might not have a response).
|
||||
*
|
||||
* @param messageContext the context which contains the request message to be sent, and which will contain the
|
||||
* response afterwards
|
||||
* @throws IOException in case of I/O errors
|
||||
* @return a transport input stream for this connection, or <code>null</code>
|
||||
* @throws IOException if an I/O error occurs when creating the input stream, the connection is closed
|
||||
*/
|
||||
void sendAndReceive(MessageContext messageContext) throws IOException;
|
||||
TransportInputStream getTransportInputStream() throws IOException;
|
||||
|
||||
/**
|
||||
* Closes the <code>WebServiceConnection</code>.
|
||||
* Returns a transport output stream for this connection.
|
||||
* <p/>
|
||||
* Returns <code>null</code> if no transport output stream is available (eg. a response might not have a response).
|
||||
*
|
||||
* @throws IOException in case of I/O errors
|
||||
* @return a transport output stream for this connection
|
||||
* @throws IOException if an I/O error occurs when creating the output stream, the connection is closed
|
||||
*/
|
||||
TransportOutputStream getTransportOutputStream() throws IOException;
|
||||
|
||||
/**
|
||||
* Closes this connection.
|
||||
* <p/>
|
||||
* Once a connection has been closed, it is not available for further use. A new connection needs to be created.
|
||||
*
|
||||
* @throws IOException if an I/O error occurs when closing this socket
|
||||
*/
|
||||
void close() throws IOException;
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
|
||||
package org.springframework.ws.transport.context;
|
||||
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
|
||||
/**
|
||||
* Default implementation of the <code>TransportContext</code> interface.
|
||||
@@ -26,24 +25,15 @@ import org.springframework.ws.transport.TransportOutputStream;
|
||||
*/
|
||||
public class DefaultTransportContext implements TransportContext {
|
||||
|
||||
private final TransportInputStream transportInputStream;
|
||||
private final WebServiceConnection connection;
|
||||
|
||||
private final TransportOutputStream transportOutputStream;
|
||||
|
||||
/**
|
||||
* Creates a new <code>DefaultTransportContext</code> that exposes the given streams.
|
||||
*/
|
||||
public DefaultTransportContext(TransportInputStream transportInputStream,
|
||||
TransportOutputStream transportOutputStream) {
|
||||
this.transportInputStream = transportInputStream;
|
||||
this.transportOutputStream = transportOutputStream;
|
||||
/** Creates a new <code>DefaultTransportContext</code> that exposes the given connection. */
|
||||
public DefaultTransportContext(WebServiceConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public TransportInputStream getTransportInputStream() {
|
||||
return transportInputStream;
|
||||
public WebServiceConnection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public TransportOutputStream getTransportOutputStream() {
|
||||
return transportOutputStream;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package org.springframework.ws.transport.context;
|
||||
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
|
||||
/**
|
||||
* Strategy interface for determining the current {@link org.springframework.ws.transport.TransportInputStream} and
|
||||
* {@link org.springframework.ws.transport.TransportOutputStream}.
|
||||
* Strategy interface for determining the current {@link org.springframework.ws.transport.WebServiceConnection}.
|
||||
* <p/>
|
||||
* An instance of this class can be associated with a thread via the {@link TransportContextHolder} class.
|
||||
*
|
||||
@@ -13,13 +11,6 @@ import org.springframework.ws.transport.TransportOutputStream;
|
||||
*/
|
||||
public interface TransportContext {
|
||||
|
||||
/**
|
||||
* Returns the current <code>TransportInputStream</code>.
|
||||
*/
|
||||
TransportInputStream getTransportInputStream();
|
||||
|
||||
/**
|
||||
* Returns the current <code>TransportOutputStream</code>.
|
||||
*/
|
||||
TransportOutputStream getTransportOutputStream();
|
||||
/** Returns the current <code>WebServiceConnection</code>. */
|
||||
WebServiceConnection getConnection();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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.transport.http;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.httpclient.Header;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
|
||||
/**
|
||||
* Implementation of {@link WebServiceConnection} that is based on Jakarta Commons HttpClient. Exposes a {@link
|
||||
* PostMethod}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class CommonsHttpConnection implements FaultAwareWebServiceConnection {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
private final PostMethod postMethod;
|
||||
|
||||
private byte[] bufferedInput;
|
||||
|
||||
public CommonsHttpConnection(HttpClient httpClient, PostMethod postMethod) {
|
||||
Assert.notNull(httpClient, "httpClient must not be null");
|
||||
Assert.notNull(postMethod, "postMethod must not be null");
|
||||
this.httpClient = httpClient;
|
||||
this.postMethod = postMethod;
|
||||
}
|
||||
|
||||
/** Returns the wrapped <code>PostMethod</code>. */
|
||||
public HttpMethod getPostMethod() {
|
||||
return postMethod;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
postMethod.releaseConnection();
|
||||
}
|
||||
|
||||
public TransportOutputStream getTransportOutputStream() {
|
||||
return new CommonsHttpTransportOutputStream();
|
||||
}
|
||||
|
||||
public TransportInputStream getTransportInputStream() throws IOException {
|
||||
return getContentLength() > 0 ? new CommonsHttpTransportInputStream() : null;
|
||||
}
|
||||
|
||||
public boolean hasFault() throws IOException {
|
||||
return postMethod.getStatusCode() == HttpStatus.SC_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
private long getContentLength() throws IOException {
|
||||
if (postMethod.getResponseContentLength() != -1) {
|
||||
return postMethod.getResponseContentLength();
|
||||
}
|
||||
else if (bufferedInput != null) {
|
||||
return bufferedInput.length;
|
||||
}
|
||||
else {
|
||||
bufferedInput = FileCopyUtils.copyToByteArray(getInputStream());
|
||||
return bufferedInput.length;
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getInputStream() throws IOException {
|
||||
if (postMethod.getStatusCode() != HttpStatus.SC_INTERNAL_SERVER_ERROR &&
|
||||
postMethod.getStatusCode() / 100 != 2) {
|
||||
throw new HttpTransportException("Did not receive successful HTTP response: status code = " +
|
||||
postMethod.getStatusCode() + ", status message = [" + postMethod.getStatusText() + "]");
|
||||
}
|
||||
return postMethod.getResponseBodyAsStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link TransportInputStream} based on the {@link PostMethod} field.
|
||||
*
|
||||
* @see CommonsHttpConnection#postMethod
|
||||
*/
|
||||
class CommonsHttpTransportInputStream extends TransportInputStream {
|
||||
|
||||
protected InputStream createInputStream() throws IOException {
|
||||
if (bufferedInput != null) {
|
||||
return new ByteArrayInputStream(bufferedInput);
|
||||
}
|
||||
else {
|
||||
return getInputStream();
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator getHeaderNames() throws IOException {
|
||||
Header[] headers = postMethod.getResponseHeaders();
|
||||
String[] names = new String[headers.length];
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
names[i] = headers[i].getName();
|
||||
}
|
||||
return Arrays.asList(names).iterator();
|
||||
}
|
||||
|
||||
public Iterator getHeaders(String name) throws IOException {
|
||||
Header[] headers = postMethod.getResponseHeaders(name);
|
||||
String[] values = new String[headers.length];
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
values[i] = headers[i].getValue();
|
||||
}
|
||||
return Arrays.asList(values).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link TransportOutputStream} based on the {@link PostMethod} field.
|
||||
*
|
||||
* @see CommonsHttpConnection#postMethod
|
||||
*/
|
||||
class CommonsHttpTransportOutputStream extends TransportOutputStream {
|
||||
|
||||
private final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
|
||||
public void addHeader(String name, String value) throws IOException {
|
||||
postMethod.addRequestHeader(name, value);
|
||||
}
|
||||
|
||||
protected OutputStream createOutputStream() throws IOException {
|
||||
return bos;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
postMethod.setRequestEntity(new ByteArrayRequestEntity(bos.toByteArray()));
|
||||
httpClient.executeMethod(postMethod);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -19,8 +19,10 @@ package org.springframework.ws.transport.http;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpConnectionManager;
|
||||
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
|
||||
@@ -34,7 +36,7 @@ import org.springframework.ws.transport.WebServiceConnection;
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.ws.transport.http.HttpUrlConnectionMessageSender
|
||||
*/
|
||||
public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSender {
|
||||
public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSender implements DisposableBean {
|
||||
|
||||
private HttpClient httpClient;
|
||||
|
||||
@@ -60,23 +62,26 @@ public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSende
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>HttpClient</code> used by this message sender.
|
||||
*/
|
||||
public void destroy() throws Exception {
|
||||
HttpConnectionManager connectionManager = httpClient.getHttpConnectionManager();
|
||||
if (connectionManager instanceof MultiThreadedHttpConnectionManager) {
|
||||
((MultiThreadedHttpConnectionManager) connectionManager).shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the <code>HttpClient</code> used by this message sender. */
|
||||
public HttpClient getHttpClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the <code>HttpClient</code> used by this message sender.
|
||||
*/
|
||||
/** Set the <code>HttpClient</code> used by this message sender. */
|
||||
public void setHttpClient(HttpClient httpClient) {
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
public WebServiceConnection createConnection() throws IOException {
|
||||
PostMethod method = new PostMethod(getUrl().toString());
|
||||
return new CommonsHttpWebServiceConnection(getHttpClient(), method);
|
||||
return new CommonsHttpConnection(getHttpClient(), method);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 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.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.httpclient.Header;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
|
||||
/**
|
||||
* Implementation of the <code>TransportInputStream</code> interface based on {@link
|
||||
* org.apache.commons.httpclient.methods.PostMethod}. Exposes the <code>PostMethod</code>.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class CommonsHttpTransportInputStream extends TransportInputStream {
|
||||
|
||||
private final PostMethod postMethod;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <code>CommonsHttpTransportInputStream</code> with a given
|
||||
* <code>PostMethod</code>.
|
||||
*/
|
||||
public CommonsHttpTransportInputStream(PostMethod postMethod) {
|
||||
Assert.notNull(postMethod, "postMethod must not be null");
|
||||
this.postMethod = postMethod;
|
||||
}
|
||||
|
||||
protected InputStream createInputStream() throws IOException {
|
||||
return postMethod.getResponseBodyAsStream();
|
||||
}
|
||||
|
||||
public Iterator getHeaderNames() throws IOException {
|
||||
Header[] headers = postMethod.getResponseHeaders();
|
||||
String[] names = new String[headers.length];
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
names[i] = headers[i].getName();
|
||||
}
|
||||
return Arrays.asList(names).iterator();
|
||||
}
|
||||
|
||||
public Iterator getHeaders(String name) throws IOException {
|
||||
Header[] headers = postMethod.getResponseHeaders(name);
|
||||
String[] names = new String[headers.length];
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
names[i] = headers[i].getValue();
|
||||
}
|
||||
return Arrays.asList(names).iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped <code>PostMethod</code>.
|
||||
*/
|
||||
public HttpMethod getPostMethod() {
|
||||
return postMethod;
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 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.transport.http;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
|
||||
/**
|
||||
* Implementation of the <code>TransportOutputStream</code> interface based on {@link
|
||||
* org.apache.commons.httpclient.methods.PostMethod}. Exposes the <code>PostMethod</code>.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class CommonsHttpTransportOutputStream extends TransportOutputStream {
|
||||
|
||||
private final PostMethod postMethod;
|
||||
|
||||
private final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <code>CommonsHttpTransportOutputStream</code> with a given
|
||||
* <code>PostMethod</code>.
|
||||
*/
|
||||
public CommonsHttpTransportOutputStream(PostMethod postMethod) {
|
||||
this.postMethod = postMethod;
|
||||
}
|
||||
|
||||
public void addHeader(String name, String value) throws IOException {
|
||||
postMethod.addRequestHeader(name, value);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
postMethod.setRequestEntity(new ByteArrayRequestEntity(bos.toByteArray()));
|
||||
}
|
||||
|
||||
protected OutputStream createOutputStream() throws IOException {
|
||||
return bos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped <code>PostMethod</code>.
|
||||
*/
|
||||
public HttpMethod getPostMethod() {
|
||||
return postMethod;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* 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.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link WebServiceConnection} that uses Jakarta Commons HttpClient.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class CommonsHttpWebServiceConnection implements WebServiceConnection {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
private final PostMethod postMethod;
|
||||
|
||||
public CommonsHttpWebServiceConnection(HttpClient httpClient, PostMethod postMethod) {
|
||||
Assert.notNull(httpClient, "httpClient must not be null");
|
||||
Assert.notNull(postMethod, "postMethod must not be null");
|
||||
this.httpClient = httpClient;
|
||||
this.postMethod = postMethod;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
postMethod.releaseConnection();
|
||||
}
|
||||
|
||||
public void sendAndReceive(MessageContext messageContext) throws IOException {
|
||||
writeRequestMessage(messageContext.getRequest());
|
||||
executePostMethod();
|
||||
validateResponse(postMethod);
|
||||
readResponse(postMethod, messageContext);
|
||||
}
|
||||
|
||||
private void writeRequestMessage(WebServiceMessage message) throws IOException {
|
||||
CommonsHttpTransportOutputStream tos = new CommonsHttpTransportOutputStream(postMethod);
|
||||
message.writeTo(tos);
|
||||
tos.flush();
|
||||
// calling close() causes the RequestEntity to be set on the PostMethod
|
||||
tos.close();
|
||||
}
|
||||
|
||||
private void executePostMethod() throws IOException {
|
||||
httpClient.executeMethod(postMethod);
|
||||
}
|
||||
|
||||
private void validateResponse(PostMethod postMethod) throws IOException {
|
||||
int statusCode = postMethod.getStatusCode();
|
||||
if (statusCode != HttpStatus.SC_INTERNAL_SERVER_ERROR && statusCode / 100 != 2) {
|
||||
throw new HttpTransportException("Did not receive successful HTTP response: status code = " + statusCode +
|
||||
", status message = [" + postMethod.getStatusText() + "]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void readResponse(PostMethod postMethod, MessageContext messageContext) throws IOException {
|
||||
if (postMethod.getStatusCode() == HttpStatus.SC_NO_CONTENT || postMethod.getResponseContentLength() == 0) {
|
||||
return;
|
||||
}
|
||||
messageContext.readResponse(new CommonsHttpTransportInputStream(postMethod));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Iterator;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
import org.springframework.ws.transport.support.EnumerationIterator;
|
||||
|
||||
/**
|
||||
* Implementation of {@link WebServiceConnection} that is based on the Servlet API. Exposes a {@link HttpServletRequest}
|
||||
* and {@link HttpServletResponse}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Arjen Poutsma
|
||||
* @see #getHttpServletRequest()
|
||||
* @see #getHttpServletResponse()
|
||||
*/
|
||||
public class HttpServletConnection implements WebServiceConnection {
|
||||
|
||||
private final HttpServletRequest httpServletRequest;
|
||||
|
||||
private final HttpServletResponse httpServletResponse;
|
||||
|
||||
/**
|
||||
* Constructs a new servlet connection with the given <code>HttpServletRequest</code> and
|
||||
* <code>HttpServletResponse</code>.
|
||||
*/
|
||||
public HttpServletConnection(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
|
||||
this.httpServletRequest = httpServletRequest;
|
||||
this.httpServletResponse = httpServletResponse;
|
||||
}
|
||||
|
||||
/** Returns the <code>HttpServletRequest</code> for this connection. */
|
||||
public HttpServletRequest getHttpServletRequest() {
|
||||
return httpServletRequest;
|
||||
}
|
||||
|
||||
/** Returns the <code>HttpServletResponse</code> for this connection. */
|
||||
public HttpServletResponse getHttpServletResponse() {
|
||||
return httpServletResponse;
|
||||
}
|
||||
|
||||
public TransportInputStream getTransportInputStream() {
|
||||
return new HttpServletTransportInputStream();
|
||||
}
|
||||
|
||||
public TransportOutputStream getTransportOutputStream() {
|
||||
return new HttpServletTransportOutputStream();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
// no op
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link TransportInputStream} based on the {@link HttpServletRequest} field.
|
||||
*
|
||||
* @see HttpServletConnection#httpServletRequest
|
||||
*/
|
||||
private class HttpServletTransportInputStream extends TransportInputStream {
|
||||
|
||||
protected InputStream createInputStream() throws IOException {
|
||||
return httpServletRequest.getInputStream();
|
||||
}
|
||||
|
||||
public Iterator getHeaderNames() {
|
||||
return new EnumerationIterator(httpServletRequest.getHeaderNames());
|
||||
}
|
||||
|
||||
public Iterator getHeaders(String name) {
|
||||
return new EnumerationIterator(httpServletRequest.getHeaders(name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link TransportOutputStream} based on the {@link HttpServletResponse} field.
|
||||
*
|
||||
* @see HttpServletConnection#httpServletResponse
|
||||
*/
|
||||
private class HttpServletTransportOutputStream extends TransportOutputStream {
|
||||
|
||||
protected OutputStream createOutputStream() throws IOException {
|
||||
return httpServletResponse.getOutputStream();
|
||||
}
|
||||
|
||||
public void addHeader(String name, String value) {
|
||||
httpServletResponse.addHeader(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 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.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.support.EnumerationIterator;
|
||||
|
||||
/**
|
||||
* HTTP Servlet specific implementation of the <code>TransportInputStream</code> interface. Exposes the
|
||||
* <code>HttpServletRequest</code>.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see #getHttpServletRequest()
|
||||
*/
|
||||
class HttpServletTransportInputStream extends TransportInputStream {
|
||||
|
||||
private final HttpServletRequest httpServletRequest;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <code>HttpTransportRequest</code> with the given
|
||||
* <code>HttpServletRequest</code>.
|
||||
*/
|
||||
public HttpServletTransportInputStream(HttpServletRequest httpServletRequest) throws IOException {
|
||||
this.httpServletRequest = httpServletRequest;
|
||||
}
|
||||
|
||||
protected InputStream createInputStream() throws IOException {
|
||||
return httpServletRequest.getInputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped <code>HttpServletRequest</code>.
|
||||
*/
|
||||
public HttpServletRequest getHttpServletRequest() {
|
||||
return httpServletRequest;
|
||||
}
|
||||
|
||||
public Iterator getHeaderNames() {
|
||||
return new EnumerationIterator(httpServletRequest.getHeaderNames());
|
||||
}
|
||||
|
||||
public Iterator getHeaders(String name) {
|
||||
return new EnumerationIterator(httpServletRequest.getHeaders(name));
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 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.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
|
||||
/**
|
||||
* HTTP Servlet specific implementation of the <code>TransportOutputStream</code> interface. Exposes the
|
||||
* <code>HttpServletResponse</code>.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see #getHttpServletResponse()
|
||||
*/
|
||||
class HttpServletTransportOutputStream extends TransportOutputStream {
|
||||
|
||||
private final HttpServletResponse httpServletResponse;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <code>HttpTransportResponse</code> with the given
|
||||
* <code>HttpServletResponse</code>.
|
||||
*/
|
||||
public HttpServletTransportOutputStream(HttpServletResponse httpServletResponse) throws IOException {
|
||||
this.httpServletResponse = httpServletResponse;
|
||||
}
|
||||
|
||||
protected OutputStream createOutputStream() throws IOException {
|
||||
return httpServletResponse.getOutputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped <code>HttpServletResponse</code>.
|
||||
*/
|
||||
public HttpServletResponse getHttpServletResponse() {
|
||||
return httpServletResponse;
|
||||
}
|
||||
|
||||
public void addHeader(String name, String value) {
|
||||
httpServletResponse.addHeader(name, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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.transport.http;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.ProtocolException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link WebServiceConnection} interface that uses a {@link HttpURLConnection}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class HttpUrlConnection implements FaultAwareWebServiceConnection {
|
||||
|
||||
private final HttpURLConnection connection;
|
||||
|
||||
private byte[] bufferedInput;
|
||||
|
||||
/** Creates a new instance of the <code>HttpUrlConnection</code> with the given <code>HttpURLConnection</code>. */
|
||||
public HttpUrlConnection(HttpURLConnection connection) throws ProtocolException {
|
||||
Assert.notNull(connection, "connection must not be null");
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
/** Returns the wrapped <code>HttpURLConnection</code>. */
|
||||
public HttpURLConnection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
public TransportOutputStream getTransportOutputStream() {
|
||||
return new HttpUrlConnectionTransportOutputStream();
|
||||
}
|
||||
|
||||
public TransportInputStream getTransportInputStream() throws IOException {
|
||||
return getContentLength() > 0 ? new HttpUrlConnectionTransportInputStream() : null;
|
||||
}
|
||||
|
||||
public boolean hasFault() throws IOException {
|
||||
return connection.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
private int getContentLength() throws IOException {
|
||||
if (connection.getContentLength() != -1) {
|
||||
return connection.getContentLength();
|
||||
}
|
||||
else if (bufferedInput != null) {
|
||||
return bufferedInput.length;
|
||||
}
|
||||
else {
|
||||
bufferedInput = FileCopyUtils.copyToByteArray(getInputStream());
|
||||
return bufferedInput.length;
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getInputStream() throws IOException {
|
||||
if (connection.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR) {
|
||||
return connection.getErrorStream();
|
||||
}
|
||||
else if (connection.getResponseCode() / 100 == 2) {
|
||||
return connection.getInputStream();
|
||||
}
|
||||
else {
|
||||
throw new HttpTransportException("Did not receive successful HTTP response: status code = " +
|
||||
connection.getResponseCode() + ", status message = [" + connection.getResponseMessage() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link TransportInputStream} based on the {@link HttpURLConnection} field.
|
||||
*
|
||||
* @see HttpUrlConnection#connection
|
||||
*/
|
||||
|
||||
class HttpUrlConnectionTransportInputStream extends TransportInputStream {
|
||||
|
||||
protected InputStream createInputStream() throws IOException {
|
||||
if (bufferedInput != null) {
|
||||
return new ByteArrayInputStream(bufferedInput);
|
||||
}
|
||||
else {
|
||||
return getInputStream();
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator getHeaderNames() throws IOException {
|
||||
List headerNames = new ArrayList();
|
||||
// Header field 0 is the status line, so we start at 1
|
||||
int i = 1;
|
||||
while (true) {
|
||||
String headerName = connection.getHeaderFieldKey(i);
|
||||
if (!StringUtils.hasLength(headerName)) {
|
||||
break;
|
||||
}
|
||||
headerNames.add(headerName);
|
||||
i++;
|
||||
}
|
||||
return headerNames.iterator();
|
||||
}
|
||||
|
||||
public Iterator getHeaders(String name) throws IOException {
|
||||
String headerField = connection.getHeaderField(name);
|
||||
if (headerField == null) {
|
||||
return Collections.EMPTY_LIST.iterator();
|
||||
}
|
||||
else {
|
||||
Set tokens = StringUtils.commaDelimitedListToSet(headerField);
|
||||
return tokens.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link TransportOutputStream} based on the {@link HttpURLConnection} field.
|
||||
*
|
||||
* @see HttpUrlConnection#connection
|
||||
*/
|
||||
class HttpUrlConnectionTransportOutputStream extends TransportOutputStream {
|
||||
|
||||
public void addHeader(String name, String value) throws IOException {
|
||||
connection.addRequestProperty(name, value);
|
||||
}
|
||||
|
||||
protected OutputStream createOutputStream() throws IOException {
|
||||
return connection.getOutputStream();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
connection.connect();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,12 +35,21 @@ import org.springframework.ws.transport.WebServiceConnection;
|
||||
*/
|
||||
public class HttpUrlConnectionMessageSender extends AbstractHttpWebServiceMessageSender {
|
||||
|
||||
private static final String HTTP_METHOD_POST = "POST";
|
||||
|
||||
public WebServiceConnection createConnection() throws IOException {
|
||||
URLConnection con = getUrl().openConnection();
|
||||
if (!(con instanceof HttpURLConnection)) {
|
||||
URLConnection connection = getUrl().openConnection();
|
||||
if (!(connection instanceof HttpURLConnection)) {
|
||||
throw new HttpTransportException("URL [" + getUrl() + "] is not an HTTP URL");
|
||||
}
|
||||
return new HttpUrlConnectionWebServiceConnection((HttpURLConnection) con);
|
||||
else {
|
||||
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
|
||||
httpURLConnection.setRequestMethod(HTTP_METHOD_POST);
|
||||
httpURLConnection.setUseCaches(false);
|
||||
httpURLConnection.setDoInput(true);
|
||||
httpURLConnection.setDoOutput(true);
|
||||
return new HttpUrlConnection(httpURLConnection);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 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.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
|
||||
/**
|
||||
* Implementation of the <code>TransportInputStream</code> interface based on {@link java.net.HttpURLConnection}.
|
||||
* Exposes the <code>HttpURLConnection</code>.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class HttpUrlConnectionTransportInputStream extends TransportInputStream {
|
||||
|
||||
private final HttpURLConnection connection;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <code>HttpUrlConnectionTransportInputStream</code> based on the given
|
||||
* <code>HttpURLConnection</code>.
|
||||
*/
|
||||
public HttpUrlConnectionTransportInputStream(HttpURLConnection connection) throws IOException {
|
||||
Assert.notNull(connection, "connection must not be null");
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
protected InputStream createInputStream() throws IOException {
|
||||
if (connection.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR) {
|
||||
return connection.getErrorStream();
|
||||
}
|
||||
else {
|
||||
return connection.getInputStream();
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator getHeaderNames() throws IOException {
|
||||
List headerNames = new ArrayList();
|
||||
// Header field 0 is the status line, so we start at 1
|
||||
int i = 1;
|
||||
while (true) {
|
||||
String headerName = connection.getHeaderFieldKey(i);
|
||||
if (!StringUtils.hasLength(headerName)) {
|
||||
break;
|
||||
}
|
||||
headerNames.add(headerName);
|
||||
i++;
|
||||
}
|
||||
return headerNames.iterator();
|
||||
}
|
||||
|
||||
public Iterator getHeaders(String name) throws IOException {
|
||||
String headerField = connection.getHeaderField(name);
|
||||
if (headerField == null) {
|
||||
return Collections.EMPTY_LIST.iterator();
|
||||
}
|
||||
else {
|
||||
Set tokens = StringUtils.commaDelimitedListToSet(headerField);
|
||||
return tokens.iterator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 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.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
|
||||
/**
|
||||
* Implementation of the <code>TransportOutputStream</code> interface based on {@link java.net.HttpURLConnection}.
|
||||
* Exposes the <code>HttpURLConnection</code>.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class HttpUrlConnectionTransportOutputStream extends TransportOutputStream {
|
||||
|
||||
private final HttpURLConnection connection;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <code>HttpUrlConnectionTransportOutputStream</code> based on the given
|
||||
* <code>HttpURLConnection</code>.
|
||||
*/
|
||||
public HttpUrlConnectionTransportOutputStream(HttpURLConnection connection) throws IOException {
|
||||
Assert.notNull(connection, "connection must not be null");
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public void addHeader(String name, String value) throws IOException {
|
||||
connection.setRequestProperty(name, value);
|
||||
}
|
||||
|
||||
protected OutputStream createOutputStream() throws IOException {
|
||||
return connection.getOutputStream();
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* 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.transport.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.ProtocolException;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link WebServiceConnection} interface that uses a {@link HttpURLConnection}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class HttpUrlConnectionWebServiceConnection implements WebServiceConnection {
|
||||
|
||||
private static final String HTTP_METHOD_POST = "POST";
|
||||
|
||||
private final HttpURLConnection connection;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the <code>HttpUrlConnectionWebServiceConnection</code> with the given
|
||||
* <code>HttpURLConnection</code>.
|
||||
*/
|
||||
public HttpUrlConnectionWebServiceConnection(HttpURLConnection connection) {
|
||||
Assert.notNull(connection, "connection must not be null");
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
public void sendAndReceive(MessageContext messageContext) throws IOException {
|
||||
prepareConnection();
|
||||
writeRequestMessage(messageContext.getRequest());
|
||||
validateResponse();
|
||||
readResponse(messageContext);
|
||||
}
|
||||
|
||||
private void prepareConnection() throws ProtocolException {
|
||||
connection.setRequestMethod(HTTP_METHOD_POST);
|
||||
connection.setUseCaches(false);
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
}
|
||||
|
||||
private void writeRequestMessage(WebServiceMessage message) throws IOException {
|
||||
TransportOutputStream tos = new HttpUrlConnectionTransportOutputStream(connection);
|
||||
message.writeTo(tos);
|
||||
tos.flush();
|
||||
}
|
||||
|
||||
private void validateResponse() throws IOException {
|
||||
int responseCode = connection.getResponseCode();
|
||||
if (responseCode != HttpURLConnection.HTTP_INTERNAL_ERROR && responseCode / 100 != 2) {
|
||||
throw new HttpTransportException("Did not receive successful HTTP response: status code = " + responseCode +
|
||||
", status message = [" + connection.getResponseMessage() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private void readResponse(MessageContext messageContext) throws IOException {
|
||||
if (connection.getResponseCode() == HttpURLConnection.HTTP_NO_CONTENT || connection.getContentLength() == 0) {
|
||||
return;
|
||||
}
|
||||
messageContext.readResponse(new HttpUrlConnectionTransportInputStream(connection));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,15 +16,13 @@
|
||||
|
||||
package org.springframework.ws.transport.http;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
import org.springframework.ws.transport.WebServiceMessageReceiver;
|
||||
import org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport;
|
||||
|
||||
@@ -55,13 +53,13 @@ public class WebServiceMessageReceiverHandlerAdapter extends WebServiceMessageRe
|
||||
HttpServletResponse httpServletResponse,
|
||||
Object handler) throws Exception {
|
||||
if ("POST".equals(httpServletRequest.getMethod())) {
|
||||
TransportInputStream tis = new HttpServletTransportInputStream(httpServletRequest);
|
||||
TransportOutputStream tos = new HttpServletTransportOutputStream(httpServletResponse);
|
||||
handle(tis, tos, (WebServiceMessageReceiver) handler);
|
||||
WebServiceConnection connection = new HttpServletConnection(httpServletRequest, httpServletResponse);
|
||||
handleConnection(connection, (WebServiceMessageReceiver) handler);
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw new ServletException("Request method '" + httpServletRequest.getMethod() + "' not supported");
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,35 +67,30 @@ public class WebServiceMessageReceiverHandlerAdapter extends WebServiceMessageRe
|
||||
return handler instanceof WebServiceMessageReceiver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the response code to 204, No Content.
|
||||
*/
|
||||
protected void handleNoResponse(TransportInputStream tis, TransportOutputStream tos) {
|
||||
HttpServletResponse httpServletResponse = ((HttpServletTransportOutputStream) tos).getHttpServletResponse();
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);
|
||||
/** Sets the response code to 204, Accepted. */
|
||||
protected void handleNoResponse(WebServiceConnection connection) {
|
||||
HttpServletResponse httpServletResponse = ((HttpServletConnection) connection).getHttpServletResponse();
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_ACCEPTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the response code to 200, OK, for normal responses. Set the code to 500, Internal Server Error, in case of a
|
||||
* SOAP Fault,
|
||||
*/
|
||||
protected void handleResponse(TransportInputStream tis, TransportOutputStream tos, WebServiceMessage response)
|
||||
throws Exception {
|
||||
HttpServletResponse httpServletResponse = ((HttpServletTransportOutputStream) tos).getHttpServletResponse();
|
||||
protected void handleResponse(WebServiceConnection connection, WebServiceMessage response) throws Exception {
|
||||
HttpServletResponse httpServletResponse = ((HttpServletConnection) connection).getHttpServletResponse();
|
||||
if (response.hasFault()) {
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
else {
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
|
||||
}
|
||||
response.writeTo(tos);
|
||||
super.handleResponse(connection, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the response code to 404, Not Found.
|
||||
*/
|
||||
protected void handleNoEndpointFound(TransportInputStream tis, TransportOutputStream tos) {
|
||||
HttpServletResponse httpServletResponse = ((HttpServletTransportOutputStream) tos).getHttpServletResponse();
|
||||
/** Sets the response code to 404, Not Found. */
|
||||
protected void handleNoEndpointFound(WebServiceConnection connection) {
|
||||
HttpServletResponse httpServletResponse = ((HttpServletConnection) connection).getHttpServletResponse();
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.ws.transport.support;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
@@ -27,6 +29,7 @@ import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
import org.springframework.ws.transport.WebServiceMessageReceiver;
|
||||
import org.springframework.ws.transport.context.DefaultTransportContext;
|
||||
import org.springframework.ws.transport.context.TransportContext;
|
||||
@@ -34,30 +37,24 @@ import org.springframework.ws.transport.context.TransportContextHolder;
|
||||
|
||||
/**
|
||||
* Convenience base class for server-side transport objects. Contains a {@link WebServiceMessageFactory}, and has
|
||||
* methods for handling incoming <code>WebServiceMessage</code> requests.
|
||||
* methods for handling incoming {@link WebServiceConnection}s.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see #handle(org.springframework.ws.transport.TransportInputStream,org.springframework.ws.transport.TransportOutputStream,org.springframework.ws.transport.WebServiceMessageReceiver)
|
||||
* @see #handleConnection
|
||||
*/
|
||||
public abstract class WebServiceMessageReceiverObjectSupport implements InitializingBean {
|
||||
|
||||
/**
|
||||
* Logger available to subclasses.
|
||||
*/
|
||||
/** Logger available to subclasses. */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private WebServiceMessageFactory messageFactory;
|
||||
|
||||
/**
|
||||
* Returns the <code>WebServiceMessageFactory</code>.
|
||||
*/
|
||||
/** Returns the <code>WebServiceMessageFactory</code>. */
|
||||
public WebServiceMessageFactory getMessageFactory() {
|
||||
return messageFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>WebServiceMessageFactory</code>.
|
||||
*/
|
||||
/** Sets the <code>WebServiceMessageFactory</code>. */
|
||||
public void setMessageFactory(WebServiceMessageFactory messageFactory) {
|
||||
this.messageFactory = messageFactory;
|
||||
}
|
||||
@@ -67,66 +64,92 @@ public abstract class WebServiceMessageReceiverObjectSupport implements Initiali
|
||||
logger.info("Using message factory [" + messageFactory + "]");
|
||||
}
|
||||
|
||||
protected final void handle(TransportInputStream tis, TransportOutputStream tos, WebServiceMessageReceiver receiver)
|
||||
/**
|
||||
* Handles an incoming connection by reading a message from the connection input stream, passing it to the receiver,
|
||||
* and writing the response (if any) to the output stream.
|
||||
* <p/>
|
||||
* Stores the given connection in the transport context.
|
||||
*
|
||||
* @param connection the incoming connection
|
||||
* @param receiver the handler of the message, typically a {@link org.springframework.ws.server.MessageDispatcher}
|
||||
* @see org.springframework.ws.transport.context.TransportContext
|
||||
*/
|
||||
protected final void handleConnection(WebServiceConnection connection, WebServiceMessageReceiver receiver)
|
||||
throws Exception {
|
||||
TransportContext previousTransportContext = TransportContextHolder.getTransportContext();
|
||||
TransportContextHolder.setTransportContext(new DefaultTransportContext(tis, tos));
|
||||
TransportContextHolder.setTransportContext(new DefaultTransportContext(connection));
|
||||
|
||||
try {
|
||||
WebServiceMessage messageRequest = getMessageFactory().createWebServiceMessage(tis);
|
||||
MessageContext messageContext = new DefaultMessageContext(messageRequest, getMessageFactory());
|
||||
MessageContext messageContext = handleRequest(connection);
|
||||
receiver.receive(messageContext);
|
||||
if (!messageContext.hasResponse()) {
|
||||
handleNoResponse(tis, tos);
|
||||
handleNoResponse(connection);
|
||||
}
|
||||
else {
|
||||
handleResponse(tis, tos, messageContext.getResponse());
|
||||
handleResponse(connection, messageContext.getResponse());
|
||||
}
|
||||
}
|
||||
catch (NoEndpointFoundException ex) {
|
||||
handleNoEndpointFound(tis, tos);
|
||||
handleNoEndpointFound(connection);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
connection.close();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.debug("Could not close connection", ex);
|
||||
}
|
||||
TransportContextHolder.setTransportContext(previousTransportContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked from {@link #handle(org.springframework.ws.transport.TransportInputStream,org.springframework.ws.transport.TransportOutputStream,org.springframework.ws.transport.WebServiceMessageReceiver)}
|
||||
* when no response is given. Default implementation does nothing. Can be overriden to set certain
|
||||
* transport-specific response headers.
|
||||
*
|
||||
* @param tis the transport input stream
|
||||
* @param tos the transport output stream
|
||||
*/
|
||||
protected void handleNoResponse(TransportInputStream tis, TransportOutputStream tos) {
|
||||
private MessageContext handleRequest(WebServiceConnection connection) throws IOException {
|
||||
TransportInputStream tis = connection.getTransportInputStream();
|
||||
try {
|
||||
WebServiceMessage messageRequest = getMessageFactory().createWebServiceMessage(tis);
|
||||
return new DefaultMessageContext(messageRequest, getMessageFactory());
|
||||
}
|
||||
finally {
|
||||
tis.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the sending of the response. Invoked from {@link #handle(org.springframework.ws.transport.TransportInputStream,org.springframework.ws.transport.TransportOutputStream,org.springframework.ws.transport.WebServiceMessageReceiver)}.
|
||||
* Default implementation writes the given response to the given <code>TransportOutputStream</code>. Can be
|
||||
* overriden to set certain transport-specific headers.
|
||||
* Invoked from {@link #handleConnection} when no response is given. Default implementation does nothing. Can be
|
||||
* overriden to set certain transport-specific response headers.
|
||||
*
|
||||
* @param tis the transport input stream
|
||||
* @param tos the transport output stream
|
||||
* @param response the response message
|
||||
* @param connection the incoming connection
|
||||
*/
|
||||
protected void handleNoResponse(WebServiceConnection connection) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the sending of the response. Invoked from {@link #handleConnection}. Default implementation writes the
|
||||
* given response to the given <code>TransportOutputStream</code>. Can be overriden to set certain
|
||||
* transport-specific headers.
|
||||
*
|
||||
* @param connection the incoming connection
|
||||
* @param response the response message
|
||||
* @see WebServiceMessage#writeTo(java.io.OutputStream)
|
||||
*/
|
||||
protected void handleResponse(TransportInputStream tis, TransportOutputStream tos, WebServiceMessage response)
|
||||
throws Exception {
|
||||
response.writeTo(tos);
|
||||
tos.flush();
|
||||
protected void handleResponse(WebServiceConnection connection, WebServiceMessage response) throws Exception {
|
||||
TransportOutputStream tos = connection.getTransportOutputStream();
|
||||
try {
|
||||
response.writeTo(tos);
|
||||
tos.flush();
|
||||
}
|
||||
finally {
|
||||
tos.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked from {@link #handle(org.springframework.ws.transport.TransportInputStream,org.springframework.ws.transport.TransportOutputStream,org.springframework.ws.transport.WebServiceMessageReceiver)}
|
||||
* when no suitable endpoint is found. Default implementation does nothing. Can be overriden to set certain
|
||||
* transport-specific response headers.
|
||||
* Invoked from {@link #handleConnection} when no suitable endpoint is found. Default implementation does nothing.
|
||||
* Can be overriden to set certain transport-specific response headers.
|
||||
*
|
||||
* @param tis the transport input stream
|
||||
* @param tos the transport output stream
|
||||
* @param connection the incoming connection
|
||||
*/
|
||||
protected void handleNoEndpointFound(TransportInputStream tis, TransportOutputStream tos) {
|
||||
protected void handleNoEndpointFound(WebServiceConnection connection) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.StringTokenizer;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.MimeHeader;
|
||||
import javax.xml.soap.MimeHeaders;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
|
||||
/**
|
||||
* A simple Servlet that uses SAAJ to echo request.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class SimpleSaajServlet extends HttpServlet {
|
||||
|
||||
private MessageFactory msgFactory = null;
|
||||
|
||||
public void init(ServletConfig servletConfig) throws ServletException {
|
||||
super.init(servletConfig);
|
||||
try {
|
||||
msgFactory = MessageFactory.newInstance();
|
||||
}
|
||||
catch (SOAPException ex) {
|
||||
throw new ServletException("Unable to create message factory" + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private MimeHeaders getHeaders(HttpServletRequest httpServletRequest) {
|
||||
Enumeration enumeration = httpServletRequest.getHeaderNames();
|
||||
MimeHeaders headers = new MimeHeaders();
|
||||
|
||||
while (enumeration.hasMoreElements()) {
|
||||
String headerName = (String) enumeration.nextElement();
|
||||
String headerValue = httpServletRequest.getHeader(headerName);
|
||||
|
||||
StringTokenizer values = new StringTokenizer(headerValue, ",");
|
||||
|
||||
while (values.hasMoreTokens()) {
|
||||
headers.addHeader(headerName, values.nextToken().trim());
|
||||
}
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
private void putHeaders(MimeHeaders headers, HttpServletResponse res) {
|
||||
Iterator it = headers.getAllHeaders();
|
||||
|
||||
while (it.hasNext()) {
|
||||
MimeHeader header = (MimeHeader) it.next();
|
||||
|
||||
String[] values = headers.getHeader(header.getName());
|
||||
|
||||
if (values.length == 1) {
|
||||
res.setHeader(header.getName(), header.getValue());
|
||||
}
|
||||
else {
|
||||
StringBuffer concat = new StringBuffer();
|
||||
int i = 0;
|
||||
|
||||
while (i < values.length) {
|
||||
if (i != 0) {
|
||||
concat.append(',');
|
||||
}
|
||||
concat.append(values[i++]);
|
||||
}
|
||||
res.setHeader(header.getName(), concat.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
try {
|
||||
MimeHeaders headers = getHeaders(req);
|
||||
SOAPMessage msg = msgFactory.createMessage(headers, req.getInputStream());
|
||||
SOAPMessage reply = onMessage(msg);
|
||||
resp.setStatus(HttpServletResponse.SC_OK);
|
||||
if (reply != null) {
|
||||
if (reply.saveRequired()) {
|
||||
reply.saveChanges();
|
||||
}
|
||||
resp.setStatus(HttpServletResponse.SC_OK);
|
||||
putHeaders(reply.getMimeHeaders(), resp);
|
||||
reply.writeTo(resp.getOutputStream());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new ServletException("SAAJ POST failed " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public SOAPMessage onMessage(SOAPMessage message) {
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.core;
|
||||
|
||||
import java.net.URL;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
|
||||
import org.custommonkey.xmlunit.XMLTestCase;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.Context;
|
||||
import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
|
||||
import org.springframework.ws.transport.http.HttpUrlConnectionMessageSender;
|
||||
import org.springframework.xml.transform.StringResult;
|
||||
import org.springframework.xml.transform.StringSource;
|
||||
|
||||
public class WebServiceTemplateIntegrationTest extends XMLTestCase {
|
||||
|
||||
private WebServiceTemplate template;
|
||||
|
||||
private Server jettyServer;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jettyServer = new Server(8085);
|
||||
Context jettyContext = new Context(jettyServer, "/");
|
||||
jettyContext.addServlet(SimpleSaajServlet.class, "/");
|
||||
jettyServer.start();
|
||||
template = new WebServiceTemplate();
|
||||
HttpUrlConnectionMessageSender messageSender = new HttpUrlConnectionMessageSender();
|
||||
messageSender.setUrl(new URL("http://localhost:8085/"));
|
||||
template.setMessageSender(messageSender);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jettyServer.stop();
|
||||
}
|
||||
|
||||
public void testSendAndReceiveSaaj() throws Exception {
|
||||
template.setMessageFactory(new SaajSoapMessageFactory(MessageFactory.newInstance()));
|
||||
String content = "<root xmlns='http://springframework.org/spring-ws'><child/></root>";
|
||||
StringResult result = new StringResult();
|
||||
template.sendAndReceive(new StringSource(content), result);
|
||||
assertXMLEqual(content, result.toString());
|
||||
}
|
||||
|
||||
public void testSendAndReceiveAxiom() throws Exception {
|
||||
template.setMessageFactory(new AxiomSoapMessageFactory());
|
||||
String content = "<root xmlns='http://springframework.org/spring-ws'><child/></root>";
|
||||
StringResult result = new StringResult();
|
||||
template.sendAndReceive(new StringSource(content), result);
|
||||
assertXMLEqual(content, result.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,17 +16,20 @@
|
||||
|
||||
package org.springframework.ws.client.core;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.custommonkey.xmlunit.XMLTestCase;
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.ws.MockWebServiceMessageFactory;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
|
||||
import org.springframework.ws.transport.MockTransportInputStream;
|
||||
import org.springframework.ws.transport.MockTransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
import org.springframework.ws.transport.WebServiceMessageSender;
|
||||
import org.springframework.xml.transform.StringResult;
|
||||
@@ -34,38 +37,29 @@ import org.springframework.xml.transform.StringSource;
|
||||
|
||||
public class WebServiceTemplateTest extends XMLTestCase {
|
||||
|
||||
private static final WebServiceMessageExtractor SIMPLE_EXTRACTOR = new WebServiceMessageExtractor() {
|
||||
|
||||
public Object extractData(WebServiceMessage message) throws IOException {
|
||||
return message;
|
||||
}
|
||||
};
|
||||
|
||||
private WebServiceTemplate template;
|
||||
|
||||
private MockControl factoryControl;
|
||||
private MockControl connectionControl;
|
||||
|
||||
private WebServiceMessageFactory factoryMock;
|
||||
|
||||
private MockControl messageControl;
|
||||
|
||||
private WebServiceMessage requestMock;
|
||||
|
||||
private WebServiceMessage responseMock;
|
||||
private FaultAwareWebServiceConnection connectionMock;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
template = new WebServiceTemplate();
|
||||
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();
|
||||
MockWebServiceMessageFactory messageFactory = new MockWebServiceMessageFactory();
|
||||
template.setMessageFactory(messageFactory);
|
||||
connectionControl = MockControl.createStrictControl(FaultAwareWebServiceConnection.class);
|
||||
connectionMock = (FaultAwareWebServiceConnection) connectionControl.getMock();
|
||||
template.setMessageSender(new WebServiceMessageSender() {
|
||||
|
||||
public WebServiceConnection createConnection() throws IOException {
|
||||
return connectionMock;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void testMarshalAndSendNoMarshallerSet() throws Exception {
|
||||
template.setMarshaller(null);
|
||||
replayMockControls();
|
||||
try {
|
||||
template.marshalSendAndReceive(new Object());
|
||||
fail("IllegalStateException expected");
|
||||
@@ -73,12 +67,10 @@ public class WebServiceTemplateTest extends XMLTestCase {
|
||||
catch (IllegalStateException ex) {
|
||||
// expected behavior
|
||||
}
|
||||
verifyMockControls();
|
||||
}
|
||||
|
||||
public void testMarshalAndSendNoUnmarshallerSet() throws Exception {
|
||||
template.setUnmarshaller(null);
|
||||
replayMockControls();
|
||||
try {
|
||||
template.marshalSendAndReceive(new Object());
|
||||
fail("IllegalStateException expected");
|
||||
@@ -86,209 +78,213 @@ public class WebServiceTemplateTest extends XMLTestCase {
|
||||
catch (IllegalStateException ex) {
|
||||
// expected behavior
|
||||
}
|
||||
verifyMockControls();
|
||||
}
|
||||
|
||||
public void testSendAndReceiveMessageResponse() throws Exception {
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), requestMock);
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), responseMock);
|
||||
messageControl.expectAndReturn(responseMock.hasFault(), false);
|
||||
template.setMessageSender(new ResponseMessageSender());
|
||||
replayMockControls();
|
||||
WebServiceMessage response = (WebServiceMessage) template.sendAndReceive(new WebServiceMessageCallback() {
|
||||
public void doInMessage(WebServiceMessage message) throws IOException {
|
||||
assertEquals("Invalid request message", requestMock, message);
|
||||
}
|
||||
}, SIMPLE_EXTRACTOR);
|
||||
assertEquals("Invalid response", responseMock, response);
|
||||
verifyMockControls();
|
||||
MockControl callbackControl = MockControl.createControl(WebServiceMessageCallback.class);
|
||||
WebServiceMessageCallback requestCallback = (WebServiceMessageCallback) callbackControl.getMock();
|
||||
requestCallback.doInMessage(null);
|
||||
callbackControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
callbackControl.replay();
|
||||
|
||||
MockControl extractorControl = MockControl.createControl(WebServiceMessageExtractor.class);
|
||||
WebServiceMessageExtractor extractorMock = (WebServiceMessageExtractor) extractorControl.getMock();
|
||||
extractorMock.extractData(null);
|
||||
extractorControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
Object extracted = new Object();
|
||||
extractorControl.setReturnValue(extracted);
|
||||
extractorControl.replay();
|
||||
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportOutputStream(),
|
||||
new MockTransportOutputStream(new ByteArrayOutputStream()));
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportInputStream(), new MockTransportInputStream(
|
||||
new ByteArrayInputStream("<response/>".getBytes("UTF-8")), Collections.EMPTY_MAP));
|
||||
connectionControl.expectAndReturn(connectionMock.hasFault(), false);
|
||||
connectionMock.close();
|
||||
connectionControl.replay();
|
||||
|
||||
Object result = template.sendAndReceive(requestCallback, extractorMock);
|
||||
assertEquals("Invalid response", extracted, result);
|
||||
|
||||
callbackControl.verify();
|
||||
extractorControl.verify();
|
||||
connectionControl.verify();
|
||||
|
||||
}
|
||||
|
||||
public void testSendAndReceiveMessageNoResponse() throws Exception {
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), requestMock);
|
||||
template.setMessageSender(new NoResponseMessageSender());
|
||||
replayMockControls();
|
||||
WebServiceMessage response = (WebServiceMessage) template.sendAndReceive(new WebServiceMessageCallback() {
|
||||
public void doInMessage(WebServiceMessage message) throws IOException {
|
||||
assertEquals("Invalid request message", requestMock, message);
|
||||
}
|
||||
}, SIMPLE_EXTRACTOR);
|
||||
assertNull("No response", response);
|
||||
verifyMockControls();
|
||||
MockControl callbackControl = MockControl.createControl(WebServiceMessageCallback.class);
|
||||
WebServiceMessageCallback requestCallback = (WebServiceMessageCallback) callbackControl.getMock();
|
||||
requestCallback.doInMessage(null);
|
||||
callbackControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
callbackControl.replay();
|
||||
|
||||
MockControl extractorControl = MockControl.createControl(WebServiceMessageExtractor.class);
|
||||
WebServiceMessageExtractor extractorMock = (WebServiceMessageExtractor) extractorControl.getMock();
|
||||
extractorControl.replay();
|
||||
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportOutputStream(),
|
||||
new MockTransportOutputStream(new ByteArrayOutputStream()));
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportInputStream(), null);
|
||||
connectionMock.close();
|
||||
connectionControl.replay();
|
||||
|
||||
Object result = (WebServiceMessage) template.sendAndReceive(requestCallback, extractorMock);
|
||||
assertNull("Invalid response", result);
|
||||
callbackControl.verify();
|
||||
extractorControl.verify();
|
||||
connectionControl.verify();
|
||||
}
|
||||
|
||||
public void testSendAndReceiveMessageFaultResponse() throws Exception {
|
||||
MockControl resolverControl = MockControl.createControl(FaultResolver.class);
|
||||
FaultResolver resolverMock = (FaultResolver) resolverControl.getMock();
|
||||
template.setFaultResolver(resolverMock);
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), requestMock);
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), responseMock);
|
||||
messageControl.expectAndReturn(responseMock.hasFault(), true);
|
||||
resolverMock.resolveFault(responseMock);
|
||||
template.setMessageSender(new ResponseMessageSender());
|
||||
replayMockControls();
|
||||
resolverControl.replay();
|
||||
WebServiceMessage response = (WebServiceMessage) template.sendAndReceive(new WebServiceMessageCallback() {
|
||||
public void doInMessage(WebServiceMessage message) throws IOException {
|
||||
assertEquals("Invalid request message", requestMock, message);
|
||||
}
|
||||
}, SIMPLE_EXTRACTOR);
|
||||
assertNull("Invalid response", response);
|
||||
verifyMockControls();
|
||||
resolverControl.verify();
|
||||
public void testSendAndReceiveMessageFault() throws Exception {
|
||||
MockControl callbackControl = MockControl.createControl(WebServiceMessageCallback.class);
|
||||
WebServiceMessageCallback requestCallback = (WebServiceMessageCallback) callbackControl.getMock();
|
||||
requestCallback.doInMessage(null);
|
||||
callbackControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
callbackControl.replay();
|
||||
|
||||
MockControl extractorControl = MockControl.createControl(WebServiceMessageExtractor.class);
|
||||
WebServiceMessageExtractor extractorMock = (WebServiceMessageExtractor) extractorControl.getMock();
|
||||
extractorControl.replay();
|
||||
|
||||
MockControl faultResolverControl = MockControl.createControl(FaultResolver.class);
|
||||
FaultResolver faultResolverMock = (FaultResolver) faultResolverControl.getMock();
|
||||
template.setFaultResolver(faultResolverMock);
|
||||
faultResolverMock.resolveFault(null);
|
||||
faultResolverControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
faultResolverControl.replay();
|
||||
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportOutputStream(),
|
||||
new MockTransportOutputStream(new ByteArrayOutputStream()));
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportInputStream(), new MockTransportInputStream(
|
||||
new ByteArrayInputStream("<response/>".getBytes("UTF-8")), Collections.EMPTY_MAP));
|
||||
connectionControl.expectAndReturn(connectionMock.hasFault(), true);
|
||||
connectionMock.close();
|
||||
connectionControl.replay();
|
||||
|
||||
Object result = template.sendAndReceive(requestCallback, extractorMock);
|
||||
assertNull("Invalid response", result);
|
||||
|
||||
callbackControl.verify();
|
||||
extractorControl.verify();
|
||||
connectionControl.verify();
|
||||
}
|
||||
|
||||
public void testSendAndReceiveSourceExtractor() throws Exception {
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), requestMock);
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), responseMock);
|
||||
messageControl.expectAndReturn(responseMock.hasFault(), false);
|
||||
messageControl.expectAndReturn(requestMock.getPayloadResult(), new StringResult());
|
||||
final Source expected = new StringSource("<response/>");
|
||||
messageControl.expectAndReturn(responseMock.getPayloadSource(), expected);
|
||||
template.setMessageSender(new ResponseMessageSender());
|
||||
replayMockControls();
|
||||
Object result = template.sendAndReceive(new StringSource("<request />"), new SourceExtractor() {
|
||||
public void testSendAndReceiveSourceResponse() throws Exception {
|
||||
MockControl extractorControl = MockControl.createControl(SourceExtractor.class);
|
||||
SourceExtractor extractorMock = (SourceExtractor) extractorControl.getMock();
|
||||
extractorMock.extractData(null);
|
||||
extractorControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
Object extracted = new Object();
|
||||
extractorControl.setReturnValue(extracted);
|
||||
extractorControl.replay();
|
||||
|
||||
public Object extractData(Source source) throws IOException {
|
||||
assertEquals("Invalid response", expected, source);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
assertNull("Invalid result", result);
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportOutputStream(),
|
||||
new MockTransportOutputStream(new ByteArrayOutputStream()));
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportInputStream(), new MockTransportInputStream(
|
||||
new ByteArrayInputStream("<response/>".getBytes("UTF-8")), Collections.EMPTY_MAP));
|
||||
connectionControl.expectAndReturn(connectionMock.hasFault(), false);
|
||||
connectionMock.close();
|
||||
connectionControl.replay();
|
||||
|
||||
Object result = template.sendAndReceive(new StringSource("<request />"), extractorMock);
|
||||
assertEquals("Invalid response", extracted, result);
|
||||
|
||||
extractorControl.verify();
|
||||
connectionControl.verify();
|
||||
}
|
||||
|
||||
public void testSendAndReceiveSourceNoResponse() throws Exception {
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), requestMock);
|
||||
messageControl.expectAndReturn(requestMock.getPayloadResult(), new StringResult());
|
||||
template.setMessageSender(new NoResponseMessageSender());
|
||||
replayMockControls();
|
||||
Object result = template.sendAndReceive(new StringSource("<request />"), new SourceExtractor() {
|
||||
MockControl extractorControl = MockControl.createControl(SourceExtractor.class);
|
||||
SourceExtractor extractorMock = (SourceExtractor) extractorControl.getMock();
|
||||
extractorControl.replay();
|
||||
|
||||
public Object extractData(Source source) throws IOException {
|
||||
assertNull("Invalid response", source);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
assertNull("Invalid result", result);
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportOutputStream(),
|
||||
new MockTransportOutputStream(new ByteArrayOutputStream()));
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportInputStream(), null);
|
||||
connectionMock.close();
|
||||
connectionControl.replay();
|
||||
|
||||
Object result = template.sendAndReceive(new StringSource("<request />"), extractorMock);
|
||||
assertNull("Invalid response", result);
|
||||
|
||||
extractorControl.verify();
|
||||
connectionControl.verify();
|
||||
}
|
||||
|
||||
public void testSendAndReceiveResultResponse() throws Exception {
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), requestMock);
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), responseMock);
|
||||
messageControl.expectAndReturn(responseMock.hasFault(), false);
|
||||
messageControl.expectAndReturn(requestMock.getPayloadResult(), new StringResult());
|
||||
Source expected = new StringSource("<response/>");
|
||||
messageControl.expectAndReturn(responseMock.getPayloadSource(), expected);
|
||||
template.setMessageSender(new ResponseMessageSender());
|
||||
replayMockControls();
|
||||
Result result = new StringResult();
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportOutputStream(),
|
||||
new MockTransportOutputStream(new ByteArrayOutputStream()));
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportInputStream(), new MockTransportInputStream(
|
||||
new ByteArrayInputStream("<response/>".getBytes("UTF-8")), Collections.EMPTY_MAP));
|
||||
connectionControl.expectAndReturn(connectionMock.hasFault(), false);
|
||||
connectionMock.close();
|
||||
connectionControl.replay();
|
||||
|
||||
StringResult result = new StringResult();
|
||||
template.sendAndReceive(new StringSource("<request />"), result);
|
||||
assertXMLEqual("Invalid response", "<response/>", result.toString());
|
||||
|
||||
connectionControl.verify();
|
||||
}
|
||||
|
||||
public void testSendAndReceiveMarshallResponse() throws Exception {
|
||||
template.setMessageSender(new ResponseMessageSender());
|
||||
public void testSendAndReceiveMarshalResponse() throws Exception {
|
||||
MockControl marshallerControl = MockControl.createControl(Marshaller.class);
|
||||
Marshaller marshallerMock = (Marshaller) marshallerControl.getMock();
|
||||
template.setMarshaller(marshallerMock);
|
||||
marshallerMock.marshal(null, null);
|
||||
marshallerControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
marshallerControl.replay();
|
||||
|
||||
MockControl unmarshallerControl = MockControl.createControl(Unmarshaller.class);
|
||||
Unmarshaller unmarshallerMock = (Unmarshaller) unmarshallerControl.getMock();
|
||||
template.setUnmarshaller(unmarshallerMock);
|
||||
Object request = new Object();
|
||||
Object expected = new Object();
|
||||
Result requestResult = new StringResult();
|
||||
Source responseSource = new StringSource("");
|
||||
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), requestMock);
|
||||
messageControl.expectAndReturn(requestMock.getPayloadResult(), requestResult);
|
||||
marshallerMock.marshal(request, requestResult);
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), responseMock);
|
||||
messageControl.expectAndReturn(responseMock.hasFault(), false);
|
||||
messageControl.expectAndReturn(responseMock.getPayloadSource(), responseSource);
|
||||
unmarshallerControl.expectAndReturn(unmarshallerMock.unmarshal(responseSource), expected);
|
||||
|
||||
replayMockControls();
|
||||
marshallerControl.replay();
|
||||
unmarshallerMock.unmarshal(null);
|
||||
unmarshallerControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
Object unmarshalled = new Object();
|
||||
unmarshallerControl.setReturnValue(unmarshalled);
|
||||
unmarshallerControl.replay();
|
||||
|
||||
Object response = template.marshalSendAndReceive(request);
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportOutputStream(),
|
||||
new MockTransportOutputStream(new ByteArrayOutputStream()));
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportInputStream(), new MockTransportInputStream(
|
||||
new ByteArrayInputStream("<response/>".getBytes("UTF-8")), Collections.EMPTY_MAP));
|
||||
connectionControl.expectAndReturn(connectionMock.hasFault(), false);
|
||||
connectionMock.close();
|
||||
connectionControl.replay();
|
||||
|
||||
assertEquals("Invalid response", expected, response);
|
||||
Object result = template.marshalSendAndReceive(new Object());
|
||||
assertEquals("Invalid result", unmarshalled, result);
|
||||
|
||||
verifyMockControls();
|
||||
connectionControl.verify();
|
||||
marshallerControl.verify();
|
||||
unmarshallerControl.verify();
|
||||
}
|
||||
|
||||
public void testSendAndReceiveMarshallNoResponse() throws Exception {
|
||||
template.setMessageSender(new NoResponseMessageSender());
|
||||
public void testSendAndReceiveMarshalNoResponse() throws Exception {
|
||||
MockControl marshallerControl = MockControl.createControl(Marshaller.class);
|
||||
Marshaller marshallerMock = (Marshaller) marshallerControl.getMock();
|
||||
template.setMarshaller(marshallerMock);
|
||||
marshallerMock.marshal(null, null);
|
||||
marshallerControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
marshallerControl.replay();
|
||||
|
||||
MockControl unmarshallerControl = MockControl.createControl(Unmarshaller.class);
|
||||
Unmarshaller unmarshallerMock = (Unmarshaller) unmarshallerControl.getMock();
|
||||
template.setUnmarshaller(unmarshallerMock);
|
||||
Object request = new Object();
|
||||
Result requestResult = new StringResult();
|
||||
unmarshallerControl.replay();
|
||||
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), requestMock);
|
||||
messageControl.expectAndReturn(requestMock.getPayloadResult(), requestResult);
|
||||
marshallerMock.marshal(request, requestResult);
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportOutputStream(),
|
||||
new MockTransportOutputStream(new ByteArrayOutputStream()));
|
||||
connectionControl.expectAndReturn(connectionMock.getTransportInputStream(), null);
|
||||
connectionMock.close();
|
||||
connectionControl.replay();
|
||||
|
||||
replayMockControls();
|
||||
marshallerControl.replay();
|
||||
Object result = template.marshalSendAndReceive(new Object());
|
||||
assertNull("Invalid result", result);
|
||||
|
||||
Object response = template.marshalSendAndReceive(request);
|
||||
|
||||
assertNull("Invalid response", response);
|
||||
|
||||
verifyMockControls();
|
||||
connectionControl.verify();
|
||||
marshallerControl.verify();
|
||||
}
|
||||
|
||||
private void replayMockControls() {
|
||||
factoryControl.replay();
|
||||
messageControl.replay();
|
||||
}
|
||||
|
||||
private void verifyMockControls() {
|
||||
factoryControl.verify();
|
||||
messageControl.verify();
|
||||
}
|
||||
|
||||
private class NoResponseMessageSender implements WebServiceMessageSender {
|
||||
|
||||
public WebServiceConnection createConnection() throws IOException {
|
||||
return new NoResponseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
private class NoResponseConnection implements WebServiceConnection {
|
||||
|
||||
public void sendAndReceive(MessageContext messageContext) throws IOException {
|
||||
assertEquals("Invalid request message", requestMock, messageContext.getRequest());
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
}
|
||||
}
|
||||
|
||||
private class ResponseMessageSender implements WebServiceMessageSender {
|
||||
|
||||
public WebServiceConnection createConnection() throws IOException {
|
||||
return new ResponseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
private class ResponseConnection implements WebServiceConnection {
|
||||
|
||||
public void sendAndReceive(MessageContext messageContext) throws IOException {
|
||||
assertEquals("Invalid request message", requestMock, messageContext.getRequest());
|
||||
messageContext.getResponse();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
}
|
||||
unmarshallerControl.verify();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import org.springframework.ws.soap.AbstractSoapMessageFactoryTestCase;
|
||||
import org.springframework.ws.soap.Attachment;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.SoapVersion;
|
||||
import org.springframework.ws.transport.StubTransportInputStream;
|
||||
import org.springframework.ws.transport.MockTransportInputStream;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
|
||||
public abstract class AbstractSoap11MessageFactoryTestCase extends AbstractSoapMessageFactoryTestCase {
|
||||
@@ -42,7 +42,7 @@ public abstract class AbstractSoap11MessageFactoryTestCase extends AbstractSoapM
|
||||
headers.setProperty("Content-Type", "text/xml");
|
||||
String soapAction = "http://springframework.org/spring-ws/Action";
|
||||
headers.setProperty("SOAPAction", soapAction);
|
||||
TransportInputStream tis = new StubTransportInputStream(is, headers);
|
||||
TransportInputStream tis = new MockTransportInputStream(is, headers);
|
||||
|
||||
WebServiceMessage message = messageFactory.createWebServiceMessage(tis);
|
||||
assertTrue("Not a SoapMessage", message instanceof SoapMessage);
|
||||
@@ -56,7 +56,7 @@ public abstract class AbstractSoap11MessageFactoryTestCase extends AbstractSoapM
|
||||
Properties headers = new Properties();
|
||||
headers.setProperty("Content-Type",
|
||||
"multipart/related; type=\"text/xml\"; boundary=\"----=_Part_0_11416420.1149699787554\"");
|
||||
TransportInputStream tis = new StubTransportInputStream(is, headers);
|
||||
TransportInputStream tis = new MockTransportInputStream(is, headers);
|
||||
|
||||
WebServiceMessage message = messageFactory.createWebServiceMessage(tis);
|
||||
assertTrue("Not a SoapMessage", message instanceof SoapMessage);
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.core.io.InputStreamSource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.ws.soap.AbstractSoapMessageTestCase;
|
||||
import org.springframework.ws.soap.SoapVersion;
|
||||
import org.springframework.ws.transport.StubTransportOutputStream;
|
||||
import org.springframework.ws.transport.MockTransportOutputStream;
|
||||
|
||||
public abstract class AbstractSoap11MessageTestCase extends AbstractSoapMessageTestCase {
|
||||
|
||||
@@ -46,7 +46,7 @@ public abstract class AbstractSoap11MessageTestCase extends AbstractSoapMessageT
|
||||
|
||||
public void testWriteToTransportOutputStream() throws Exception {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
StubTransportOutputStream tos = new StubTransportOutputStream(bos);
|
||||
MockTransportOutputStream tos = new MockTransportOutputStream(bos);
|
||||
String soapAction = "http://springframework.org/spring-ws/Action";
|
||||
soapMessage.setSoapAction(soapAction);
|
||||
soapMessage.writeTo(tos);
|
||||
@@ -63,7 +63,7 @@ public abstract class AbstractSoap11MessageTestCase extends AbstractSoapMessageT
|
||||
InputStreamSource inputStreamSource = new ByteArrayResource("contents".getBytes("UTF-8"));
|
||||
soapMessage.addAttachment(inputStreamSource, "text/plain");
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
StubTransportOutputStream tos = new StubTransportOutputStream(bos);
|
||||
MockTransportOutputStream tos = new MockTransportOutputStream(bos);
|
||||
soapMessage.writeTo(tos);
|
||||
String contentType = (String) tos.getHeaders().get("Content-Type");
|
||||
assertTrue("Invalid Content-Type set", contentType.indexOf(SoapVersion.SOAP_11.getContentType()) != -1);
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.springframework.ws.soap.AbstractSoapMessageFactoryTestCase;
|
||||
import org.springframework.ws.soap.Attachment;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.SoapVersion;
|
||||
import org.springframework.ws.transport.StubTransportInputStream;
|
||||
import org.springframework.ws.transport.MockTransportInputStream;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
|
||||
public abstract class AbstractSoap12MessageFactoryTestCase extends AbstractSoapMessageFactoryTestCase {
|
||||
@@ -40,7 +40,7 @@ public abstract class AbstractSoap12MessageFactoryTestCase extends AbstractSoapM
|
||||
InputStream is = AbstractSoap12MessageFactoryTestCase.class.getResourceAsStream("soap12.xml");
|
||||
final Properties headers = new Properties();
|
||||
headers.setProperty("Content-Type", "application/soap+xml");
|
||||
TransportInputStream tis = new StubTransportInputStream(is, headers);
|
||||
TransportInputStream tis = new MockTransportInputStream(is, headers);
|
||||
|
||||
WebServiceMessage message = messageFactory.createWebServiceMessage(tis);
|
||||
assertTrue("Not a SoapMessage", message instanceof SoapMessage);
|
||||
@@ -53,7 +53,7 @@ public abstract class AbstractSoap12MessageFactoryTestCase extends AbstractSoapM
|
||||
Properties headers = new Properties();
|
||||
headers.setProperty("Content-Type",
|
||||
"multipart/related; type=\"application/soap+xml\"; boundary=\"----=_Part_0_11416420.1149699787554\"");
|
||||
TransportInputStream tis = new StubTransportInputStream(is, headers);
|
||||
TransportInputStream tis = new MockTransportInputStream(is, headers);
|
||||
|
||||
WebServiceMessage message = messageFactory.createWebServiceMessage(tis);
|
||||
assertTrue("Not a SoapMessage", message instanceof SoapMessage);
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.core.io.InputStreamSource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.ws.soap.AbstractSoapMessageTestCase;
|
||||
import org.springframework.ws.soap.SoapVersion;
|
||||
import org.springframework.ws.transport.StubTransportOutputStream;
|
||||
import org.springframework.ws.transport.MockTransportOutputStream;
|
||||
|
||||
public abstract class AbstractSoap12MessageTestCase extends AbstractSoapMessageTestCase {
|
||||
|
||||
@@ -47,7 +47,7 @@ public abstract class AbstractSoap12MessageTestCase extends AbstractSoapMessageT
|
||||
|
||||
public void testWriteToTransportResponse() throws Exception {
|
||||
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
StubTransportOutputStream tos = new StubTransportOutputStream(bos);
|
||||
MockTransportOutputStream tos = new MockTransportOutputStream(bos);
|
||||
soapMessage.writeTo(tos);
|
||||
String result = bos.toString("UTF-8");
|
||||
|
||||
@@ -60,7 +60,7 @@ public abstract class AbstractSoap12MessageTestCase extends AbstractSoapMessageT
|
||||
InputStreamSource inputStreamSource = new ByteArrayResource("contents".getBytes("UTF-8"));
|
||||
soapMessage.addAttachment(inputStreamSource, "text/plain");
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
StubTransportOutputStream tos = new StubTransportOutputStream(bos);
|
||||
MockTransportOutputStream tos = new MockTransportOutputStream(bos);
|
||||
soapMessage.writeTo(tos);
|
||||
String contentType = (String) tos.getHeaders().get("Content-Type");
|
||||
assertTrue("Invalid Content-Type set", contentType.indexOf(SoapVersion.SOAP_12.getContentType()) != -1);
|
||||
|
||||
@@ -24,13 +24,13 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class StubTransportInputStream extends TransportInputStream {
|
||||
public class MockTransportInputStream extends TransportInputStream {
|
||||
|
||||
private Map headers;
|
||||
|
||||
private InputStream inputStream;
|
||||
|
||||
public StubTransportInputStream(InputStream inputStream, Map headers) {
|
||||
public MockTransportInputStream(InputStream inputStream, Map headers) {
|
||||
Assert.notNull(inputStream, "inputStream must not be null");
|
||||
Assert.notNull(headers, "headers must not be null");
|
||||
this.inputStream = inputStream;
|
||||
@@ -23,13 +23,13 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class StubTransportOutputStream extends TransportOutputStream {
|
||||
public class MockTransportOutputStream extends TransportOutputStream {
|
||||
|
||||
private Map headers = new HashMap();
|
||||
|
||||
private OutputStream outputStream;
|
||||
|
||||
public StubTransportOutputStream(OutputStream outputStream) {
|
||||
public MockTransportOutputStream(OutputStream outputStream) {
|
||||
Assert.notNull(outputStream, "outputStream must not be null");
|
||||
this.outputStream = outputStream;
|
||||
}
|
||||
@@ -16,22 +16,16 @@
|
||||
|
||||
package org.springframework.ws.transport.http;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Iterator;
|
||||
import javax.servlet.GenericServlet;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.custommonkey.xmlunit.XMLTestCase;
|
||||
import org.custommonkey.xmlunit.XMLUnit;
|
||||
@@ -39,13 +33,10 @@ import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.Context;
|
||||
import org.mortbay.jetty.servlet.ServletHolder;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
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;
|
||||
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
import org.springframework.ws.transport.WebServiceConnection;
|
||||
import org.springframework.xml.transform.StringResult;
|
||||
import org.springframework.xml.transform.StringSource;
|
||||
|
||||
public abstract class AbstractHttpWebServiceMessageSenderTestCase extends XMLTestCase {
|
||||
|
||||
@@ -59,34 +50,17 @@ public abstract class AbstractHttpWebServiceMessageSenderTestCase extends XMLTes
|
||||
|
||||
private static final String RESPONSE_HEADER_VALUE = "ResponseHeaderValue";
|
||||
|
||||
protected static final String URL = "http://localhost:8888";
|
||||
protected static final String REQUEST = "Request";
|
||||
|
||||
protected static final String REQUEST = "<Request xmlns='http://springframework.org/spring-ws'/>";
|
||||
|
||||
protected static final String EXPECTED_SOAP_REQUEST =
|
||||
"<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>" + "<SOAP-ENV:Header/>" +
|
||||
"<SOAP-ENV:Body>" + REQUEST + "</SOAP-ENV:Body>" + "</SOAP-ENV:Envelope>";
|
||||
|
||||
protected static final String RESPONSE = "<Response xmlns='http://springframework.org/spring-ws'/>";
|
||||
|
||||
protected Transformer transformer;
|
||||
protected static final String RESPONSE = "Response";
|
||||
|
||||
protected AbstractHttpWebServiceMessageSender messageSender;
|
||||
|
||||
private MessageFactory messageFactory;
|
||||
|
||||
private String receivedRequest;
|
||||
|
||||
private String receivedHeader;
|
||||
private Context jettyContext;
|
||||
|
||||
protected final void setUp() throws Exception {
|
||||
messageFactory = MessageFactory.newInstance();
|
||||
transformer = TransformerFactory.newInstance().newTransformer();
|
||||
jettyServer = new Server(8888);
|
||||
Context root = new Context(jettyServer, "/");
|
||||
root.addServlet(new ServletHolder(new ResponseServlet()), "/response");
|
||||
root.addServlet(new ServletHolder(new NoResponseServlet()), "/noresponse");
|
||||
jettyServer.start();
|
||||
jettyServer = new Server(8085);
|
||||
jettyContext = new Context(jettyServer, "/");
|
||||
messageSender = createMessageSender();
|
||||
XMLUnit.setIgnoreWhitespace(true);
|
||||
}
|
||||
@@ -94,31 +68,64 @@ public abstract class AbstractHttpWebServiceMessageSenderTestCase extends XMLTes
|
||||
protected abstract AbstractHttpWebServiceMessageSender createMessageSender();
|
||||
|
||||
protected final void tearDown() throws Exception {
|
||||
jettyServer.stop();
|
||||
if (jettyServer.isRunning()) {
|
||||
jettyServer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void testSendAndReceiveResponse() throws Exception {
|
||||
messageSender.setUrl(new URL("http://localhost:8888/response"));
|
||||
SOAPMessage saajRequest = messageFactory.createMessage();
|
||||
saajRequest.getMimeHeaders().addHeader(REQUEST_HEADER_NAME, REQUEST_HEADER_VALUE);
|
||||
transformer.transform(new StringSource(REQUEST), new DOMResult(saajRequest.getSOAPBody()));
|
||||
SaajSoapMessage request = new SaajSoapMessage(saajRequest);
|
||||
MessageContext context = new DefaultMessageContext(request, new SaajSoapMessageFactory(messageFactory));
|
||||
WebServiceConnection connection = messageSender.createConnection();
|
||||
validateResponse(new MyServlet(true));
|
||||
}
|
||||
|
||||
public void testSendAndReceiveResponseInvalidContentLength() throws Exception {
|
||||
validateResponse(new MyServlet(true, HttpServletResponse.SC_OK, false));
|
||||
}
|
||||
|
||||
public void testSendAndReceiveFault() throws Exception {
|
||||
jettyContext
|
||||
.addServlet(new ServletHolder(new MyServlet(true, HttpServletResponse.SC_INTERNAL_SERVER_ERROR)), "/");
|
||||
jettyServer.start();
|
||||
messageSender.setUrl(new URL("http://localhost:8085/"));
|
||||
FaultAwareWebServiceConnection connection = (FaultAwareWebServiceConnection) messageSender.createConnection();
|
||||
try {
|
||||
connection.sendAndReceive(context);
|
||||
assertXMLEqual(EXPECTED_SOAP_REQUEST, receivedRequest.toString());
|
||||
assertEquals("Invalid header value received on server side", REQUEST_HEADER_VALUE, receivedHeader);
|
||||
assertTrue("No response", context.hasResponse());
|
||||
SaajSoapMessage response = (SaajSoapMessage) context.getResponse();
|
||||
SOAPMessage saajResponse = response.getSaajMessage();
|
||||
assertNotNull("No header value received on client side",
|
||||
saajResponse.getMimeHeaders().getHeader(RESPONSE_HEADER_NAME));
|
||||
assertEquals("Invalid header value received on client side", RESPONSE_HEADER_VALUE,
|
||||
saajResponse.getMimeHeaders().getHeader(RESPONSE_HEADER_NAME)[0]);
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
response.writeTo(os);
|
||||
assertXMLEqual(RESPONSE, os.toString("UTF-8"));
|
||||
TransportOutputStream tos = connection.getTransportOutputStream();
|
||||
tos.addHeader("Content-Type", "text/xml");
|
||||
tos.addHeader(REQUEST_HEADER_NAME, REQUEST_HEADER_VALUE);
|
||||
FileCopyUtils.copy(REQUEST.getBytes("UTF-8"), tos);
|
||||
assertNotNull("No response", connection.getTransportInputStream());
|
||||
assertTrue("Response has no fault", connection.hasFault());
|
||||
}
|
||||
finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void validateResponse(Servlet servlet) throws Exception {
|
||||
jettyContext.addServlet(new ServletHolder(servlet), "/");
|
||||
jettyServer.start();
|
||||
messageSender.setUrl(new URL("http://localhost:8085/"));
|
||||
FaultAwareWebServiceConnection connection = (FaultAwareWebServiceConnection) messageSender.createConnection();
|
||||
try {
|
||||
TransportOutputStream tos = connection.getTransportOutputStream();
|
||||
tos.addHeader("Content-Type", "text/xml");
|
||||
tos.addHeader(REQUEST_HEADER_NAME, REQUEST_HEADER_VALUE);
|
||||
FileCopyUtils.copy(REQUEST.getBytes("UTF-8"), tos);
|
||||
assertNotNull("No response", connection.getTransportInputStream());
|
||||
assertFalse("Response has fault", connection.hasFault());
|
||||
TransportInputStream tis = connection.getTransportInputStream();
|
||||
boolean headerFound = false;
|
||||
for (Iterator iterator = tis.getHeaderNames(); iterator.hasNext();) {
|
||||
String headerName = (String) iterator.next();
|
||||
if (RESPONSE_HEADER_NAME.equals(headerName)) {
|
||||
headerFound = true;
|
||||
}
|
||||
}
|
||||
assertTrue("Response has invalid header", headerFound);
|
||||
Iterator headerValues = tis.getHeaders(RESPONSE_HEADER_NAME);
|
||||
assertTrue("Response has no header values", headerValues.hasNext());
|
||||
assertEquals("Response has invalid header values", RESPONSE_HEADER_VALUE, headerValues.next());
|
||||
String result = new String(FileCopyUtils.copyToByteArray(tis), "UTF-8");
|
||||
assertEquals("Invalid response", RESPONSE, result);
|
||||
}
|
||||
finally {
|
||||
connection.close();
|
||||
@@ -126,56 +133,72 @@ public abstract class AbstractHttpWebServiceMessageSenderTestCase extends XMLTes
|
||||
}
|
||||
|
||||
public void testSendAndReceiveNoResponse() throws Exception {
|
||||
messageSender.setUrl(new URL("http://localhost:8888/noresponse"));
|
||||
SOAPMessage saajRequest = messageFactory.createMessage();
|
||||
transformer.transform(new StringSource(REQUEST), new DOMResult(saajRequest.getSOAPBody()));
|
||||
SaajSoapMessage request = new SaajSoapMessage(saajRequest);
|
||||
MessageContext context = new DefaultMessageContext(request, new SaajSoapMessageFactory(messageFactory));
|
||||
validateNonResponse(new MyServlet(false));
|
||||
}
|
||||
|
||||
public void testSendAndReceiveNoResponseAccepted() throws Exception {
|
||||
validateNonResponse(new MyServlet(false, HttpServletResponse.SC_ACCEPTED));
|
||||
}
|
||||
|
||||
public void testSendAndReceiveNoResponseInvalidContentLength() throws Exception {
|
||||
validateNonResponse(new MyServlet(false, HttpServletResponse.SC_OK, false));
|
||||
}
|
||||
|
||||
private void validateNonResponse(Servlet servlet) throws Exception {
|
||||
jettyContext.addServlet(new ServletHolder(servlet), "/");
|
||||
jettyServer.start();
|
||||
|
||||
messageSender.setUrl(new URL("http://localhost:8085/"));
|
||||
WebServiceConnection connection = messageSender.createConnection();
|
||||
try {
|
||||
connection.sendAndReceive(context);
|
||||
assertFalse("Response", context.hasResponse());
|
||||
TransportOutputStream tos = connection.getTransportOutputStream();
|
||||
tos.addHeader(REQUEST_HEADER_NAME, REQUEST_HEADER_VALUE);
|
||||
FileCopyUtils.copy(REQUEST.getBytes("UTF-8"), tos);
|
||||
assertNull("Response", connection.getTransportInputStream());
|
||||
}
|
||||
finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
private class ResponseServlet extends GenericServlet {
|
||||
private static class MyServlet extends GenericServlet {
|
||||
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
||||
try {
|
||||
StringResult requestResult = new StringResult();
|
||||
transformer.transform(new StreamSource(req.getInputStream()), requestResult);
|
||||
receivedRequest = requestResult.toString();
|
||||
receivedHeader = ((HttpServletRequest) req).getHeader(REQUEST_HEADER_NAME);
|
||||
private boolean response;
|
||||
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) res;
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
|
||||
httpServletResponse.addHeader("Content-Type", "text/xml");
|
||||
httpServletResponse.addHeader(RESPONSE_HEADER_NAME, RESPONSE_HEADER_VALUE);
|
||||
FileCopyUtils.copy(RESPONSE.getBytes("UTF-8"), res.getOutputStream());
|
||||
}
|
||||
catch (TransformerException ex) {
|
||||
throw new ServletException(ex);
|
||||
}
|
||||
private int responseStatus;
|
||||
|
||||
private boolean validContentLength;
|
||||
|
||||
public MyServlet(boolean response) {
|
||||
this(response, HttpServletResponse.SC_OK, true);
|
||||
}
|
||||
}
|
||||
|
||||
private class NoResponseServlet extends GenericServlet {
|
||||
public MyServlet(boolean response, int responseStatus) {
|
||||
this(response, responseStatus, true);
|
||||
}
|
||||
|
||||
public MyServlet(boolean response, int responseStatus, boolean validContentLength) {
|
||||
this.response = response;
|
||||
this.responseStatus = responseStatus;
|
||||
this.validContentLength = validContentLength;
|
||||
}
|
||||
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
||||
try {
|
||||
StringResult requestResult = new StringResult();
|
||||
transformer.transform(new StreamSource(req.getInputStream()), requestResult);
|
||||
receivedRequest = requestResult.toString();
|
||||
receivedHeader = ((HttpServletRequest) req).getHeader(REQUEST_HEADER_NAME);
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) req;
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) res;
|
||||
assertEquals("Invalid header value received on server side", REQUEST_HEADER_VALUE,
|
||||
httpServletRequest.getHeader(REQUEST_HEADER_NAME));
|
||||
String receivedRequest = new String(FileCopyUtils.copyToByteArray(req.getInputStream()), "UTF-8");
|
||||
assertEquals("Invalid request received", REQUEST, receivedRequest);
|
||||
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) res;
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);
|
||||
httpServletResponse.setStatus(responseStatus);
|
||||
if (!validContentLength) {
|
||||
httpServletResponse.setContentLength(-1);
|
||||
}
|
||||
catch (TransformerException ex) {
|
||||
throw new ServletException(ex);
|
||||
if (response) {
|
||||
httpServletResponse.addHeader(RESPONSE_HEADER_NAME, RESPONSE_HEADER_VALUE);
|
||||
httpServletResponse.setContentType("text/xml");
|
||||
FileCopyUtils.copy(RESPONSE.getBytes("UTF-8"), res.getOutputStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -17,34 +17,41 @@
|
||||
package org.springframework.ws.transport.http;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
|
||||
public class HttpServletTransportInputStreamTest extends TestCase {
|
||||
public class HttpServletConnectionTest extends TestCase {
|
||||
|
||||
private HttpServletTransportInputStream tis;
|
||||
private HttpServletConnection connection;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
request = new MockHttpServletRequest();
|
||||
tis = new HttpServletTransportInputStream(request);
|
||||
response = new MockHttpServletResponse();
|
||||
connection = new HttpServletConnection(request, response);
|
||||
}
|
||||
|
||||
public void testReadInputStream() throws Exception {
|
||||
byte[] content = "content".getBytes("UTF-8");
|
||||
request.setContent(content);
|
||||
byte[] result = FileCopyUtils.copyToByteArray(tis);
|
||||
byte[] result = FileCopyUtils.copyToByteArray(connection.getTransportInputStream());
|
||||
assertTrue("Invalid contents", Arrays.equals(content, result));
|
||||
}
|
||||
|
||||
public void testHeaders() throws Exception {
|
||||
public void testGetHeaders() throws Exception {
|
||||
String headerName = "Header";
|
||||
String headerValue = "Value";
|
||||
request.addHeader(headerName, headerValue);
|
||||
TransportInputStream tis = connection.getTransportInputStream();
|
||||
Iterator iterator = tis.getHeaderNames();
|
||||
assertTrue("No headers found", iterator.hasNext());
|
||||
assertEquals("Invalid header", headerName, iterator.next());
|
||||
@@ -53,4 +60,18 @@ public class HttpServletTransportInputStreamTest extends TestCase {
|
||||
assertEquals("Invalid header value", headerValue, iterator.next());
|
||||
}
|
||||
|
||||
public void testWriteOutputStream() throws Exception {
|
||||
byte[] content = "content".getBytes("UTF-8");
|
||||
FileCopyUtils.copy(content, connection.getTransportOutputStream());
|
||||
assertTrue("Invalid contents", Arrays.equals(content, response.getContentAsByteArray()));
|
||||
}
|
||||
|
||||
public void testAddHeaders() throws Exception {
|
||||
String headerName = "Header";
|
||||
String headerValue = "Value";
|
||||
connection.getTransportOutputStream().addHeader(headerName, headerValue);
|
||||
assertTrue("No header set", response.getHeaderNames().contains(headerName));
|
||||
assertEquals("Invalid header value set", Collections.singletonList(headerValue),
|
||||
response.getHeaders(headerName));
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 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.transport.http;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
public class HttpServletTransportOutputStreamTest extends TestCase {
|
||||
|
||||
private HttpServletTransportOutputStream tos;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
response = new MockHttpServletResponse();
|
||||
tos = new HttpServletTransportOutputStream(response);
|
||||
}
|
||||
|
||||
public void testWriteOutputStream() throws Exception {
|
||||
byte[] content = "content".getBytes("UTF-8");
|
||||
FileCopyUtils.copy(content, tos);
|
||||
assertTrue("Invalid contents", Arrays.equals(content, response.getContentAsByteArray()));
|
||||
}
|
||||
|
||||
public void testHeaders() throws Exception {
|
||||
String headerName = "Header";
|
||||
String headerValue = "Value";
|
||||
tos.addHeader(headerName, headerValue);
|
||||
assertTrue("No header set", response.getHeaderNames().contains(headerName));
|
||||
assertEquals("Invalid header value set", Collections.singletonList(headerValue),
|
||||
response.getHeaders(headerName));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.ws.transport.http;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
@@ -53,10 +52,13 @@ public class WebServiceMessageReceiverHandlerAdapterTest extends TestCase {
|
||||
|
||||
private WebServiceMessage requestMock;
|
||||
|
||||
private HttpServletConnection connection;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
adapter = new WebServiceMessageReceiverHandlerAdapter();
|
||||
httpRequest = new MockHttpServletRequest();
|
||||
httpResponse = new MockHttpServletResponse();
|
||||
connection = new HttpServletConnection(httpRequest, httpResponse);
|
||||
factoryControl = MockControl.createControl(WebServiceMessageFactory.class);
|
||||
factoryMock = (WebServiceMessageFactory) factoryControl.getMock();
|
||||
adapter.setMessageFactory(factoryMock);
|
||||
@@ -73,13 +75,9 @@ public class WebServiceMessageReceiverHandlerAdapterTest extends TestCase {
|
||||
public void receive(MessageContext messageContext) throws Exception {
|
||||
}
|
||||
};
|
||||
try {
|
||||
adapter.handle(httpRequest, httpResponse, endpoint);
|
||||
fail("ServletException expected");
|
||||
}
|
||||
catch (ServletException ex) {
|
||||
// expected
|
||||
}
|
||||
adapter.handle(httpRequest, httpResponse, endpoint);
|
||||
assertEquals("METHOD_NOT_ALLOWED expected", HttpServletResponse.SC_METHOD_NOT_ALLOWED,
|
||||
httpResponse.getStatus());
|
||||
verifyMockControls();
|
||||
}
|
||||
|
||||
@@ -88,7 +86,7 @@ public class WebServiceMessageReceiverHandlerAdapterTest extends TestCase {
|
||||
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
|
||||
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
|
||||
httpRequest.setCharacterEncoding("UTF-8");
|
||||
factoryMock.createWebServiceMessage(new HttpServletTransportInputStream(httpRequest));
|
||||
factoryMock.createWebServiceMessage(connection.getTransportInputStream());
|
||||
factoryControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
factoryControl.setReturnValue(responseMock);
|
||||
|
||||
@@ -101,7 +99,7 @@ public class WebServiceMessageReceiverHandlerAdapterTest extends TestCase {
|
||||
|
||||
adapter.handle(httpRequest, httpResponse, endpoint);
|
||||
|
||||
assertEquals("Invalid status code on response", HttpServletResponse.SC_NO_CONTENT, httpResponse.getStatus());
|
||||
assertEquals("Invalid status code on response", HttpServletResponse.SC_ACCEPTED, httpResponse.getStatus());
|
||||
assertEquals("Response written", 0, httpResponse.getContentAsString().length());
|
||||
verifyMockControls();
|
||||
}
|
||||
@@ -111,12 +109,12 @@ public class WebServiceMessageReceiverHandlerAdapterTest extends TestCase {
|
||||
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
|
||||
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
|
||||
httpRequest.setCharacterEncoding("UTF-8");
|
||||
factoryMock.createWebServiceMessage(new HttpServletTransportInputStream(httpRequest));
|
||||
factoryMock.createWebServiceMessage(connection.getTransportInputStream());
|
||||
factoryControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
factoryControl.setReturnValue(requestMock);
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), responseMock);
|
||||
messageControl.expectAndReturn(responseMock.hasFault(), false);
|
||||
responseMock.writeTo(new HttpServletTransportOutputStream(httpResponse));
|
||||
responseMock.writeTo(connection.getTransportOutputStream());
|
||||
messageControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
|
||||
replayMockControls();
|
||||
@@ -138,12 +136,12 @@ public class WebServiceMessageReceiverHandlerAdapterTest extends TestCase {
|
||||
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
|
||||
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
|
||||
httpRequest.setCharacterEncoding("UTF-8");
|
||||
factoryMock.createWebServiceMessage(new HttpServletTransportInputStream(httpRequest));
|
||||
factoryMock.createWebServiceMessage(connection.getTransportInputStream());
|
||||
factoryControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
factoryControl.setReturnValue(requestMock);
|
||||
factoryControl.expectAndReturn(factoryMock.createWebServiceMessage(), responseMock);
|
||||
messageControl.expectAndReturn(responseMock.hasFault(), true);
|
||||
responseMock.writeTo(new HttpServletTransportOutputStream(httpResponse));
|
||||
responseMock.writeTo(connection.getTransportOutputStream());
|
||||
messageControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
|
||||
replayMockControls();
|
||||
@@ -166,7 +164,7 @@ public class WebServiceMessageReceiverHandlerAdapterTest extends TestCase {
|
||||
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
|
||||
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
|
||||
httpRequest.setCharacterEncoding("UTF-8");
|
||||
factoryMock.createWebServiceMessage(new HttpServletTransportInputStream(httpRequest));
|
||||
factoryMock.createWebServiceMessage(connection.getTransportInputStream());
|
||||
factoryControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
factoryControl.setReturnValue(requestMock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user