Skip to content

In a @JsonPath projection a List<interface> property always returns a list with only one element #2270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jekutzsche opened this issue Jan 8, 2021 · 4 comments
Assignees
Labels
status: feedback-provided Feedback has been provided type: bug A general bug

Comments

@jekutzsche
Copy link

The @JsonPath projection of a List of an interface type returns only the first element even if the list should contain more elements.

The following code hopefully makes the circumstances clear.

var payload = template.exchange("https://…", HttpMethod.GET, new HttpEntity<Void>(headers), UserPayload.class).getBody();

var users = payload.users();
users.size() == 1 is also true if the list had to contain more elements


@ProjectedPayload
interface UserPayload {

	@JsonPath("$..person")
	List<Users> users();

	interface Users {

		public String getFirstName();
		public String getLastName();
	}
}

Responsible for the error is the following code in InputMessageProjecting.invoke:

if (returnType.getRequiredActualType().getType().isInterface()) {

    List<?> result = context.read(jsonPath);
    return result.isEmpty() ? null : result.get(0);
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 8, 2021
@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 11, 2021
@mp911de mp911de self-assigned this Jan 11, 2021
@mp911de
Copy link
Member

mp911de commented Jan 12, 2021

I was able to reproduce the issue by using ProjectingJackson2HttpMessageConverter directly. Our unit tests don't reproduce the issue as the JSON path result is wrapped in another list which renders the correct result. Need to investigate further why using ProjectingJackson2HttpMessageConverter doesn't show this behavior.

@mp911de
Copy link
Member

mp911de commented Jan 12, 2021

Okay, so the actual path definition makes the difference, whether the path is definite or not. Only definite paths lead to additional list wrapping. Can you provide a sample for your input JSON?

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Jan 12, 2021
@jekutzsche
Copy link
Author

Yes of course, here is a sample:

[
    {
        "creationDate": 1610111331413,
        "changeDate": 1610111332160,
        "person": {
            "caption": "Test2 TEST2",
            "firstName": "Test2",
            "lastName": "Test2"
        }
    },
    {
        "creationDate": 1609775450502,
        "changeDate": 1609775451333,
        "person": {
            "caption": "Test TEST",
            "firstName": "Test",
            "lastName": "Test"
        }
    }
]

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 12, 2021
@mp911de
Copy link
Member

mp911de commented Jan 12, 2021

Okay, thanks. The combination of a scan token with an array response leads to a non-definite path and therefore the JSON path library doesn't wrap the response in a nested list. Checking for a non-definite path and then applying the proper collection handling in combination with checking the return type does the trick.

@mp911de mp911de added this to the 2.3.7 (Neumann SR7) milestone Jan 12, 2021
mp911de added a commit that referenced this issue Jan 12, 2021
We now check for double-nesting of JSON path evaluation results when the return type is a collection. If the result is double-wrapped and the nested object is a collection then we unwrap it.

Closes #2270
mp911de added a commit that referenced this issue Jan 12, 2021
Reuse definitive path flag without recompile the expression.

See #2270
mp911de added a commit that referenced this issue Jan 12, 2021
We now check for double-nesting of JSON path evaluation results when the return type is a collection. If the result is double-wrapped and the nested object is a collection then we unwrap it.

Closes #2270
mp911de added a commit that referenced this issue Jan 12, 2021
Reuse definitive path flag without recompile the expression.

See #2270
mp911de added a commit that referenced this issue Jan 12, 2021
Reuse definitive path flag without recompile the expression.

See #2270
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: feedback-provided Feedback has been provided type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants