RestServletRequestParamReader extends ServletRequestParamReader { @Override public Object[] read() throws ServiceException { try { EndpointMethod method = getMethod(); if (method.getParameterClasses().length == 0) { return new Object[0]; } HttpServletRequest servletRequest = endpointsContext.getRequest(); JsonNode node; if (ServletFileUpload.isMultipartContent(servletRequest)) { try { ServletFileUpload upload = new ServletFileUpload(); FileItemIterator iter = upload.getItemIterator(servletRequest); ObjectNode obj = (ObjectNode) objectReader.createObjectNode(); while (iter.hasNext()) { FileItemStream item = iter.next(); if (item.isFormField()) { obj.put(item.getFieldName(), IoUtil.readStream(item.openStream())); } else { throw new BadRequestException("unable to parse multipart form field"); } } node = obj; } catch (FileUploadException e) { throw new BadRequestException("unable to parse multipart request", e); } } else { String requestBody = IoUtil.readRequestBody(servletRequest); logger.atFine().log("requestBody=%s", requestBody); node = Strings.isEmptyOrWhitespace(requestBody) ? objectReader.createObjectNode() : objectReader.readTree(requestBody); } if (!node.isObject()) { throw new BadRequestException("expected a JSON object body"); } ObjectNode body = (ObjectNode) node; Map<String, Class<?>> parameterMap = getParameterMap(method); for (Enumeration<?> e = servletRequest.getParameterNames(); e.hasMoreElements(); ) { String parameterName = (String) e.nextElement(); if (!body.has(parameterName)) { Class<?> parameterClass = parameterMap.get(parameterName); ApiParameterConfig parameterConfig = parameterConfigMap.get(parameterName); if (parameterClass != null && parameterConfig.isRepeated()) { ArrayNode values = body.putArray(parameterName); for (String value : servletRequest.getParameterValues(parameterName)) { values.add(value); } } else { body.put(parameterName, servletRequest.getParameterValues(parameterName)[0]); } } } for (Entry<String, String> entry : rawPathParameters.entrySet()) { String parameterName = entry.getKey(); Class<?> parameterClass = parameterMap.get(parameterName); if (parameterClass != null && !body.has(parameterName)) { if (parameterConfigMap.get(parameterName).isRepeated()) { ArrayNode values = body.putArray(parameterName); for (String value : COMPOSITE_PATH_SPLITTER.split(entry.getValue())) { values.add(value); } } else { body.put(parameterName, entry.getValue()); } } } for (Entry<String, ApiParameterConfig> entry : parameterConfigMap.entrySet()) { if (!body.has(entry.getKey()) && entry.getValue().getDefaultValue() != null) { body.put(entry.getKey(), entry.getValue().getDefaultValue()); } } return deserializeParams(body); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | IOException e) { logger.atInfo().withCause(e).log("Unable to read request parameter(s)"); throw new BadRequestException(e); } } RestServletRequestParamReader(EndpointMethod method,
      EndpointsContext endpointsContext, ServletContext servletContext,
      ApiSerializationConfig serializationConfig, ApiMethodConfig methodConfig); @Override Object[] read();  }
@Test public void repeatedQueryParameter() throws Exception { request.addParameter("dates", NOV_1.toString()); request.addParameter("dates", NOV_2.toString()); request.addParameter("defaultvalue", NOV_2.toString()); RestServletRequestParamReader reader = createReader(ImmutableMap.of("path", "1234")); Object[] params = reader.read(); assertThat(params).hasLength(endpointMethod.getParameterClasses().length); assertThat(params).asList() .containsExactly( 1234L, ImmutableList.of(NOV_1, NOV_2), NOV_2, new TestResource()) .inOrder(); }
@Test public void defaultValue() throws Exception { RestServletRequestParamReader reader = createReader(ImmutableMap.of("path", "1234")); Object[] params = reader.read(); assertThat(params).hasLength(endpointMethod.getParameterClasses().length); assertThat(params).asList() .containsExactly( 1234L, null, JAN_1, new TestResource()); }
@Test public void resourceOverridesQuery() throws Exception { request.addParameter("query", NOV_1.toString()); request.addParameter("defaultvalue", NOV_2.toString()); request.setContent( String.format("{\"query\": \"%s\"}", NOV_2).getBytes(StandardCharsets.UTF_8)); RestServletRequestParamReader reader = createReader(ImmutableMap.of("path", "1234")); Object[] params = reader.read(); assertThat(params).hasLength(endpointMethod.getParameterClasses().length); assertThat(params).asList() .containsExactly( 1234L, null, NOV_2, new TestResource(NOV_2)) .inOrder(); }
@Test public void queryOverridesPath() throws Exception { request.addParameter("path", "4321"); request.addParameter("defaultvalue", NOV_2.toString()); RestServletRequestParamReader reader = createReader(ImmutableMap.of("path", "1234")); Object[] params = reader.read(); assertThat(params).hasLength(endpointMethod.getParameterClasses().length); assertThat(params).asList() .containsExactly( 4321L, null, NOV_2, new TestResource()) .inOrder(); }
@Test public void nonObjectRequest() throws Exception { try { request.setContent("\"a string\"".getBytes(StandardCharsets.UTF_8)); RestServletRequestParamReader reader = createReader(ImmutableMap.of("path", "1234")); reader.read(); fail("expected BadRequestException"); } catch (BadRequestException e) { } }
@Test public void gzippedRequest() throws Exception { request.addParameter("path", "1234"); request.setContent(compress( String.format("{\"query\": \"%s\"}", NOV_2).getBytes(StandardCharsets.UTF_8))); request.addHeader("Content-Encoding", "gzip"); RestServletRequestParamReader reader = createReader(ImmutableMap.of("path", "1234")); Object[] params = reader.read(); assertThat(params).hasLength(endpointMethod.getParameterClasses().length); assertThat(params).asList() .containsExactly( 1234L, null, JAN_1, new TestResource(NOV_2)) .inOrder(); }
@Test public void arrayPathParam() throws Exception { endpointMethod = EndpointMethod.create(TestApi.class, TestApi.class.getMethod("testArrayPathParam", ArrayList.class)); methodConfig = apiConfig.getApiClassConfig().getMethods().get(endpointMethod); RestServletRequestParamReader reader = createReader(ImmutableMap.of("values", "4,3,2,1")); Object[] params = reader.read(); assertThat(params).hasLength(endpointMethod.getParameterClasses().length); assertThat(params).asList() .containsExactly(ImmutableList.of("4", "3", "2", "1")); }
@Test public void multipartFormData() throws Exception { endpointMethod = EndpointMethod.create(TestApi.class, TestApi.class.getMethod("testFormData", String.class, Integer.class)); methodConfig = apiConfig.getApiClassConfig().getMethods().get(endpointMethod); request.setContentType("multipart/form-data; boundary=----test"); request.setMethod("POST"); String requestContent = "------test\r\n" + "Content-Disposition: form-data; name=\"foo\"\r\n\r\n" + "test\r\n" + "------test\r\n" + "Content-Disposition: form-data; name=\"bar\"\r\n\r\n" + "1234\r\n" + "------test--\r\n"; request.setContent(requestContent.getBytes(StandardCharsets.UTF_8)); RestServletRequestParamReader reader = createReader(ImmutableMap.<String, String>of()); Object[] params = reader.read(); assertThat(params).hasLength(endpointMethod.getParameterClasses().length); assertThat(params).asList() .containsExactly("test", 1234); }