MultivaluedMapEntityProvider implements EntityProvider<MultivaluedMap<String, String>> { @Override @SuppressWarnings("unchecked") public MultivaluedMap<String, String> readFrom(Class<MultivaluedMap<String, String>> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException { ApplicationContext context = ApplicationContext.getCurrent(); Object decodedMap = context.getAttributes().get("org.everrest.provider.entity.decoded.form"); if (decodedMap != null) { return (MultivaluedMap<String, String>)decodedMap; } MultivaluedMap<String, String> encodedForm = new MultivaluedMapImpl(); MultivaluedMap<String, String> decodedForm = new MultivaluedMapImpl(); StringBuilder sb = new StringBuilder(); int r; while ((r = entityStream.read()) != -1) { if (r != '&') { sb.append((char)r); } else { parseKeyValuePair(sb.toString().trim(), encodedForm, decodedForm); sb.setLength(0); } } parseKeyValuePair(sb.toString().trim(), encodedForm, decodedForm); if (decodedForm.isEmpty() && httpRequest != null) { httpRequest.getParameterMap() .entrySet() .stream() .filter(e -> e.getValue() != null) .forEach(e -> decodedForm.addAll(e.getKey(), e.getValue())); } context.getAttributes().put("org.everrest.provider.entity.decoded.form", decodedForm); context.getAttributes().put("org.everrest.provider.entity.encoded.form", encodedForm); return decodedForm; } MultivaluedMapEntityProvider(@Context HttpServletRequest httpRequest); @Override boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType); @Override @SuppressWarnings("unchecked") MultivaluedMap<String, String> readFrom(Class<MultivaluedMap<String, String>> type,
                                                   Type genericType,
                                                   Annotation[] annotations,
                                                   MediaType mediaType,
                                                   MultivaluedMap<String, String> httpHeaders,
                                                   InputStream entityStream); @Override long getSize(MultivaluedMap<String, String> multivaluedMap, Class<?> type, Type genericType, Annotation[] annotations,
                        MediaType mediaType); @Override boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType); @Override void writeTo(MultivaluedMap<String, String> multivaluedMap,
                        Class<?> type,
                        Type genericType,
                        Annotation[] annotations,
                        MediaType mediaType,
                        MultivaluedMap<String, Object> httpHeaders,
                        OutputStream entityStream);  }
@SuppressWarnings("unchecked") @Test public void readsContentOfEntityStreamAsMultivaluedMap() throws Exception { MultivaluedMap<String, String> multivaluedMap = multivaluedMapEntityProvider.readFrom((Class)MultivaluedMap.class, multiValuedMapGenericType, null, APPLICATION_FORM_URLENCODED_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(testContent)); Map<String, List<String>> decodedMap = ImmutableMap.of("foo", newArrayList("to be or not to be"), "bar", newArrayList("hello world")); Map<String, List<String>> encodedMap = ImmutableMap.of("foo", newArrayList("to%20be%20or%20not%20to%20be"), "bar", newArrayList("hello%20world")); assertEquals(decodedMap, multivaluedMap); ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class); verify(context.getAttributes()).put(eq("org.everrest.provider.entity.decoded.form"), argumentCaptor.capture()); assertEquals(decodedMap, argumentCaptor.getValue()); verify(context.getAttributes()).put(eq("org.everrest.provider.entity.encoded.form"), argumentCaptor.capture()); assertEquals(encodedMap, argumentCaptor.getValue()); }
@SuppressWarnings("unchecked") @Test public void getsParsedDecodedMultivaluedMapFromContextIfPresent() throws Exception { MultivaluedMap<String, String> decodedMap = new MultivaluedHashMap<>(); when(context.getAttributes().get("org.everrest.provider.entity.decoded.form")).thenReturn(decodedMap); MultivaluedMap<String, String> multivaluedMap = multivaluedMapEntityProvider.readFrom((Class)MultivaluedMap.class, multiValuedMapGenericType, null, APPLICATION_FORM_URLENCODED_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(testContent)); assertSame(decodedMap, multivaluedMap); }
@SuppressWarnings("unchecked") @Test public void getsParametersFromServletRequestWhenEntityStreamIsEmpty() throws Exception { Map<String, String[]> parameterMap = ImmutableMap.of("foo", new String[]{"to be or not to be"}, "bar", new String[]{"hello world"}); when(servletRequest.getParameterMap()).thenReturn(parameterMap); MultivaluedMap<String, String> multivaluedMap = multivaluedMapEntityProvider.readFrom((Class)MultivaluedMap.class, multiValuedMapGenericType, null, APPLICATION_FORM_URLENCODED_TYPE, new MultivaluedMapImpl(), new EmptyInputStream()); Map<String, List<String>> decodedMap = ImmutableMap.of("foo", newArrayList("to be or not to be"), "bar", newArrayList("hello world")); assertEquals(decodedMap, multivaluedMap); ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class); verify(context.getAttributes()).put(eq("org.everrest.provider.entity.decoded.form"), argumentCaptor.capture()); assertEquals(decodedMap, argumentCaptor.getValue()); verify(context.getAttributes()).put(eq("org.everrest.provider.entity.encoded.form"), argumentCaptor.capture()); assertTrue(((MultivaluedMap)argumentCaptor.getValue()).isEmpty()); }
@SuppressWarnings("unchecked") @Test public void readsContentOfEntityStreamAsMultivaluedMapWhenFormFieldMissedValue() throws Exception { testContent = "foo&bar=hello%20world".getBytes("UTF-8"); MultivaluedMap<String, String> multivaluedMap = multivaluedMapEntityProvider.readFrom((Class)MultivaluedMap.class, multiValuedMapGenericType, null, APPLICATION_FORM_URLENCODED_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(testContent)); Map<String, List<String>> decodedMap = ImmutableMap.of("foo", newArrayList(""), "bar", newArrayList("hello world")); assertEquals(decodedMap, multivaluedMap); }