Skip to content

Commit

Permalink
Jackson query param mapper exception messages improved
Browse files Browse the repository at this point in the history
  • Loading branch information
jjlauer committed Sep 26, 2024
1 parent b9b8203 commit b481000
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.fizzed.crux.jackson;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.node.ArrayNode;

import java.io.IOException;
Expand Down Expand Up @@ -60,6 +62,10 @@ static public Map<String,String> toQueryParams(ObjectMapper objectMapper, Object
}

static public <T> T fromQueryParams(ObjectMapper objectMapper, Map<String,String> params, Class<T> type) throws IOException {
return fromQueryParams(objectMapper, params, type, false);
}

static public <T> T fromQueryParams(ObjectMapper objectMapper, Map<String,String> params, Class<T> type, boolean failOnUnknownProperties) throws IOException {

// build a map of key -> values, where comma-delimited values are turned into lists
final Map<String,Object> data = new HashMap<>();
Expand All @@ -76,7 +82,19 @@ static public <T> T fromQueryParams(ObjectMapper objectMapper, Map<String,String
}
}

return objectMapper.convertValue(data, type);
ObjectReader objectReader = objectMapper
.readerFor(type)
.with(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

if (!failOnUnknownProperties) {
objectReader = objectReader.without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
} else {
objectReader = objectReader.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}

final JsonNode rootNode = objectMapper.valueToTree(data);

return objectReader.readValue(rootNode);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.fizzed.crux.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import org.junit.Test;

import java.util.*;
Expand Down Expand Up @@ -126,12 +127,32 @@ public void fromQueryParams() throws Exception {
assertThat(a4.getTypes(), contains("C", "D", "F"));
assertThat(a4.getAnimals(), containsInAnyOrder(Animal.SHEEP, Animal.DOG));

values.put("animals", "DOG");

final A a5 = QueryParamMapper.fromQueryParams(objectMapper, values, A.class);

assertThat(a5.getId(), is(1));
assertThat(a5.getName(), is("Hello!"));
assertThat(a5.getTypes(), contains("C", "D", "F"));
assertThat(a5.getAnimals(), containsInAnyOrder(Animal.DOG));

// ignore an unknown property?
values.put("doesnot", "exist");

final A a6 = QueryParamMapper.fromQueryParams(objectMapper, values, A.class);

assertThat(a6.getId(), is(1));
assertThat(a6.getName(), is("Hello!"));
assertThat(a6.getTypes(), contains("C", "D", "F"));
assertThat(a6.getAnimals(), containsInAnyOrder(Animal.DOG));


// bad enum value?
values.put("animals", "NOTFOUND");

try {
QueryParamMapper.fromQueryParams(objectMapper, values, A.class);
} catch (IllegalArgumentException e) {
} catch (InvalidFormatException e) {
// expected
}
}
Expand Down

0 comments on commit b481000

Please sign in to comment.