Skip to content

Commit 162bd31

Browse files
committed
#416 - Alter ResourceAssemblerSupport.toResources to return Resources
To avoid confusion about what to return on a Spring MVC endpoint, change toResources to not return `List<D>`, but instead `Resources<D>`. This clearly ensures when used to construct Spring MVC endpoints, will return a type Spring HATEOAS will properly marshal. Related issues: #493 Related pull requests: #572
1 parent ef82543 commit 162bd31

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

src/main/java/org/springframework/hateoas/mvc/ResourceAssemblerSupport.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import org.springframework.beans.BeanUtils;
2424
import org.springframework.hateoas.ResourceAssembler;
2525
import org.springframework.hateoas.ResourceSupport;
26+
import org.springframework.hateoas.Resources;
2627
import org.springframework.util.Assert;
28+
import org.springframework.util.ClassUtils;
2729

2830
/**
2931
* Base class to implement {@link ResourceAssembler}s. Will automate {@link ResourceSupport} instance creation and make
@@ -57,7 +59,9 @@ public ResourceAssemblerSupport(Class<?> controllerClass, Class<D> resourceType)
5759
* @see #toResource(Object)
5860
* @param entities must not be {@literal null}.
5961
* @return
62+
* @deprecated Results of this method may not render properly if returned by a Spring MVC endpoint. Cast your {@link Iterable} parameter as an {@link Object} to use the new API, which does.
6063
*/
64+
@Deprecated
6165
public List<D> toResources(Iterable<? extends T> entities) {
6266

6367
Assert.notNull(entities, "Entities must not be null!");
@@ -70,6 +74,29 @@ public List<D> toResources(Iterable<? extends T> entities) {
7074
return result;
7175
}
7276

77+
/**
78+
* Converts an {@link Iterable} collection of entities into {@link Resources}. To maintain backward compatibility, using this method requires casting the {@link Iterable} input as an {@link Object}.
79+
*
80+
* TODO: Migrate from {@link Object} to {@link Iterable} when old method is removed and remove the runtime {@link ClassUtils#isAssignable(Class, Class)} check.
81+
*
82+
* @param entities
83+
* @return
84+
*/
85+
public Resources<D> toResources(Object entities) {
86+
87+
Assert.isTrue(ClassUtils.isAssignable(Iterable.class, entities.getClass()), "Entities must be Iterable!");
88+
Iterable<? extends T> iterableEntities = (Iterable<? extends T>) entities;
89+
90+
Assert.notNull(entities, "Entities must not be null!");
91+
List<D> result = new ArrayList<D>();
92+
93+
for (T entity : iterableEntities) {
94+
result.add(toResource(entity));
95+
}
96+
97+
return new Resources(result);
98+
}
99+
73100
/**
74101
* Creates a new resource with a self link to the given id.
75102
*

src/test/java/org/springframework/hateoas/mvc/IdentifiableResourceAssemblerSupportUnitTest.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.hateoas.Link;
2929
import org.springframework.hateoas.LinkBuilder;
3030
import org.springframework.hateoas.ResourceSupport;
31+
import org.springframework.hateoas.Resources;
3132
import org.springframework.hateoas.TestUtils;
3233
import org.springframework.web.bind.annotation.RequestMapping;
3334

@@ -78,7 +79,7 @@ public void unwrapsIdentifyablesForParameters() {
7879
}
7980

8081
@Test
81-
public void convertsEntitiesToResources() {
82+
public void convertsEntitiesToResourcesUsingDeprecatedSignature() {
8283

8384
Person first = new Person();
8485
first.id = 1L;
@@ -99,6 +100,28 @@ public void convertsEntitiesToResources() {
99100
assertThat(result, hasItems(firstResource, secondResource));
100101
}
101102

103+
@Test
104+
public void convertsEntitiesToResourcesUsingNewSignature() {
105+
106+
Person first = new Person();
107+
first.id = 1L;
108+
Person second = new Person();
109+
second.id = 2L;
110+
111+
Resources<PersonResource> result = assembler.toResources((Object) Arrays.asList(first, second));
112+
113+
LinkBuilder builder = linkTo(PersonController.class);
114+
115+
PersonResource firstResource = new PersonResource();
116+
firstResource.add(builder.slash(1L).withSelfRel());
117+
118+
PersonResource secondResource = new PersonResource();
119+
secondResource.add(builder.slash(1L).withSelfRel());
120+
121+
assertThat(result.getContent().size(), is(2));
122+
assertThat(result, hasItems(firstResource, secondResource));
123+
}
124+
102125
@RequestMapping("/people")
103126
static class PersonController {
104127

0 commit comments

Comments
 (0)