WebServiceConnection is now container for TransportInputStream and TransportOutputStream, used on both client- and server-side.

This commit is contained in:
Arjen Poutsma
2007-04-07 20:19:47 +00:00
parent c52aa50a4e
commit 790ad51c17
33 changed files with 1237 additions and 1127 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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) {
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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());
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006 the original author or authors.
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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);