Support null return value for JAXB
Support null return values for JAXB MethodReturnValueHandlers.\ Issue: SWS-867
This commit is contained in:
@@ -231,10 +231,7 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter
|
||||
Object[] args = getMethodArguments(messageContext, methodEndpoint);
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
StringBuilder builder = new StringBuilder("Invoking [");
|
||||
builder.append(methodEndpoint).append("] with arguments ");
|
||||
builder.append(Arrays.asList(args));
|
||||
logger.trace(builder.toString());
|
||||
logger.trace("Invoking [" + methodEndpoint + "] with arguments " + Arrays.asList(args));
|
||||
}
|
||||
|
||||
Object returnValue = methodEndpoint.invoke(args);
|
||||
|
||||
@@ -151,6 +151,9 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc
|
||||
|
||||
public void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
|
||||
throws Exception {
|
||||
if (returnValue == null) {
|
||||
return;
|
||||
}
|
||||
Marshaller marshaller = getMarshaller();
|
||||
Assert.state(marshaller != null, "marshaller must not be null");
|
||||
|
||||
|
||||
@@ -42,6 +42,13 @@ import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
@@ -50,12 +57,6 @@ import org.springframework.ws.stream.StreamingPayload;
|
||||
import org.springframework.ws.stream.StreamingWebServiceMessage;
|
||||
import org.springframework.xml.transform.TraxUtils;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver
|
||||
* MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler
|
||||
@@ -71,7 +72,18 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
|
||||
|
||||
private final ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>();
|
||||
|
||||
/**
|
||||
@Override
|
||||
public final void handleReturnValue(MessageContext messageContext,
|
||||
MethodParameter returnType, Object returnValue) throws Exception {
|
||||
if (returnValue != null) {
|
||||
handleReturnValueInternal(messageContext, returnType, returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void handleReturnValueInternal(MessageContext messageContext,
|
||||
MethodParameter returnType, Object returnValue) throws Exception;
|
||||
|
||||
/**
|
||||
* Marshals the given {@code jaxbElement} to the response payload of the given message context.
|
||||
*
|
||||
* @param messageContext the message context to marshal to
|
||||
|
||||
@@ -54,7 +54,8 @@ public class JaxbElementPayloadMethodProcessor extends AbstractJaxb2PayloadMetho
|
||||
return JAXBElement.class.isAssignableFrom(parameterType);
|
||||
}
|
||||
|
||||
public void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
|
||||
@Override
|
||||
protected void handleReturnValueInternal(MessageContext messageContext, MethodParameter returnType, Object returnValue)
|
||||
throws JAXBException {
|
||||
JAXBElement<?> element = (JAXBElement<?>) returnValue;
|
||||
marshalToResponsePayload(messageContext, element.getDeclaredType(), element);
|
||||
|
||||
@@ -60,7 +60,8 @@ public class XmlRootElementPayloadMethodProcessor extends AbstractJaxb2PayloadMe
|
||||
return parameterType.isAnnotationPresent(XmlRootElement.class);
|
||||
}
|
||||
|
||||
public void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
|
||||
@Override
|
||||
protected void handleReturnValueInternal(MessageContext messageContext, MethodParameter returnType, Object returnValue)
|
||||
throws JAXBException {
|
||||
Class<?> parameterType = returnType.getParameterType();
|
||||
marshalToResponsePayload(messageContext, parameterType, returnValue);
|
||||
|
||||
@@ -20,6 +20,11 @@ import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.easymock.EasyMock.*;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.ws.MockWebServiceMessage;
|
||||
import org.springframework.ws.MockWebServiceMessageFactory;
|
||||
@@ -29,12 +34,6 @@ import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.easymock.EasyMock.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
public class DefaultMethodEndpointAdapterTest {
|
||||
|
||||
@@ -48,21 +47,25 @@ public class DefaultMethodEndpointAdapterTest {
|
||||
|
||||
private MethodEndpoint supportedEndpoint;
|
||||
|
||||
private MethodEndpoint nullReturnValue;
|
||||
|
||||
private MethodEndpoint unsupportedEndpoint;
|
||||
|
||||
private MethodEndpoint exceptionEndpoint;
|
||||
|
||||
private String supportedArgument;
|
||||
|
||||
@Before
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
adapter = new DefaultMethodEndpointAdapter();
|
||||
argumentResolver1 = createMock("stringResolver", MethodArgumentResolver.class);
|
||||
argumentResolver2 = createMock("intResolver", MethodArgumentResolver.class);
|
||||
returnValueHandler = createMock(MethodReturnValueHandler.class);
|
||||
adapter.setMethodArgumentResolvers(Arrays.asList(argumentResolver1, argumentResolver2));
|
||||
adapter.setMethodReturnValueHandlers(Collections.singletonList(returnValueHandler));
|
||||
adapter.setMethodReturnValueHandlers(
|
||||
Collections.singletonList(returnValueHandler));
|
||||
supportedEndpoint = new MethodEndpoint(this, "supported", String.class, Integer.class);
|
||||
nullReturnValue = new MethodEndpoint(this, "nullReturnValue", String.class);
|
||||
unsupportedEndpoint = new MethodEndpoint(this, "unsupported", String.class);
|
||||
exceptionEndpoint = new MethodEndpoint(this, "exception", String.class);
|
||||
}
|
||||
@@ -146,6 +149,27 @@ public class DefaultMethodEndpointAdapterTest {
|
||||
verify(argumentResolver1, argumentResolver2, returnValueHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeNullReturnValue() throws Exception {
|
||||
MockWebServiceMessage request = new MockWebServiceMessage("<root xmlns='http://springframework.org'/>");
|
||||
MessageContext messageContext = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
|
||||
|
||||
String value = "Foo";
|
||||
|
||||
expect(argumentResolver1.supportsParameter(isA(MethodParameter.class))).andReturn(true);
|
||||
expect(argumentResolver1.resolveArgument(eq(messageContext), isA(MethodParameter.class))).andReturn(value);
|
||||
|
||||
expect(returnValueHandler.supportsReturnType(isA(MethodParameter.class))).andReturn(true);
|
||||
returnValueHandler.handleReturnValue(eq(messageContext), isA(MethodParameter.class), isNull());
|
||||
|
||||
replay(argumentResolver1, argumentResolver2, returnValueHandler);
|
||||
|
||||
adapter.invoke(messageContext, nullReturnValue);
|
||||
assertEquals("Invalid argument passed", value, supportedArgument);
|
||||
|
||||
verify(argumentResolver1, argumentResolver2, returnValueHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeException() throws Exception {
|
||||
MockWebServiceMessage request = new MockWebServiceMessage("<root xmlns='http://springframework.org'/>");
|
||||
@@ -177,6 +201,11 @@ public class DefaultMethodEndpointAdapterTest {
|
||||
|
||||
}
|
||||
|
||||
public String nullReturnValue(String s) {
|
||||
supportedArgument = s;
|
||||
return null;
|
||||
}
|
||||
|
||||
public String unsupported(String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.ws.server.endpoint.adapter.method.jaxb;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
@@ -26,6 +25,11 @@ import javax.xml.namespace.QName;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.ws.MockWebServiceMessage;
|
||||
import org.springframework.ws.MockWebServiceMessageFactory;
|
||||
@@ -38,14 +42,6 @@ import org.springframework.ws.soap.axiom.AxiomSoapMessage;
|
||||
import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
|
||||
import org.springframework.xml.transform.StringResult;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class JaxbElementPayloadMethodProcessorTest {
|
||||
|
||||
private JaxbElementPayloadMethodProcessor processor;
|
||||
@@ -88,7 +84,7 @@ public class JaxbElementPayloadMethodProcessorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleReturnValue() throws JAXBException, IOException, SAXException {
|
||||
public void handleReturnValue() throws Exception {
|
||||
MessageContext messageContext = new DefaultMessageContext(new MockWebServiceMessageFactory());
|
||||
|
||||
MyType type = new MyType();
|
||||
@@ -101,7 +97,7 @@ public class JaxbElementPayloadMethodProcessorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleReturnValueString() throws JAXBException, IOException, SAXException {
|
||||
public void handleReturnValueString() throws Exception {
|
||||
MessageContext messageContext = new DefaultMessageContext(new MockWebServiceMessageFactory());
|
||||
|
||||
String s = "Foo";
|
||||
@@ -112,6 +108,15 @@ public class JaxbElementPayloadMethodProcessorTest {
|
||||
assertXMLEqual("<string xmlns='http://springframework.org'>Foo</string>", response.getPayloadAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleNullReturnValue() throws Exception {
|
||||
MessageContext messageContext =
|
||||
new DefaultMessageContext(new MockWebServiceMessageFactory());
|
||||
|
||||
processor.handleReturnValue(messageContext, stringReturnType, null);
|
||||
assertFalse("context has response", messageContext.hasResponse());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleReturnValueAxiom() throws Exception {
|
||||
AxiomSoapMessageFactory messageFactory = new AxiomSoapMessageFactory();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.ws.server.endpoint.adapter.method.jaxb;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
@@ -25,6 +24,11 @@ import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.ws.MockWebServiceMessage;
|
||||
import org.springframework.ws.MockWebServiceMessageFactory;
|
||||
@@ -37,14 +41,6 @@ import org.springframework.ws.soap.axiom.AxiomSoapMessage;
|
||||
import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
|
||||
import org.springframework.xml.transform.StringResult;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class XmlRootElementPayloadMethodProcessorTest {
|
||||
|
||||
private XmlRootElementPayloadMethodProcessor processor;
|
||||
@@ -67,13 +63,14 @@ public class XmlRootElementPayloadMethodProcessorTest {
|
||||
public void supportsParameter() {
|
||||
assertTrue("processor does not support @XmlRootElement parameter",
|
||||
processor.supportsParameter(rootElementParameter));
|
||||
assertTrue("processor does not support @XmlType parameter", processor.supportsParameter(typeParameter));
|
||||
assertTrue("processor does not support @XmlType parameter", processor.supportsParameter(
|
||||
typeParameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsReturnType() {
|
||||
assertTrue("processor does not support @XmlRootElement return type",
|
||||
processor.supportsReturnType(rootElementReturnType));
|
||||
processor.supportsReturnType(rootElementReturnType));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -99,7 +96,7 @@ public class XmlRootElementPayloadMethodProcessorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleReturnValue() throws JAXBException, IOException, SAXException {
|
||||
public void handleReturnValue() throws Exception {
|
||||
MessageContext messageContext = new DefaultMessageContext(new MockWebServiceMessageFactory());
|
||||
|
||||
MyRootElement rootElement = new MyRootElement();
|
||||
@@ -110,6 +107,15 @@ public class XmlRootElementPayloadMethodProcessorTest {
|
||||
assertXMLEqual("<root xmlns='http://springframework.org'><string>Foo</string></root>", response.getPayloadAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleNullReturnValue() throws Exception {
|
||||
MessageContext messageContext = new DefaultMessageContext(new MockWebServiceMessageFactory());
|
||||
|
||||
MyRootElement rootElement = null;
|
||||
processor.handleReturnValue(messageContext, rootElementReturnType, rootElement);
|
||||
assertFalse("context has response", messageContext.hasResponse());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleReturnValueAxiom() throws Exception {
|
||||
AxiomSoapMessageFactory messageFactory = new AxiomSoapMessageFactory();
|
||||
|
||||
Reference in New Issue
Block a user