Skip to content

Commit 8cd6da9

Browse files
Return 400 Bad Request when request body converter returns incompatible type.
When text/uri-list is posted to a non-association endpoint, UriListHttpMessageConverter returns a CollectionModel instead of the target domain type. The argument resolver then fails with an internal exception mapped to 500. This change validates the converter output type and throws HttpMessageNotReadableException (400) instead. Fixes #1194 Signed-off-by: Babalola Opeyemi Daniel <babaloladanielope@gmail.com>
1 parent 9861a23 commit 8cd6da9

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/PersistentEntityResourceHandlerMethodArgumentResolver.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
* @author Jon Brisbin
6464
* @author Oliver Gierke
6565
* @author Mark Paluch
66+
* @author Babalola Opeyemi Daniel
6667
*/
6768
public class PersistentEntityResourceHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
6869

@@ -139,6 +140,10 @@ public boolean supportsParameter(MethodParameter parameter) {
139140
throw new HttpMessageNotReadableException(String.format(ERROR_MESSAGE, domainType), request);
140141
}
141142

143+
if (!domainType.isInstance(newObject)) {
144+
throw new HttpMessageNotReadableException(String.format(ERROR_MESSAGE, domainType), request);
145+
}
146+
142147
PersistentEntity<?, ?> entity = resourceInformation.getPersistentEntity();
143148

144149
if (!id.isPresent()) {

spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/PersistentEntityResourceHandlerMethodArgumentResolverUnitTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
import org.springframework.data.rest.webmvc.support.BackendIdHandlerMethodArgumentResolver;
4343
import org.springframework.http.HttpInputMessage;
4444
import org.springframework.http.MediaType;
45+
import org.springframework.hateoas.CollectionModel;
4546
import org.springframework.http.converter.HttpMessageConverter;
47+
import org.springframework.http.converter.HttpMessageNotReadableException;
4648
import org.springframework.mock.web.MockHttpServletRequest;
4749
import org.springframework.plugin.core.PluginRegistry;
4850
import org.springframework.web.bind.support.WebDataBinderFactory;
@@ -55,6 +57,7 @@
5557
* Unit tests for {@link PersistentEntityResourceHandlerMethodArgumentResolver}.
5658
*
5759
* @author Oliver Gierke
60+
* @author Babalola Opeyemi Daniel
5861
*/
5962
class PersistentEntityResourceHandlerMethodArgumentResolverUnitTests {
6063

@@ -124,6 +127,23 @@ Arrays.<HttpMessageConverter<?>> asList(converter), rootResourceResolver, backen
124127
});
125128
}
126129

130+
@Test // GH-1194
131+
@SuppressWarnings("unchecked")
132+
void rejectsRequestBodyIfConverterReturnsIncompatibleType() throws Exception {
133+
134+
PersistentEntityResourceHandlerMethodArgumentResolver argumentResolver = new PersistentEntityResourceHandlerMethodArgumentResolver(
135+
Arrays.<HttpMessageConverter<?>> asList(converter), rootResourceResolver, backendIdResolver, reader,
136+
PluginRegistry.empty(), FACTORY);
137+
138+
HttpServletRequest request = new MockHttpServletRequest("POST", "/foo");
139+
140+
doReturn(CollectionModel.empty()).when(converter).read(Mockito.any(Class.class), Mockito.any(HttpInputMessage.class));
141+
142+
assertThatExceptionOfType(HttpMessageNotReadableException.class).isThrownBy(() -> {
143+
argumentResolver.resolveArgument(null, null, new ServletWebRequest(request), null);
144+
});
145+
}
146+
127147
private void setupRootResourceInfoFor(Class<?> type) throws Exception {
128148

129149
RootResourceInformation information = mock(RootResourceInformation.class);

0 commit comments

Comments
 (0)