“RestTemplate exchange”的版本间的差异
跳到导航
跳到搜索
Jihongchang(讨论 | 贡献) |
Jihongchang(讨论 | 贡献) |
||
第207行: | 第207行: | ||
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) | at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) | ||
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) | at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==== exchange 获取带泛型的嵌套对象 ==== | ||
+ | <syntaxhighlight lang="java"> | ||
+ | import io.github.jihch.pojo.People; | ||
+ | import org.junit.jupiter.api.Test; | ||
+ | import org.junit.runners.Parameterized; | ||
+ | import org.springframework.boot.test.context.SpringBootTest; | ||
+ | import org.springframework.core.ParameterizedTypeReference; | ||
+ | import org.springframework.http.HttpEntity; | ||
+ | import org.springframework.http.HttpMethod; | ||
+ | import org.springframework.http.ResponseEntity; | ||
+ | import org.springframework.web.client.RestTemplate; | ||
+ | |||
+ | import java.util.HashMap; | ||
+ | import java.util.List; | ||
+ | import java.util.Map; | ||
+ | |||
+ | @SpringBootTest | ||
+ | public class ClientApplicationTests { | ||
+ | |||
+ | @Test | ||
+ | void exchange() { | ||
+ | RestTemplate restTemplate = new RestTemplate(); | ||
+ | // HttpEntity 请求体数据 | ||
+ | // 构造方法参数是请求体内容 | ||
+ | HttpEntity<String> httpEntity = new HttpEntity<>(""); | ||
+ | // 泛型为响应体的类型 | ||
+ | ParameterizedTypeReference<List<People>> parameterizedTypeReference = | ||
+ | new ParameterizedTypeReference<List<People>>() { | ||
+ | }; | ||
+ | ResponseEntity<List<People>> result = restTemplate.exchange("http://localhost:8080/demo6", HttpMethod.GET, | ||
+ | null, parameterizedTypeReference); | ||
+ | List<People> list = result.getBody(); | ||
+ | for (People people : list) { | ||
+ | System.out.println(people); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
</syntaxhighlight> | </syntaxhighlight> |
2023年3月27日 (一) 01:54的版本
https://www.bilibili.com/video/BV1AN411Z7mx?p=12
当请求的控制器返回值类型为 List<xx>、Set<xxx> 等带有泛型类型的类型时,就不能使用 getForObject、getForEntity、postForObject 等,因为它们都是只能设置返回值类型,而不能设置类型的泛型。
这时就需要用到 exchange 方法。
除此之外,如果需要设置请求头参数情况也需要使用 exchange 方法。
Application Service 中
新增 POJO People.java
package io.github.jihch.pojo;
public class People {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public People() {
}
public People(int id, String name) {
this.id = id;
this.name = name;
}
}
DemoController.java 中新增方法
import io.github.jihch.pojo.People;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@RestController
public class DemoController {
@RequestMapping("/demo5")
public People demo5() {
return new People(1, "jihch");
}
@RequestMapping("/demo6")
public List<People> demo6() {
List<People> list = new ArrayList<>();
list.add(new People(1, "jihch1"));
list.add(new People(2, "jihch2"));
return list;
}
}
Application Client 中的单元测试
getForObject 获取简单非嵌套的单个对象
import io.github.jihch.pojo.People;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest
public class ClientApplicationTests {
@Test
void withObject() {
RestTemplate restTemplate = new RestTemplate();
People people = restTemplate.getForObject("http://localhost:8080/demo5", People.class);
System.out.println(people);
System.out.println(people.getId());
System.out.println(people.getName());
}
}
People{id=1, name='jihch'}
1
jihch
getForObject 获取嵌套带泛型的对象就会遇到问题
import io.github.jihch.pojo.People;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest
public class ClientApplicationTests {
/**
* 接收返回值为 List<People> 这种带泛型的
*/
@Test
void withGenericity() {
RestTemplate restTemplate = new RestTemplate();
List<People> list = restTemplate.getForObject("http://localhost:8080/demo6", List.class);
System.out.println(list);
for (People people : list) {
System.out.println(people);
}
}
}
[{id=1, name=jihch1}, {id=2, name=jihch2}]
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to io.github.jihch.pojo.People
at io.github.jihch.ClientApplicationTests.withGenericity(ClientApplicationTests.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
exchange 获取带泛型的嵌套对象
import io.github.jihch.pojo.People;
import org.junit.jupiter.api.Test;
import org.junit.runners.Parameterized;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SpringBootTest
public class ClientApplicationTests {
@Test
void exchange() {
RestTemplate restTemplate = new RestTemplate();
// HttpEntity 请求体数据
// 构造方法参数是请求体内容
HttpEntity<String> httpEntity = new HttpEntity<>("");
// 泛型为响应体的类型
ParameterizedTypeReference<List<People>> parameterizedTypeReference =
new ParameterizedTypeReference<List<People>>() {
};
ResponseEntity<List<People>> result = restTemplate.exchange("http://localhost:8080/demo6", HttpMethod.GET,
null, parameterizedTypeReference);
List<People> list = result.getBody();
for (People people : list) {
System.out.println(people);
}
}
}