Finishing up on JMS support.
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.NoEndpointFoundException;
|
||||
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.endpoint.MessageEndpoint;
|
||||
|
||||
/**
|
||||
* 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.endpoint.MessageEndpoint)
|
||||
*/
|
||||
public abstract class ServerTransportObjectSupport implements InitializingBean {
|
||||
|
||||
/**
|
||||
* Logger available to subclasses.
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private WebServiceMessageFactory messageFactory;
|
||||
|
||||
/**
|
||||
* Returns the <code>WebServiceMessageFactory</code>.
|
||||
*/
|
||||
public WebServiceMessageFactory getMessageFactory() {
|
||||
return messageFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>WebServiceMessageFactory</code>.
|
||||
*/
|
||||
public void setMessageFactory(WebServiceMessageFactory messageFactory) {
|
||||
this.messageFactory = messageFactory;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(messageFactory, "messageFactory is required");
|
||||
logger.info("Using message factory [" + messageFactory + "]");
|
||||
}
|
||||
|
||||
protected final void handle(TransportInputStream tis, TransportOutputStream tos, MessageEndpoint endpoint)
|
||||
throws Exception {
|
||||
TransportContext previousTransportContext = TransportContextHolder.getTransportContext();
|
||||
TransportContextHolder.setTransportContext(new DefaultTransportContext(tis, tos));
|
||||
|
||||
try {
|
||||
WebServiceMessage messageRequest = getMessageFactory().createWebServiceMessage(tis);
|
||||
MessageContext messageContext = new DefaultMessageContext(messageRequest, getMessageFactory());
|
||||
endpoint.invoke(messageContext);
|
||||
if (!messageContext.hasResponse()) {
|
||||
handleNoResponse(tis, tos);
|
||||
}
|
||||
else {
|
||||
handleResponse(tis, tos, messageContext.getResponse());
|
||||
}
|
||||
}
|
||||
catch (NoEndpointFoundException ex) {
|
||||
handleNoEndpointFound(tis, tos);
|
||||
}
|
||||
finally {
|
||||
TransportContextHolder.setTransportContext(previousTransportContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked from <code>handle()</code> when no response is given. Default implementation does nothing. Can be
|
||||
* overriden to set certain transport-specific headers.
|
||||
*
|
||||
* @param tis the transport input stream
|
||||
* @param tos the transport output stream
|
||||
*/
|
||||
protected void handleNoResponse(TransportInputStream tis, TransportOutputStream tos) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the sending of the response. Invoked from <code>handle()</code>. Default implementation writes the given
|
||||
* response to the given <code>TransportOutputStream</code>. Can be overriden to set certain transport-specific
|
||||
* headers.
|
||||
*
|
||||
* @param tis the transport input stream
|
||||
* @param tos the transport output stream
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when no suitable endpoint is found. Default implementation does nothing. Can be overriden to set certain
|
||||
* transport-specific headers.
|
||||
*
|
||||
* @param tis the transport input stream
|
||||
* @param tos the transport output stream
|
||||
*/
|
||||
protected void handleNoEndpointFound(TransportInputStream tis, TransportOutputStream tos) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,47 +20,31 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.ws.NoEndpointFoundException;
|
||||
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.endpoint.MessageEndpoint;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.transport.DefaultTransportContext;
|
||||
import org.springframework.ws.transport.TransportContext;
|
||||
import org.springframework.ws.transport.TransportContextHolder;
|
||||
import org.springframework.ws.transport.ServerTransportObjectSupport;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
|
||||
/**
|
||||
* Adapter to use the <code>MessageEndpoint</code> interface with the generic <code>DispatcherServlet</code>. Requires a
|
||||
* {@link WebServiceMessageFactory}, which is used to convert the incoming <code>HttpServletRequest</code> into a {@link
|
||||
* WebServiceMessage}, and passes that context to the mapped <code>MessageEndpoint</code>. If a response is created,
|
||||
* that is sent via the <code>HttpServletResponse</code>.
|
||||
* <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>.
|
||||
* <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.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see #setMessageFactory(org.springframework.ws.WebServiceMessageFactory)
|
||||
* @see org.springframework.ws.WebServiceMessageFactory
|
||||
* @see org.springframework.ws.endpoint.MessageEndpoint
|
||||
* @see org.springframework.ws.MessageDispatcher
|
||||
*/
|
||||
public class MessageEndpointHandlerAdapter implements HandlerAdapter, InitializingBean {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(MessageEndpointHandlerAdapter.class);
|
||||
|
||||
private WebServiceMessageFactory messageFactory;
|
||||
|
||||
public void setMessageFactory(WebServiceMessageFactory messageFactory) {
|
||||
this.messageFactory = messageFactory;
|
||||
}
|
||||
public class MessageEndpointHandlerAdapter extends ServerTransportObjectSupport implements HandlerAdapter {
|
||||
|
||||
public long getLastModified(HttpServletRequest request, Object handler) {
|
||||
return -1L;
|
||||
@@ -70,7 +54,9 @@ public class MessageEndpointHandlerAdapter implements HandlerAdapter, Initializi
|
||||
HttpServletResponse httpServletResponse,
|
||||
Object handler) throws Exception {
|
||||
if ("POST".equals(httpServletRequest.getMethod())) {
|
||||
handlePost(httpServletRequest, (MessageEndpoint) handler, httpServletResponse);
|
||||
TransportInputStream tis = new HttpServletTransportInputStream(httpServletRequest);
|
||||
TransportOutputStream tos = new HttpServletTransportOutputStream(httpServletResponse);
|
||||
handle(tis, tos, (MessageEndpoint) handler);
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
@@ -82,44 +68,35 @@ public class MessageEndpointHandlerAdapter implements HandlerAdapter, Initializi
|
||||
return handler instanceof MessageEndpoint;
|
||||
}
|
||||
|
||||
public final void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(messageFactory, "messageFactory is required");
|
||||
logger.info("Using message factory [" + messageFactory + "]");
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
private void handlePost(HttpServletRequest httpServletRequest,
|
||||
MessageEndpoint endpoint,
|
||||
HttpServletResponse httpServletResponse) throws Exception {
|
||||
TransportInputStream tis = new HttpServletTransportInputStream(httpServletRequest);
|
||||
TransportOutputStream tos = new HttpServletTransportOutputStream(httpServletResponse);
|
||||
/**
|
||||
* 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();
|
||||
if (response instanceof SoapMessage && ((SoapMessage) response).getSoapBody().hasFault()) {
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
else {
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
|
||||
}
|
||||
response.writeTo(tos);
|
||||
}
|
||||
|
||||
TransportContext previousTransportContext = TransportContextHolder.getTransportContext();
|
||||
TransportContextHolder.setTransportContext(new DefaultTransportContext(tis, tos));
|
||||
|
||||
try {
|
||||
WebServiceMessage messageRequest = messageFactory.createWebServiceMessage(tis);
|
||||
MessageContext messageContext = new DefaultMessageContext(messageRequest, messageFactory);
|
||||
endpoint.invoke(messageContext);
|
||||
if (!messageContext.hasResponse()) {
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);
|
||||
}
|
||||
else {
|
||||
WebServiceMessage messageResponse = messageContext.getResponse();
|
||||
if (messageResponse instanceof SoapMessage &&
|
||||
((SoapMessage) messageResponse).getSoapBody().hasFault()) {
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
else {
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
|
||||
}
|
||||
messageResponse.writeTo(tos);
|
||||
}
|
||||
}
|
||||
catch (NoEndpointFoundException ex) {
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
finally {
|
||||
TransportContextHolder.setTransportContext(previousTransportContext);
|
||||
}
|
||||
/**
|
||||
* Sets the response code to 404, Not Found.
|
||||
*/
|
||||
protected void handleNoEndpointFound(TransportInputStream tis, TransportOutputStream tos) {
|
||||
HttpServletResponse httpServletResponse = ((HttpServletTransportOutputStream) tos).getHttpServletResponse();
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,24 @@
|
||||
<artifactId>spring-ws-sandbox</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring WS Sandbox</name>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>spring-2.0</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>spring.version</name>
|
||||
<value>2.0</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jms</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
<dependencies>
|
||||
<!-- Spring-WS dependencies -->
|
||||
<dependency>
|
||||
|
||||
@@ -1,33 +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.jms;
|
||||
|
||||
import org.springframework.ws.transport.TransportException;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class JmsTransportException extends TransportException {
|
||||
|
||||
public JmsTransportException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public JmsTransportException(String string, Throwable throwable) {
|
||||
super(string, throwable);
|
||||
}
|
||||
}
|
||||
@@ -29,17 +29,34 @@ import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.support.EnumerationIterator;
|
||||
|
||||
/**
|
||||
* JMS specific implementation of the <code>TransportInputStream</code> interface. Exposes a JMS
|
||||
* <code>TextMessage</code>.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see #getTextMessage()
|
||||
*/
|
||||
public class JmsTransportInputStream extends TransportInputStream {
|
||||
|
||||
private final TextMessage textMessage;
|
||||
|
||||
public JmsTransportInputStream(TextMessage textMessage) throws IOException {
|
||||
/**
|
||||
* Constructs a new instance of the <code>JmsTransportInputStream</code> using the provided JMS
|
||||
* <code>TextMessage</code>.
|
||||
*
|
||||
* @param textMessage the JMS message
|
||||
*/
|
||||
public JmsTransportInputStream(TextMessage textMessage) {
|
||||
Assert.notNull(textMessage, "textMessage must not be null");
|
||||
this.textMessage = textMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped JMS <code>TextMessage</code>.
|
||||
*/
|
||||
public TextMessage getTextMessage() {
|
||||
return textMessage;
|
||||
}
|
||||
|
||||
protected InputStream createInputStream() throws IOException {
|
||||
try {
|
||||
return new ByteArrayInputStream(textMessage.getText().getBytes("UTF-8"));
|
||||
|
||||
@@ -16,94 +16,114 @@
|
||||
|
||||
package org.springframework.ws.transport.jms;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jms.listener.SessionAwareMessageListener;
|
||||
import org.springframework.jms.support.JmsUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.NoEndpointFoundException;
|
||||
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.endpoint.MessageEndpoint;
|
||||
import org.springframework.ws.transport.DefaultTransportContext;
|
||||
import org.springframework.ws.transport.TransportContext;
|
||||
import org.springframework.ws.transport.TransportContextHolder;
|
||||
import org.springframework.ws.transport.ServerTransportObjectSupport;
|
||||
import org.springframework.ws.transport.TransportInputStream;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
|
||||
/**
|
||||
* JMS <code>MessageListener</code> that can be used to handle incoming JMS messages. Requires a
|
||||
* <code>WebServiceMessageFactory</code> which is used to convert the incoming JMS <code>TextMessage</code> into a
|
||||
* <code>WebServiceMessage</code>, and passes that context to the required <code>MessageEndpoint</code>. If a response
|
||||
* is created, it is sent using a response JMS message.
|
||||
* <p/>
|
||||
* This class implements both <code>MessageListener</code>, for
|
||||
* <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.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see #setMessageFactory(org.springframework.ws.WebServiceMessageFactory)
|
||||
* @see #setMessageEndpoint(org.springframework.ws.endpoint.MessageEndpoint)
|
||||
*/
|
||||
public class JmsTransportMessageListener implements MessageListener, InitializingBean {
|
||||
// TODO: implemement SessionAwareMessageListener
|
||||
public class JmsTransportMessageListener extends ServerTransportObjectSupport
|
||||
implements SessionAwareMessageListener, MessageListener, InitializingBean {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JmsTransportMessageListener.class);
|
||||
|
||||
private WebServiceMessageFactory messageFactory;
|
||||
private MessageEndpoint messageEndpoint;
|
||||
|
||||
private MessageEndpoint endpoint;
|
||||
/**
|
||||
* Returns the <code>MessageEndpoint</code> used by this listener.
|
||||
*/
|
||||
public MessageEndpoint getMessageEndpoint() {
|
||||
return messageEndpoint;
|
||||
}
|
||||
|
||||
public void setMessageFactory(WebServiceMessageFactory messageFactory) {
|
||||
this.messageFactory = messageFactory;
|
||||
/**
|
||||
* Sets the <code>MessageEndpoint</code> used by this listener.
|
||||
*/
|
||||
public void setMessageEndpoint(MessageEndpoint messageEndpoint) {
|
||||
this.messageEndpoint = messageEndpoint;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(messageFactory, "messageFactory is required");
|
||||
logger.info("Using message factory [" + messageFactory + "]");
|
||||
Assert.notNull(getMessageFactory(), "messageFactory is required");
|
||||
Assert.notNull(getMessageEndpoint(), "messageEndpoint must not be null");
|
||||
logger.info("Using message factory [" + getMessageFactory() + "]");
|
||||
}
|
||||
|
||||
public void onMessage(Message message) {
|
||||
try {
|
||||
onMessage(message, null);
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
logger.error("Could not handle message: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void onMessage(Message message, Session session) throws JMSException {
|
||||
if (message instanceof TextMessage) {
|
||||
TextMessage textMessage = (TextMessage) message;
|
||||
try {
|
||||
handleTextMessage(textMessage);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.error("Could not create message: " + ex.getMessage(), ex);
|
||||
TransportInputStream tis = new JmsTransportInputStream((TextMessage) message);
|
||||
TransportOutputStream tos;
|
||||
if (session == null) {
|
||||
tos = null;
|
||||
}
|
||||
else {
|
||||
tos = new JmsTransportOutputStream(session, ((TextMessage) message).getJMSCorrelationID());
|
||||
}
|
||||
handle(tis, tos, getMessageEndpoint());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.error("Could not handle message: " + ex.getMessage(), ex);
|
||||
throw new JMSException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new JmsTransportException("JmsTransportMessageListener can only handle TextMessages");
|
||||
throw new IllegalArgumentException("JmsTransportMessageListener can only handle TextMessages");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTextMessage(TextMessage textMessage) throws Exception {
|
||||
TransportInputStream tis = new JmsTransportInputStream(textMessage);
|
||||
TransportOutputStream tos = new JmsTransportOutputStream(getSession());
|
||||
|
||||
TransportContext previousTransportContext = TransportContextHolder.getTransportContext();
|
||||
TransportContextHolder.setTransportContext(new DefaultTransportContext(tis, tos));
|
||||
|
||||
try {
|
||||
WebServiceMessage messageRequest = messageFactory.createWebServiceMessage(tis);
|
||||
MessageContext messageContext = new DefaultMessageContext(messageRequest, messageFactory);
|
||||
endpoint.invoke(messageContext);
|
||||
if (messageContext.hasResponse()) {
|
||||
WebServiceMessage messageResponse = messageContext.getResponse();
|
||||
messageResponse.writeTo(tos);
|
||||
protected void handleResponse(TransportInputStream tis, TransportOutputStream tos, WebServiceMessage response)
|
||||
throws Exception {
|
||||
if (tos != null) {
|
||||
TextMessage requestMessage = ((JmsTransportInputStream) tis).getTextMessage();
|
||||
TextMessage responseMessage = ((JmsTransportOutputStream) tos).getTextMessage();
|
||||
Session session = ((JmsTransportOutputStream) tos).getSession();
|
||||
MessageProducer producer = session.createProducer(requestMessage.getJMSReplyTo());
|
||||
try {
|
||||
producer.send(responseMessage);
|
||||
}
|
||||
finally {
|
||||
JmsUtils.closeMessageProducer(producer);
|
||||
}
|
||||
}
|
||||
catch (NoEndpointFoundException ex) {
|
||||
// do nothing
|
||||
else {
|
||||
logger.warn("JMS Session is not available, sending of response is impossible");
|
||||
}
|
||||
finally {
|
||||
TransportContextHolder.setTransportContext(previousTransportContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Session getSession() {
|
||||
//TODO implement
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,26 +24,67 @@ import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.transport.TransportOutputStream;
|
||||
|
||||
/**
|
||||
* JMS specific implementation of the <code>TransportOutputStream</code> interface. Exposes a JMS
|
||||
* <code>TextMessage</code>, constructed lazily using a <code>Session</code>.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see #getTextMessage()
|
||||
*/
|
||||
public class JmsTransportOutputStream extends TransportOutputStream {
|
||||
|
||||
private TextMessage textMessage;
|
||||
|
||||
private Session session;
|
||||
private final Session session;
|
||||
|
||||
private String correlationId;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <code>JmsTransportOutputStream</code> with the given session.
|
||||
*
|
||||
* @param session the JMS session
|
||||
* @see javax.jms.Message#setJMSCorrelationID(String)
|
||||
*/
|
||||
public JmsTransportOutputStream(Session session) {
|
||||
Assert.notNull(session, "session must not be null");
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
private TextMessage getTextMessage() throws IOException {
|
||||
/**
|
||||
* Constructs a new instance of the <code>JmsTransportOutputStream</code> with the given session and correlation ID.
|
||||
* The correlation ID is used for creating a response to a request JMS message.
|
||||
*
|
||||
* @param session the JMS session
|
||||
* @param correlationId the correlation id
|
||||
* @see javax.jms.Message#setJMSCorrelationID(String)
|
||||
*/
|
||||
public JmsTransportOutputStream(Session session, String correlationId) {
|
||||
Assert.notNull(session, "session must not be null");
|
||||
Assert.hasLength(correlationId, "correlationId must not be null");
|
||||
this.session = session;
|
||||
this.correlationId = correlationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped JMS <code>Session</code>.
|
||||
*/
|
||||
public Session getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped JMS <code>TextMessage</code>. Created lazily.
|
||||
*/
|
||||
public TextMessage getTextMessage() throws IOException {
|
||||
if (textMessage == null) {
|
||||
try {
|
||||
textMessage = session.createTextMessage();
|
||||
if (StringUtils.hasLength(correlationId)) {
|
||||
textMessage.setJMSCorrelationID(correlationId);
|
||||
}
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
throw new IOException("Could not create text message: " + ex.getMessage());
|
||||
@@ -53,7 +94,7 @@ public class JmsTransportOutputStream extends TransportOutputStream {
|
||||
}
|
||||
|
||||
protected OutputStream getOutputStream() throws IOException {
|
||||
return new TextMessageOutputStream(getTextMessage());
|
||||
return new TextMessageOutputStream();
|
||||
}
|
||||
|
||||
public void addHeader(String name, String value) throws IOException {
|
||||
@@ -65,17 +106,11 @@ public class JmsTransportOutputStream extends TransportOutputStream {
|
||||
}
|
||||
}
|
||||
|
||||
private static class TextMessageOutputStream extends ByteArrayOutputStream {
|
||||
|
||||
private final TextMessage textMessage;
|
||||
|
||||
public TextMessageOutputStream(TextMessage textMessage) {
|
||||
this.textMessage = textMessage;
|
||||
}
|
||||
private class TextMessageOutputStream extends ByteArrayOutputStream {
|
||||
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
textMessage.setText(new String(toString("UTF-8")));
|
||||
getTextMessage().setText(new String(toString("UTF-8")));
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
throw new IOException("Could not set message text: " + ex.getMessage());
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.jms;
|
||||
|
||||
import javax.jms.BytesMessage;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.ws.MockWebServiceMessageFactory;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.endpoint.MessageEndpoint;
|
||||
|
||||
public class JmsTransportMessageListenerTest extends TestCase {
|
||||
|
||||
private static final String REQUEST = " <SOAP-ENV:Envelope\n" +
|
||||
" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
|
||||
" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" + " <SOAP-ENV:Body>\n" +
|
||||
" <m:GetLastTradePrice xmlns:m=\"Some-URI\">\n" + " <symbol>DIS</symbol>\n" +
|
||||
" </m:GetLastTradePrice>\n" + " </SOAP-ENV:Body>\n" + "</SOAP-ENV:Envelope>";
|
||||
|
||||
private JmsTransportMessageListener messageListener;
|
||||
|
||||
private MockControl messageControl;
|
||||
|
||||
private TextMessage requestMock;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
messageListener = new JmsTransportMessageListener();
|
||||
messageControl = MockControl.createControl(TextMessage.class);
|
||||
requestMock = (TextMessage) messageControl.getMock();
|
||||
messageListener.setMessageFactory(new MockWebServiceMessageFactory());
|
||||
}
|
||||
|
||||
public void testOnMessageInvalidMessage() throws Exception {
|
||||
MockControl mockControl = MockControl.createControl(BytesMessage.class);
|
||||
BytesMessage bytesMessage = (BytesMessage) mockControl.getMock();
|
||||
try {
|
||||
messageListener.onMessage(bytesMessage);
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testOnMessageNoResponse() throws Exception {
|
||||
messageControl.expectAndReturn(requestMock.getText(), REQUEST);
|
||||
messageControl.replay();
|
||||
|
||||
MessageEndpoint endpoint = new MessageEndpoint() {
|
||||
|
||||
public void invoke(MessageContext messageContext) throws Exception {
|
||||
}
|
||||
};
|
||||
messageListener.setMessageEndpoint(endpoint);
|
||||
|
||||
messageListener.onMessage(requestMock);
|
||||
|
||||
messageControl.verify();
|
||||
}
|
||||
|
||||
public void testOnMessageResponse() throws Exception {
|
||||
MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
Session sessionMock = (Session) sessionControl.getMock();
|
||||
MockControl producerControl = MockControl.createControl(MessageProducer.class);
|
||||
MessageProducer producerMock = (MessageProducer) producerControl.getMock();
|
||||
TextMessage responseMock = (TextMessage) messageControl.getMock();
|
||||
messageControl.expectAndReturn(requestMock.getText(), REQUEST);
|
||||
String correlationId = "correlationId";
|
||||
Destination replyTo = new Destination() {
|
||||
};
|
||||
messageControl.expectAndReturn(requestMock.getJMSCorrelationID(), correlationId);
|
||||
sessionControl.expectAndReturn(sessionMock.createTextMessage(), responseMock);
|
||||
responseMock.setJMSCorrelationID(correlationId);
|
||||
messageControl.expectAndReturn(requestMock.getJMSReplyTo(), replyTo);
|
||||
sessionControl.expectAndReturn(sessionMock.createProducer(replyTo), producerMock);
|
||||
producerMock.send(responseMock);
|
||||
messageControl.replay();
|
||||
sessionControl.replay();
|
||||
producerControl.replay();
|
||||
|
||||
MessageEndpoint endpoint = new MessageEndpoint() {
|
||||
|
||||
public void invoke(MessageContext messageContext) throws Exception {
|
||||
messageContext.getResponse();
|
||||
}
|
||||
};
|
||||
messageListener.setMessageEndpoint(endpoint);
|
||||
|
||||
messageListener.onMessage(requestMock, sessionMock);
|
||||
|
||||
messageControl.verify();
|
||||
sessionControl.verify();
|
||||
producerControl.verify();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user