2

I have this method which should return different objects from JSON, depending on the type of class in the argument.I tryed it to return a list of objects based on the argument, but I get only LinkedHashMap into ArrayList.

I searched a lot, but everywhere in the solutions the class type is hard-coded.

Is there a way to solve this problem without hard code?

 public static <T> List<T> getObjects(Class<T> c) {
    CloseableHttpClient rest =  HttpClientSessionSingleton.getInstance().getHttpClient();
    String urlRequest = (host + "/" +
            c.getSimpleName().toLowerCase() + "s");

    HttpGet httpGet = new HttpGet(urlRequest);
    try (CloseableHttpResponse response = rest.execute(httpGet)) {
        HttpEntity entity = response.getEntity();
        String jsonString = EntityUtils.toString(entity);

        List<T> listObjectFromJson = new ObjectMapper().readValue(jsonString, new TypeReference<List<T>>(){});

        return listObjectFromJson;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

I want to just pass the class type and get objects through one method.

[
{
"id": "73cbc0b5-3dd5-49c4-97cb-6225a19122b5",
"name": "Management",
"fields": [
{
"id": "c2d740d5-4d47-42ae-b616-977b40327812",
"name": "newField1"
}
]
},
{
"id": "dd74384b-717d-4368-b0e4-3f441d5b1ffc",
"name": "IT",
"fields": []
},
{
"id": "03304335-d7d7-46ca-8075-8d5e9feb43c6",
"name": "hhh",
"fields": []
},
{
"id": "e11b4c3f-080e-490d-8ef4-ea301d551a5d",
"name": "NEWWWWW",
"fields": []
},
{
"id": "fec7eeb0-0845-49be-be14-6cdb5fcd3575",
"name": "NEWWWWW",
"fields": []
},
{
"id": "50dfea14-f30a-448c-99df-10bf01d088fa",
"name": "NEWWWWW",
"fields": []
},
{
"id": "a4a1224e-7c66-484c-ae87-dc2ecc058c36",
"name": "NEWWWWW",
"fields": []
}
]

I get this exception when my object has a relationship

Unrecognized field "fields" (class model.orm.Department), not marked as ignorable (2 known properties: "id", "name"]) at [Source: (String)"[{"id":"73cbc0b5-3dd5-49c4-97cb-6225a19122b5","name":"Management","fields":[{"id":"c2d740d5-4d47-42ae-b616-977b40327812","name":"newField1"}]},{"id":"dd74384b-717d-4368-b0e4-3f441d5b1ffc","name":"IT","fields":[]},{"id":"03304335-d7d7-46ca-8075-8d5e9feb43c6","name":"hhh","fields":[]},{"id":"e11b4c3f-080e-490d-8ef4-ea301d551a5d","name":"NEWWWWW","fields":[]},{"id":"fec7eeb0-0845-49be-be14-6cdb5fcd3575","name":"NEWWWWW","fields":[]},{"id":"50dfea14-f30a-448c-99df-10bf01d088fa","name":"NEWWWWW","fie"[truncated 84 chars]; line: 1, column: 77] (through reference chain: java.util.ArrayList[0]->model.orm.Department["fields"]) at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from

1
  • 1
    This happens because the mapper fails when it encounters unknown properties as the default behaviour; to avoid this error you can use mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); Commented Aug 22, 2021 at 20:01

1 Answer 1

3

You can construct a new JavaType parametric type passing as an argument the List.class to the ObjectMapper.html#getTypeFactory method like below:

public static <T> List<T> getObjects(Class<T> c) throws IOException {
    //omitted the lines before creating the mapper including the jsonstring
    ObjectMapper mapper = new ObjectMapper();
    JavaType type = mapper.getTypeFactory().constructParametricType(List.class, c);
    
    return mapper.readValue(jsonString, type);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you it helped! Only if the object has relationships then it stops working...
@jen1g You are welcome. You can include an example of json and class you are using for which it is not working, so I can test it and if it is possible solve the issue.
@jen1g, the fact that doesn't work when something is present suggest me that probably you have to ignore unknown properties in the mapper.
I added a JSON example and an exception when I use the method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.