Allow empty request body for POST/PUT/DELETE REST endpoints that expect List/Map as input

If a REST endpoint expects a List or a Map as input, but the user
provides an empty request body we currently fail with 500 Internal
Server Error, e.g.: POST /accounts/<account-id>/watched.projects

Instead just create an empty List/Map and provide it to the REST
endpoint. This is consistent with instantiating empty Input objects when
the REST endpoint expects a non-generic input type and the user provides
no body.

Change-Id: I78fe66b2d0f63a6078411dd50a55196424d88490
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2018-06-08 15:01:31 +02:00
parent 8954ede856
commit 2f020e92e2
2 changed files with 15 additions and 1 deletions

View File

@@ -846,16 +846,25 @@ public class RestApiServlet extends HttpServlet {
throw new BadRequestException("Expected JSON object");
}
@SuppressWarnings("unchecked")
private static Object createInstance(Type type)
throws NoSuchMethodException, InstantiationException, IllegalAccessException,
InvocationTargetException {
if (type instanceof Class) {
@SuppressWarnings("unchecked")
Class<Object> clazz = (Class<Object>) type;
Constructor<Object> c = clazz.getDeclaredConstructor();
c.setAccessible(true);
return c.newInstance();
}
if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) type).getRawType();
if (rawType instanceof Class && List.class.isAssignableFrom((Class<Object>) rawType)) {
return new ArrayList<>();
}
if (rawType instanceof Class && Map.class.isAssignableFrom((Class<Object>) rawType)) {
return new HashMap<>();
}
}
throw new InstantiationException("Cannot make " + type);
}

View File

@@ -235,4 +235,9 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
assertThat(persistedWatchedProjects).doesNotContain(pwi);
assertThat(persistedWatchedProjects).containsAllIn(projectsToWatch);
}
@Test
public void postWithoutBody() throws Exception {
adminRestSession.post("/accounts/" + admin.username + "/watched.projects").assertOK();
}
}