MessageDispatcher no longer implements MessageEndpoint, to fix circular package dependency.

Moved TransportContext and friends to transport.context subpackage.
This commit is contained in:
Arjen Poutsma
2007-01-14 14:15:50 +00:00
parent 5800c82444
commit 3c2e016164
12 changed files with 120 additions and 63 deletions

View File

@@ -26,9 +26,9 @@ import org.springframework.beans.factory.BeanNameAware;
import org.springframework.util.ObjectUtils;
import org.springframework.ws.NoEndpointFoundException;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.MessageEndpoint;
import org.springframework.ws.server.endpoint.MessageEndpointAdapter;
import org.springframework.ws.server.endpoint.PayloadEndpointAdapter;
import org.springframework.ws.transport.WebServiceMessageReceiver;
/**
* Central dispatcher for use withing Spring-WS. Dispatches Web service messages to registered endoints.
@@ -43,9 +43,6 @@ import org.springframework.ws.server.endpoint.PayloadEndpointAdapter;
* <code>endpointAdapters</code> property.</li> <li>Its exception resolution strategy can be specified via a
* <code>EndpointExceptionResolver</code>, for example mapping certain exceptions to SOAP Faults. Default is none.
* Additional exception resolvers can be added through the <code>endpointExceptionResolvers</code> property.</li> </ul>
* A web application can use any number of <code>MessageDispatcher</code>s.</b> Since a <code>MessageDispatcher</code>
* also implements <code>MessageEndpoint</code>, it is also possible to chain them: one dispatcher can be registered as
* the endpoint of another, though the <code>MessageEndpointAdapter</code>.
*
* @author Arjen Poutsma
* @see EndpointMapping
@@ -53,7 +50,7 @@ import org.springframework.ws.server.endpoint.PayloadEndpointAdapter;
* @see EndpointExceptionResolver
* @see org.springframework.web.servlet.DispatcherServlet
*/
public class MessageDispatcher implements MessageEndpoint, BeanNameAware {
public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAware {
/**
* Log category to use when no mapped endpoint is found for a request.
@@ -143,7 +140,7 @@ public class MessageDispatcher implements MessageEndpoint, BeanNameAware {
this.beanName = beanName;
}
public void invoke(MessageContext messageContext) throws Exception {
public void receive(MessageContext messageContext) throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("MessageDispatcher with name '" + beanName + "' received request [" +
messageContext.getRequest() + "]");

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 org.springframework.ws.context.MessageContext;
/**
* Defines the methods for classes capable of receiving {@link org.springframework.ws.WebServiceMessage} instances
* coming in on a transport.
*
* @author Arjen Poutsma
*/
public interface WebServiceMessageReceiver {
/**
* Receives the given message context. The given message context can be used to create a response.
*
* @param messageContext the message context to be received
*/
void receive(MessageContext messageContext) throws Exception;
}

View File

@@ -14,7 +14,10 @@
* limitations under the License.
*/
package org.springframework.ws.transport;
package org.springframework.ws.transport.context;
import org.springframework.ws.transport.TransportInputStream;
import org.springframework.ws.transport.TransportOutputStream;
/**
* Default implementation of the <code>TransportContext</code> interface.

View File

@@ -1,7 +1,11 @@
package org.springframework.ws.transport;
package org.springframework.ws.transport.context;
import org.springframework.ws.transport.TransportInputStream;
import org.springframework.ws.transport.TransportOutputStream;
/**
* Strategy interface for determining the current {@link TransportInputStream} and {@link TransportOutputStream}.
* Strategy interface for determining the current {@link org.springframework.ws.transport.TransportInputStream} and
* {@link org.springframework.ws.transport.TransportOutputStream}.
* <p/>
* An instance of this class can be associated with a thread via the {@link TransportContextHolder} class.
*

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.transport;
package org.springframework.ws.transport.context;
/**
* Simple holder class that associates a <code>TransportContext</code> instance with the current thread. The

View File

@@ -0,0 +1,5 @@
<html>
<body>
Abstraction for determining the current TransportInputStream and TransportOutputStream.
</body>
</html>

View File

@@ -32,10 +32,10 @@ import org.springframework.ws.wsdl.WsdlDefinition;
/**
* Servlet for simplified dispatching of Web service messages. Delegates to a <code>MessageDispatcher</code> and a
* <code>MessageEndpointHandlerAdapter</code>.
* <code>WebServiceMessageReceiverHandlerAdapter</code>.
* <p/>
* This servlet is a convenient alternative for a standard Spring-MVC <code>DispatcherServlet</code> with a separate
* <code>MessageEndpointHandlerAdapter</code> and a <code>MessageDispatcher</code>.
* <code>WebServiceMessageReceiverHandlerAdapter</code> and a <code>MessageDispatcher</code>.
* <p/>
* This servlet automatically detects <code>EndpointAdapter</code>s, <code>EndpointMapping</code>s, and
* <code>EndpointExceptionResolver</code>s, by type (when the corresponding detectAll* property is enabled) or by type
@@ -47,7 +47,7 @@ import org.springframework.ws.wsdl.WsdlDefinition;
* @author Arjen Poutsma
* @see org.springframework.web.servlet.DispatcherServlet
* @see org.springframework.ws.server.MessageDispatcher
* @see org.springframework.ws.transport.http.MessageEndpointHandlerAdapter
* @see org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter
*/
public class MessageDispatcherServlet extends FrameworkServlet {
@@ -120,9 +120,10 @@ public class MessageDispatcherServlet extends FrameworkServlet {
private boolean detectAllWsdlDefinitions = true;
/**
* The <code>MessageEndpointHandlerAdapter</code> used by this servlet.
* The <code>WebServiceMessageReceiverHandlerAdapter</code> used by this servlet.
*/
private MessageEndpointHandlerAdapter messageEndpointHandlerAdapter = new MessageEndpointHandlerAdapter();
private WebServiceMessageReceiverHandlerAdapter messageReceiverHandlerAdapter =
new WebServiceMessageReceiverHandlerAdapter();
/**
* The <code>WsdlDefinitionHandlerAdapter</code> used by this servlet.
@@ -219,7 +220,7 @@ public class MessageDispatcherServlet extends FrameworkServlet {
}
protected long getLastModified(HttpServletRequest req) {
return messageEndpointHandlerAdapter.getLastModified(req, messageDispatcher);
return messageReceiverHandlerAdapter.getLastModified(req, messageDispatcher);
}
protected void initFrameworkServlet() throws ServletException, BeansException {
@@ -235,7 +236,7 @@ public class MessageDispatcherServlet extends FrameworkServlet {
wsdlDefinitionHandlerAdapter.handle(httpServletRequest, httpServletResponse, definition);
}
else {
messageEndpointHandlerAdapter.handle(httpServletRequest, httpServletResponse, messageDispatcher);
messageReceiverHandlerAdapter.handle(httpServletRequest, httpServletResponse, messageDispatcher);
}
}
@@ -428,7 +429,7 @@ public class MessageDispatcherServlet extends FrameworkServlet {
}
}
}
messageEndpointHandlerAdapter.setMessageFactory(messageFactory);
messageReceiverHandlerAdapter.setMessageFactory(messageFactory);
}
private void initMessageDispatcher() {

View File

@@ -23,27 +23,29 @@ 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.server.endpoint.MessageEndpoint;
import org.springframework.ws.transport.MessageReceiverObjectSupport;
import org.springframework.ws.transport.TransportInputStream;
import org.springframework.ws.transport.TransportOutputStream;
import org.springframework.ws.transport.WebServiceMessageReceiver;
import org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport;
/**
* Adapter to use the <code>MessageEndpoint</code> interface with the generic <code>DispatcherServlet</code>. Requires a
* <code>WebServiceMessageFactory</code> which is used to convert the incoming <code>HttpServletRequest</code> into a
* <code>WebServiceMessage</code>, and passes that context to the mapped <code>MessageEndpoint</code>. If a response is
* created, that is sent via the <code>HttpServletResponse</code>.
* Adapter to use the {@link WebServiceMessageReceiver} interface with the generic {@link
* org.springframework.web.servlet.DispatcherServlet}. Requires a {@link org.springframework.ws.WebServiceMessageFactory}
* which is used to convert the incoming <code>HttpServletRequest</code> into a <code>WebServiceMessage</code>, and
* passes that context to the mapped <code>WebServiceMessageReceiver</code>. If a response is created, that is sent via
* the <code>HttpServletResponse</code>.
* <p/>
* Note that the <code>MessageDispatcher</code> implements the <code>MessageEndpoint</code> interface, enabling this
* adapter to function as a gateway to further message handling logic.
* Note that the <code>MessageDispatcher</code> implements the <code>WebServiceMessageReceiver</code> interface,
* enabling this adapter to function as a gateway to further message handling logic.
*
* @author Arjen Poutsma
* @see #setMessageFactory(org.springframework.ws.WebServiceMessageFactory)
* @see org.springframework.ws.transport.WebServiceMessageReceiver
* @see org.springframework.ws.WebServiceMessageFactory
* @see org.springframework.ws.server.endpoint.MessageEndpoint
* @see org.springframework.ws.server.MessageDispatcher
*/
public class MessageEndpointHandlerAdapter extends MessageReceiverObjectSupport implements HandlerAdapter {
public class WebServiceMessageReceiverHandlerAdapter extends WebServiceMessageReceiverObjectSupport
implements HandlerAdapter {
public long getLastModified(HttpServletRequest request, Object handler) {
return -1L;
@@ -55,7 +57,7 @@ public class MessageEndpointHandlerAdapter extends MessageReceiverObjectSupport
if ("POST".equals(httpServletRequest.getMethod())) {
TransportInputStream tis = new HttpServletTransportInputStream(httpServletRequest);
TransportOutputStream tos = new HttpServletTransportOutputStream(httpServletResponse);
handle(tis, tos, (MessageEndpoint) handler);
handle(tis, tos, (WebServiceMessageReceiver) handler);
return null;
}
else {
@@ -64,7 +66,7 @@ public class MessageEndpointHandlerAdapter extends MessageReceiverObjectSupport
}
public boolean supports(Object handler) {
return handler instanceof MessageEndpoint;
return handler instanceof WebServiceMessageReceiver;
}
/**

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.ws.transport;
package org.springframework.ws.transport.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -25,16 +25,21 @@ import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.MessageEndpoint;
import org.springframework.ws.transport.TransportInputStream;
import org.springframework.ws.transport.TransportOutputStream;
import org.springframework.ws.transport.WebServiceMessageReceiver;
import org.springframework.ws.transport.context.DefaultTransportContext;
import org.springframework.ws.transport.context.TransportContext;
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.
*
* @author Arjen Poutsma
* @see #handle(TransportInputStream,TransportOutputStream,org.springframework.ws.server.endpoint.MessageEndpoint)
* @see #handle(org.springframework.ws.transport.TransportInputStream,org.springframework.ws.transport.TransportOutputStream,org.springframework.ws.transport.WebServiceMessageReceiver)
*/
public abstract class MessageReceiverObjectSupport implements InitializingBean {
public abstract class WebServiceMessageReceiverObjectSupport implements InitializingBean {
/**
* Logger available to subclasses.
@@ -62,7 +67,7 @@ public abstract class MessageReceiverObjectSupport implements InitializingBean {
logger.info("Using message factory [" + messageFactory + "]");
}
protected final void handle(TransportInputStream tis, TransportOutputStream tos, MessageEndpoint endpoint)
protected final void handle(TransportInputStream tis, TransportOutputStream tos, WebServiceMessageReceiver receiver)
throws Exception {
TransportContext previousTransportContext = TransportContextHolder.getTransportContext();
TransportContextHolder.setTransportContext(new DefaultTransportContext(tis, tos));
@@ -70,7 +75,7 @@ public abstract class MessageReceiverObjectSupport implements InitializingBean {
try {
WebServiceMessage messageRequest = getMessageFactory().createWebServiceMessage(tis);
MessageContext messageContext = new DefaultMessageContext(messageRequest, getMessageFactory());
endpoint.invoke(messageContext);
receiver.receive(messageContext);
if (!messageContext.hasResponse()) {
handleNoResponse(tis, tos);
}
@@ -87,7 +92,7 @@ public abstract class MessageReceiverObjectSupport implements InitializingBean {
}
/**
* Invoked from {@link #handle(TransportInputStream,TransportOutputStream,org.springframework.ws.server.endpoint.MessageEndpoint)}
* 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.
*
@@ -98,7 +103,7 @@ public abstract class MessageReceiverObjectSupport implements InitializingBean {
}
/**
* Handles the sending of the response. Invoked from {@link #handle(TransportInputStream,TransportOutputStream,org.springframework.ws.server.endpoint.MessageEndpoint)}.
* 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.
*
@@ -113,7 +118,7 @@ public abstract class MessageReceiverObjectSupport implements InitializingBean {
}
/**
* Invoked from {@link #handle(TransportInputStream,TransportOutputStream,org.springframework.ws.server.endpoint.MessageEndpoint)}
* 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.
*

View File

@@ -29,7 +29,7 @@ import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.MessageEndpoint;
public class MessageEndpointHandlerAdapterTest extends TestCase {
public class WebServiceMessageReceiverHandlerAdapterTest extends TestCase {
private static final String REQUEST = " <SOAP-ENV:Envelope\n" +
" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
@@ -37,7 +37,7 @@ public class MessageEndpointHandlerAdapterTest extends TestCase {
" <m:GetLastTradePrice xmlns:m=\"Some-URI\">\n" + " <symbol>DIS</symbol>\n" +
" </m:GetLastTradePrice>\n" + " </SOAP-ENV:Body>\n" + "</SOAP-ENV:Envelope>";
private MessageEndpointHandlerAdapter adapter;
private WebServiceMessageReceiverHandlerAdapter adapter;
private MockHttpServletRequest httpRequest;
@@ -54,7 +54,7 @@ public class MessageEndpointHandlerAdapterTest extends TestCase {
private WebServiceMessage requestMock;
protected void setUp() throws Exception {
adapter = new MessageEndpointHandlerAdapter();
adapter = new WebServiceMessageReceiverHandlerAdapter();
httpRequest = new MockHttpServletRequest();
httpResponse = new MockHttpServletResponse();
factoryControl = MockControl.createControl(WebServiceMessageFactory.class);
@@ -85,7 +85,7 @@ public class MessageEndpointHandlerAdapterTest extends TestCase {
public void testHandlePostNoResponse() throws Exception {
httpRequest.setMethod("POST");
httpRequest.setContent(MessageEndpointHandlerAdapterTest.REQUEST.getBytes("UTF-8"));
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
httpRequest.setCharacterEncoding("UTF-8");
factoryMock.createWebServiceMessage(new HttpServletTransportInputStream(httpRequest));
@@ -108,7 +108,7 @@ public class MessageEndpointHandlerAdapterTest extends TestCase {
public void testHandlePostResponse() throws Exception {
httpRequest.setMethod("POST");
httpRequest.setContent(MessageEndpointHandlerAdapterTest.REQUEST.getBytes("UTF-8"));
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
httpRequest.setCharacterEncoding("UTF-8");
factoryMock.createWebServiceMessage(new HttpServletTransportInputStream(httpRequest));
@@ -135,7 +135,7 @@ public class MessageEndpointHandlerAdapterTest extends TestCase {
public void testHandlePostFault() throws Exception {
httpRequest.setMethod("POST");
httpRequest.setContent(MessageEndpointHandlerAdapterTest.REQUEST.getBytes("UTF-8"));
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
httpRequest.setCharacterEncoding("UTF-8");
factoryMock.createWebServiceMessage(new HttpServletTransportInputStream(httpRequest));
@@ -163,7 +163,7 @@ public class MessageEndpointHandlerAdapterTest extends TestCase {
public void testHandleNotFound() throws Exception {
httpRequest.setMethod("POST");
httpRequest.setContent(MessageEndpointHandlerAdapterTest.REQUEST.getBytes("UTF-8"));
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
httpRequest.setCharacterEncoding("UTF-8");
factoryMock.createWebServiceMessage(new HttpServletTransportInputStream(httpRequest));

View File

@@ -22,6 +22,7 @@ import javax.jms.Message;
import javax.jms.Session;
import org.springframework.jms.listener.SessionAwareMessageListener;
import org.springframework.ws.transport.jms.support.JmsWebServiceMessageReceiverObjectSupport;
/**
* Spring-2.0 <code>SessionAwareMessageListener</code> that can be used to handle incoming JMS messages. Requires a
@@ -34,9 +35,9 @@ import org.springframework.jms.listener.SessionAwareMessageListener;
*
* @author Arjen Poutsma
* @see #setMessageFactory(org.springframework.ws.WebServiceMessageFactory)
* @see #setMessageEndpoint(org.springframework.ws.server.endpoint.MessageEndpoint)
* @see #setMessageReceiver(org.springframework.ws.transport.WebServiceMessageReceiver)
*/
public class MessageEndpointMessageListener extends JmsMessageReceiverObjectSupport
public class MessageEndpointMessageListener extends JmsWebServiceMessageReceiverObjectSupport
implements SessionAwareMessageListener {
public void onMessage(Message message, Session session) throws JMSException {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.ws.transport.jms;
package org.springframework.ws.transport.jms.support;
import javax.jms.BytesMessage;
import javax.jms.Message;
@@ -25,41 +25,44 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.jms.support.JmsUtils;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.server.endpoint.MessageEndpoint;
import org.springframework.ws.transport.MessageReceiverObjectSupport;
import org.springframework.ws.transport.TransportInputStream;
import org.springframework.ws.transport.TransportOutputStream;
import org.springframework.ws.transport.WebServiceMessageReceiver;
import org.springframework.ws.transport.jms.JmsTransportInputStream;
import org.springframework.ws.transport.jms.JmsTransportOutputStream;
import org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport;
/**
* Convenience base class for JMS server-side transport objects. Contains a {@link MessageEndpoint}, and has methods for
* handling incoming JMS <code>Message</code> requests.
* Convenience base class for JMS server-side transport objects. Contains a {@link WebServiceMessageReceiver}, and has
* methods for handling incoming JMS <code>Message</code> requests.
* <p/>
* This class can be used as a base for a EJB MessageDrivenBean, or using Spring-2.0's MessageDriven POJO's.
*
* @author Arjen Poutsma
* @see #handle(javax.jms.Message,javax.jms.Session)
*/
public abstract class JmsMessageReceiverObjectSupport extends MessageReceiverObjectSupport implements InitializingBean {
public abstract class JmsWebServiceMessageReceiverObjectSupport extends WebServiceMessageReceiverObjectSupport
implements InitializingBean {
private MessageEndpoint messageEndpoint;
private WebServiceMessageReceiver messageReceiver;
/**
* Returns the <code>MessageEndpoint</code> used by this listener.
* Returns the <code>WebServiceMessageReceiver</code> used by this listener.
*/
public MessageEndpoint getMessageEndpoint() {
return messageEndpoint;
public WebServiceMessageReceiver getMessageReceiver() {
return messageReceiver;
}
/**
* Sets the <code>MessageEndpoint</code> used by this listener.
* Sets the <code>WebServiceMessageReceiver</code> used by this listener.
*/
public void setMessageEndpoint(MessageEndpoint messageEndpoint) {
this.messageEndpoint = messageEndpoint;
public void setMessageReceiver(WebServiceMessageReceiver messageReceiver) {
this.messageReceiver = messageReceiver;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(getMessageFactory(), "messageFactory is required");
Assert.notNull(getMessageEndpoint(), "messageEndpoint must not be null");
Assert.notNull(getMessageReceiver(), "messageReceiver must not be null");
logger.info("Using message factory [" + getMessageFactory() + "]");
}
@@ -74,7 +77,7 @@ public abstract class JmsMessageReceiverObjectSupport extends MessageReceiverObj
if (request instanceof BytesMessage) {
TransportInputStream tis = new JmsTransportInputStream((BytesMessage) request);
TransportOutputStream tos = new JmsTransportOutputStream(session, request.getJMSCorrelationID());
handle(tis, tos, getMessageEndpoint());
handle(tis, tos, getMessageReceiver());
}
else {
throw new IllegalArgumentException(