Jackson does not contains any XPath feature but you can define converter for each property. This converter will be used by Jackson to convert input type to output type which you need. In your example input type is Map<String, Object>
and output type is List<String>
. Probably, this is not the simplest and the best solution which we can use but it allows us to define converter for only one property without defining deserializer for entire entity.
Your POJO class:
class MyProfileDto {
@JsonDeserialize(converter = SkillConverter.class)
private List<String> skills;
public List<String> getSkills() {
return skills;
}
public void setSkills(List<String> skills) {
this.skills = skills;
}
}
Converter for List<String> skills;
property:
class SkillConverter implements Converter<Map<String, Object>, List<String>> {
@SuppressWarnings("unchecked")
public List<String> convert(Map<String, Object> value) {
Object values = value.get("values");
if (values == null || !(values instanceof List)) {
return Collections.emptyList();
}
List<String> result = new ArrayList<String>();
for (Object item : (List<Object>) values) {
Map<String, Object> mapItem = (Map<String, Object>) item;
Map<String, Object> skillMap = (Map<String, Object>) mapItem.get("skill");
if (skillMap == null) {
continue;
}
result.add(skillMap.get("name").toString());
}
return result;
}
public JavaType getInputType(TypeFactory typeFactory) {
return typeFactory.constructMapLikeType(Map.class, String.class, Object.class);
}
public JavaType getOutputType(TypeFactory typeFactory) {
return typeFactory.constructCollectionLikeType(List.class, String.class);
}
}
And example usage:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.Converter;
public class JacksonProgram {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
MyProfileDto dto = mapper.readValue(new File("/x/json"), MyProfileDto.class);
System.out.println(dto.getSkills());
}
}
Above program prints:
[C++, Java]