Skip to content

Commit

Permalink
First list deserialization test
Browse files Browse the repository at this point in the history
  • Loading branch information
trickl committed Sep 10, 2019
1 parent 5344e7b commit 32a4476
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,21 @@
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.github.trickl.jackson.module.httpquery.annotations.HttpQueryDelimited;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class HttpQueryDeserializer extends StdDeserializer<Object> {

Expand Down Expand Up @@ -65,8 +73,8 @@ public Object deserialize(JsonParser jp, DeserializationContext ctxt)
final Object bean = valueInstantiator.createUsingDefault(ctxt);

String[] nameValueParams = queryString.split("&");
for (String nameValueParam : nameValueParams) {

Map<String, List<String>> params = new HashMap<>();
for (String nameValueParam : nameValueParams) {
String name;
String value = null;
if (nameValueParam.contains("=")) {
Expand All @@ -76,21 +84,25 @@ public Object deserialize(JsonParser jp, DeserializationContext ctxt)
} else {
name = decode(nameValueParam);
}
params.computeIfAbsent(name, n -> new ArrayList<>());
params.get(name).add(value);
}

SettableBeanProperty prop = beanDeserializer.findProperty(new PropertyName(name));
for (Map.Entry<String, List<String>> param : params.entrySet()) {
SettableBeanProperty prop = beanDeserializer.findProperty(new PropertyName(param.getKey()));
if (prop == null) {
if (ignoreUnknown) {
continue;
} else {
String errorMessage =
MessageFormat.format(
"Unknown parameter \"{0}\" supplied.",
new Object[] {name});
new Object[] {param.getKey()});
throw new JsonParseException(jp, errorMessage);
}
}

deserializeNameValue(value, prop, jp, ctxt, bean);
deserializeNameValue(param.getValue(), prop, jp, ctxt, bean);
}

return bean;
Expand All @@ -104,13 +116,35 @@ private String decode(String value) throws UnsupportedEncodingException {
* Set an object value using the supplied query param.
*/
public void deserializeNameValue(
String value,
List<String> values,
SettableBeanProperty prop,
JsonParser p,
DeserializationContext ctxt,
Object bean)
throws IOException {
StringReader reader = new StringReader(quoted(value));

String jsonifiedParam = "";
JavaType propType = prop.getType();
boolean isArrayOrCollection =
prop.getType().isTypeOrSubTypeOf(Collection.class)
|| prop.getType().isArrayType();
if (isArrayOrCollection) {
HttpQueryDelimited delimited = prop.getAnnotation(HttpQueryDelimited.class);
if (delimited != null) {
String lastValue = values.get(values.size() - 1);
values = Arrays.asList(lastValue.split(delimited.delimiter()));
}
jsonifiedParam = wrapAsArray(values);
} else {
String lastValue = values.get(values.size() - 1);
if (propType.isPrimitive()) {
jsonifiedParam = lastValue;
} else {
jsonifiedParam = quote(lastValue);
}
}

StringReader reader = new StringReader(jsonifiedParam);
JsonParser parser = new ReaderBasedJsonParser(
getIoContext(),
p.getFeatureMask(),
Expand Down Expand Up @@ -141,7 +175,12 @@ private CharsToNameCanonicalizer getCharsToNameCanonicalizer() {
return CharsToNameCanonicalizer.createRoot();
}

private String quoted(String value) {
private String quote(String value) {
return '"' + value + '"';
}

private String wrapAsArray(List<String> values) {
return "[" + values.stream().map(this::quote)
.collect(Collectors.joining(" ,")) + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

Expand All @@ -16,6 +17,9 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

public class ListParamTest {

private static ObjectMapper objectMapper;
Expand Down Expand Up @@ -73,6 +77,8 @@ public CustomDelimiterListQuery(List<String> values) {
}

@HttpQuery
@NoArgsConstructor
@EqualsAndHashCode
private static class CustomDelimiterNoEncodeListQuery {
@JsonProperty("paramA")
@HttpQueryDelimited(delimiter = ";", encodeDelimiter = false)
Expand Down Expand Up @@ -117,4 +123,11 @@ public void testCustomDelimiterNoEncodeListSerialization() throws JsonProcessing
objectMapper.writeValueAsString(
new CustomDelimiterNoEncodeListQuery(EXAMPLE_LIST)));
}

@Test
public void testCustomDelimiterNoEncodeListDeserialization() throws IOException {
assertEquals(new CustomDelimiterNoEncodeListQuery(EXAMPLE_LIST),
objectMapper.readValue("\"?paramA=first;second;third\"",
CustomDelimiterNoEncodeListQuery.class));
}
}

0 comments on commit 32a4476

Please sign in to comment.