diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverter.java
index 189bf9b218..2a0868549d 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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,11 +17,13 @@
package org.springframework.http.converter.xml;
import java.io.IOException;
+
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.oxm.Marshaller;
@@ -103,10 +105,20 @@ public class MarshallingHttpMessageConverter extends AbstractXmlHttpMessageConve
this.unmarshaller = unmarshaller;
}
+ @Override
+ public boolean canRead(Class> clazz, MediaType mediaType) {
+ return canRead(mediaType) && (this.unmarshaller != null) && this.unmarshaller.supports(clazz);
+ }
@Override
- public boolean supports(Class> clazz) {
- return this.unmarshaller.supports(clazz);
+ public boolean canWrite(Class> clazz, MediaType mediaType) {
+ return canWrite(mediaType) && (this.marshaller != null) && this.marshaller.supports(clazz);
+ }
+
+ @Override
+ protected boolean supports(Class> clazz) {
+ // should not be called, since we override canRead()/canWrite()
+ throw new UnsupportedOperationException();
}
@Override
@@ -134,5 +146,4 @@ public class MarshallingHttpMessageConverter extends AbstractXmlHttpMessageConve
throw new HttpMessageNotWritableException("Could not write [" + o + "]", ex);
}
}
-
}
diff --git a/spring-web/src/test/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverterTests.java
index 75de8e4019..ab016f5ae6 100644
--- a/spring-web/src/test/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverterTests.java
+++ b/spring-web/src/test/java/org/springframework/http/converter/xml/MarshallingHttpMessageConverterTests.java
@@ -16,36 +16,60 @@
package org.springframework.http.converter.xml;
-import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamSource;
-import org.junit.Before;
import org.junit.Test;
+import org.springframework.beans.TypeMismatchException;
import org.springframework.http.MediaType;
import org.springframework.http.MockHttpInputMessage;
import org.springframework.http.MockHttpOutputMessage;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.oxm.Marshaller;
+import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.Unmarshaller;
+import org.springframework.oxm.UnmarshallingFailureException;
import static org.junit.Assert.*;
-import static org.mockito.BDDMockito.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
/**
+ * Tests for {@link MarshallingHttpMessageConverter}.
+ *
* @author Arjen Poutsma
*/
public class MarshallingHttpMessageConverterTests {
- private MarshallingHttpMessageConverter converter;
+ @Test
+ public void canRead() throws Exception {
+ Unmarshaller unmarshaller = mock(Unmarshaller.class);
- private Marshaller marshaller;
+ when(unmarshaller.supports(Integer.class)).thenReturn(false);
+ when(unmarshaller.supports(String.class)).thenReturn(true);
- private Unmarshaller unmarshaller;
+ MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter();
+ converter.setUnmarshaller(unmarshaller);
- @Before
- public void setUp() {
- marshaller = mock(Marshaller.class);
- unmarshaller = mock(Unmarshaller.class);
- converter = new MarshallingHttpMessageConverter(marshaller, unmarshaller);
+ assertFalse(converter.canRead(Boolean.class, MediaType.TEXT_PLAIN));
+ assertFalse(converter.canRead(Integer.class, MediaType.TEXT_XML));
+ assertTrue(converter.canRead(String.class, MediaType.TEXT_XML));
+ }
+
+ @Test
+ public void canWrite() throws Exception {
+ Marshaller marshaller = mock(Marshaller.class);
+
+ when(marshaller.supports(Integer.class)).thenReturn(false);
+ when(marshaller.supports(String.class)).thenReturn(true);
+
+ MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter();
+ converter.setMarshaller(marshaller);
+
+ assertFalse(converter.canWrite(Boolean.class, MediaType.TEXT_PLAIN));
+ assertFalse(converter.canWrite(Integer.class, MediaType.TEXT_XML));
+ assertTrue(converter.canWrite(String.class, MediaType.TEXT_XML));
}
@Test
@@ -53,20 +77,84 @@ public class MarshallingHttpMessageConverterTests {
String body = "Hello World";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
- given(unmarshaller.unmarshal(isA(StreamSource.class))).willReturn(body);
+ Unmarshaller unmarshaller = mock(Unmarshaller.class);
+ when(unmarshaller.unmarshal(isA(StreamSource.class))).thenReturn(body);
+
+ MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter();
+ converter.setUnmarshaller(unmarshaller);
String result = (String) converter.read(Object.class, inputMessage);
assertEquals("Invalid result", body, result);
}
+ @Test(expected = TypeMismatchException.class)
+ public void readWithTypeMismatchException() throws Exception {
+ MockHttpInputMessage inputMessage = new MockHttpInputMessage(new byte[0]);
+
+ Marshaller marshaller = mock(Marshaller.class);
+ Unmarshaller unmarshaller = mock(Unmarshaller.class);
+ when(unmarshaller.unmarshal(isA(StreamSource.class))).thenReturn(Integer.valueOf(3));
+
+ MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(marshaller, unmarshaller);
+ converter.read(String.class, inputMessage);
+ }
+
+ @Test
+ public void readWithMarshallingFailureException() throws Exception {
+ MockHttpInputMessage inputMessage = new MockHttpInputMessage(new byte[0]);
+ UnmarshallingFailureException ex = new UnmarshallingFailureException("forced");
+
+ Unmarshaller unmarshaller = mock(Unmarshaller.class);
+ when(unmarshaller.unmarshal(isA(StreamSource.class))).thenThrow(ex);
+
+ MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter();
+ converter.setUnmarshaller(unmarshaller);
+
+ try {
+ converter.read(Object.class, inputMessage);
+ fail("HttpMessageNotReadableException should be thrown");
+ }
+ catch (HttpMessageNotReadableException e) {
+ assertTrue("Invalid exception hierarchy", e.getCause() == ex);
+ }
+ }
+
@Test
public void write() throws Exception {
String body = "Hello World";
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
+ Marshaller marshaller = mock(Marshaller.class);
+ doNothing().when(marshaller).marshal(eq(body), isA(Result.class));
+
+ MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(marshaller);
converter.write(body, null, outputMessage);
- assertEquals("Invalid content-type", new MediaType("application", "xml"),
- outputMessage.getHeaders().getContentType());
- verify(marshaller).marshal(eq(body), isA(StreamResult.class));
+
+ assertEquals("Invalid content-type", new MediaType("application", "xml"), outputMessage.getHeaders()
+ .getContentType());
+ }
+
+ @Test
+ public void writeWithMarshallingFailureException() throws Exception {
+ String body = "Hello World";
+ MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
+ MarshallingFailureException ex = new MarshallingFailureException("forced");
+
+ Marshaller marshaller = mock(Marshaller.class);
+ doThrow(ex).when(marshaller).marshal(eq(body), isA(Result.class));
+
+ try {
+ MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(marshaller);
+ converter.write(body, null, outputMessage);
+ fail("HttpMessageNotWritableException should be thrown");
+ }
+ catch (HttpMessageNotWritableException e) {
+ assertTrue("Invalid exception hierarchy", e.getCause() == ex);
+ }
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void supports() throws Exception {
+ new MarshallingHttpMessageConverter().supports(Object.class);
}
}