Skip to content

Commit 033d277

Browse files
rPramlsnicoll
authored andcommitted
Resolve base type in parameterized type if necessary
See gh-34086
1 parent 2273850 commit 033d277

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ else if (genericType instanceof ParameterizedType parameterizedType) {
180180
generics[i] = resolvedTypeArgument;
181181
}
182182
else {
183-
generics[i] = ResolvableType.forType(typeArgument);
183+
generics[i] = ResolvableType.forType(typeArgument).resolveType();
184184
}
185185
}
186186
else if (typeArgument instanceof ParameterizedType) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2002-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.test.web.servlet.samples.standalone;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import com.fasterxml.jackson.annotation.JsonSubTypes;
23+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
24+
import org.junit.jupiter.api.Test;
25+
26+
import org.springframework.http.MediaType;
27+
import org.springframework.web.bind.annotation.GetMapping;
28+
import org.springframework.web.bind.annotation.RestController;
29+
30+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
31+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
32+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
33+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
34+
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
35+
36+
/**
37+
* Demonstrates, if returning a List>? extends SomeType< can be correctly serialized.
38+
*
39+
* @author Roland Praml
40+
*/
41+
public class GenericReturnTests {
42+
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
43+
@JsonSubTypes({
44+
@JsonSubTypes.Type(value = SubType1.class, name = "one"),
45+
@JsonSubTypes.Type(value = SubType2.class, name = "two")
46+
})
47+
public static class BaseType {
48+
49+
}
50+
51+
public static class SubType1 extends BaseType {
52+
}
53+
54+
public static class SubType2 extends BaseType {
55+
}
56+
57+
@Test
58+
public void genericReturnTest() throws Exception {
59+
60+
standaloneSetup(new Controller()).build()
61+
.perform(get("/genericReturnList").accept(MediaType.APPLICATION_JSON))
62+
.andExpect(status().isOk())
63+
.andExpect(content().contentType("application/json"))
64+
.andExpect(jsonPath("$[0].type").value("one"))
65+
.andExpect(jsonPath("$[1].type").value("two"));
66+
}
67+
68+
@RestController
69+
@SuppressWarnings("unchecked")
70+
public static class Controller {
71+
72+
@GetMapping(value = "/genericReturnList", produces = MediaType.APPLICATION_JSON_VALUE)
73+
public <T extends BaseType> List<T> get() {
74+
List<T> list = new ArrayList<>();
75+
list.add((T) new SubType1());
76+
list.add((T) new SubType2());
77+
return list;
78+
}
79+
80+
}
81+
}

0 commit comments

Comments
 (0)