Reputation: 741
I'm using Jackson 2.8.9 in my application to generate some JSON. I have some unit tests in which I compare generated JSON with some files content.
When I compare my generated JSON with my file content, it does not match due to the properties order.
For the tests to be repeatable I need to have the properties sorted alphabetically. But with Jackson, it does not seems to work.
I wrote some tests for illustation. Only should_indent_properties
pass.
public class FormatJsonWithJacksonTest {
private static final String INDENTED_UNSORTED = "{\r\n" +
" \"firstChild\" : {\r\n" +
" \"subChild\" : {\r\n" +
" \"alphaItem\" : \"1234567891234567\",\r\n" +
" \"otherProperty\" : \"2017-06-21\",\r\n" +
" \"someOtherProperty\" : \"NONE\",\r\n" +
" \"alphaType\" : \"KIND_OF_TYPE\"\r\n" +
" }\r\n" +
" }\r\n" +
"}";
private static final String INDENTED_SORTED = "{\r\n" +
" \"firstChild\" : {\r\n" +
" \"subChild\" : {\r\n" +
" \"alphaItem\" : \"1234567891234567\",\r\n" +
" \"alphaType\" : \"KIND_OF_TYPE\",\r\n" +
" \"otherProperty\" : \"2017-06-21\",\r\n" +
" \"someOtherProperty\" : \"NONE\"\r\n" +
" }\r\n" +
" }\r\n" +
"}";
private static final String UNINDENTED_UNSORTED = "{" +
"\"firstChild\":{" +
"\"subChild\":{" +
"\"alphaItem\":\"1234567891234567\"," +
"\"otherProperty\":\"2017-06-21\"," +
"\"someOtherProperty\":\"NONE\"," +
"\"alphaType\":\"KIND_OF_TYPE\"" +
"}" +
"}" +
"}";
private static final String UNINDENTED_SORTED = "{" +
"\"firstChild\":{" +
"\"subChild\":{" +
"\"alphaItem\":\"1234567891234567\"," +
"\"alphaType\":\"KIND_OF_TYPE\"," +
"\"otherProperty\":\"2017-06-21\"," +
"\"someOtherProperty\":\"NONE\"" +
"}" +
"}" +
"}";
@Test
public void should_sort_properties() throws Exception {
// Given
ObjectMapper objectMapper = new ObjectMapper();
objectMapper = objectMapper
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
// When
String formattedJson = tryingToFormatJson(objectMapper, INDENTED_UNSORTED);
// Then
assertEquals(UNINDENTED_SORTED, formattedJson);
}
@Test
public void should_indent_properties() throws Exception {
// Given
ObjectMapper objectMapper = new ObjectMapper();
objectMapper = objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// When
String formattedJson = tryingToFormatJson(objectMapper, UNINDENTED_UNSORTED);
// Then
assertEquals(INDENTED_UNSORTED, formattedJson);
}
@Test
public void should_sort_and_indent_properties() throws Exception {
// Given
ObjectMapper objectMapper = new ObjectMapper();
objectMapper = objectMapper
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
.enable(SerializationFeature.INDENT_OUTPUT);
// When
String formattedJson = tryingToFormatJson(objectMapper, INDENTED_UNSORTED);
// Then
assertEquals(INDENTED_SORTED, formattedJson);
}
//
// Utils
//
private String tryingToFormatJson(ObjectMapper objectMapper, String unformattedJson)
throws IOException, JsonProcessingException {
JsonNode unsortedTree = objectMapper.readTree(unformattedJson);
Object treeToValue = objectMapper.treeToValue(unsortedTree, Object.class);
return objectMapper.writeValueAsString(treeToValue);
}
}
tryingToFormatJson
?Upvotes: 0
Views: 2433
Reputation:
When you call objectMapper.treeToValue(unsortedTree, Object.class)
, the Object
's type is a subclass of Map
- just put a System.out.println(treeToValue.getClass())
to check.
And according to javadoc, SORT_PROPERTIES_ALPHABETICALLY
doesn't sort map keys:
Feature that defines default property serialization order used for POJO fields (note: does not apply to Map serialization!)
If you want to sort the fields, you have to create a custom class for you structure, like this:
public class Tree {
private Map<String, Child> firstChild;
// getters and setters
}
public class Child {
private String alphaItem;
private String otherProperty;
private String someOtherProperty;
private String alphaType;
// getters and setters
}
And change the treeToValue
call to:
Tree treeToValue = objectMapper.treeToValue(unsortedTree, Tree.class);
With this, the fields will be sorted and the test will work.
Upvotes: 1