RestTemplate - 使用
将多个服务注册到 Eureka上,使用RestTemplate进行调用:
演示 APP-RESTTEMPLATE
通过 RestTemplate调用 API-02-APPLICATION
应用 API-02-APPLICATION 配置
准备
配置文件:
server:
port: 8001
eureka:
client:
# 设置服务注册中心的url
service-url:
defaultZone: http://localhost:7900/eureka
instance:
instance-id: qiankai-client-002 #显示此名字(默认是当前项目http://localhost:8001)
prefer-ip-address: true #访问路径可以显示ip地址
spring:
application:
name: api-02-application
配置
Controller如下:
package com.qiankai.api.controller;
import com.qiankai.common.dto.Person;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
/**
* 演示RestTemplate
* 给其他客户端调用
*
* @author kai_qian
* @version v1.0
* @since 2020/09/15 16:32
*/
@RestController
public class RestTemplateApiController {
@GetMapping("/getMap")
public Map<String, String> getMap() {
HashMap<String, String> map = new HashMap<>();
map.put("name", "500");
return map;
}
@GetMapping("/getObj")
public Person getObj() {
Person person = new Person();
person.setId(100);
person.setName("xiaoming");
return person;
}
@GetMapping("/getObjParam")
public Person getObjParam(String name) {
Person person = new Person();
person.setId(100);
person.setName(name);
return person;
}
@PostMapping("/postParam")
public Person postParam(@RequestBody String name) {
System.out.println("name:" + name);
Person person = new Person();
person.setId(100);
person.setName("xiaoming" + name);
return person;
}
@PostMapping("/postForLocation")
public URI postParam(@RequestBody Person person, HttpServletResponse response) throws Exception {
URI uri = new URI("https://www.baidu.com/s?wd=" + person.getName());
response.addHeader("Location", uri.toString());
return uri;
}
}
应用 APP-RESTTEMPLATE 配置
准备
pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>client-resttemplate</artifactId>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>com.qiankai</groupId>
<artifactId>client-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 用于上报节点信息 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置文件:
server:
port: 8010
eureka:
client:
# 设置服务注册中心的url
service-url:
defaultZone: http://localhost:7900/eureka
instance:
instance-id: qiankai-resttemplate #显示此名字(默认是当前项目http://localhost:8001)
prefer-ip-address: true #访问路径可以显示ip地址
spring:
application:
name: app-restTemplate
配置
先配置一个 RestTemplate实例:
package com.qiankai.rest.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 配置
*
* @author kai_qian
* @version v1.0
* @since 2020/09/15 16:41
*/
@Configuration
public class AppConfig {
@Bean
@LoadBalanced // 开启负载均衡
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Controller 如下:
package com.qiankai.rest.controller;
import com.qiankai.common.dto.Person;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.Collections;
import java.util.Map;
/**
* 使用RestTemplate调用其他客户端接口
*
* @author kai_qian
* @version v1.0
* @since 2020/09/15 16:42
*/
@RestController
public class CallApiController {
// 地址使用配置的应用名(Eureka中显示的)
private static final String CLIENT002_8001_URL = "http://API-02-APPLICATION";
@Autowired
private RestTemplate restTemplate;
/**
* 返回Map
*/
@GetMapping("/getMap")
public void getMap() {
String url = CLIENT002_8001_URL + "/getMap";
ResponseEntity<Map> entity = restTemplate.getForEntity(url, Map.class);
System.out.println("getMap返回: " + entity.getBody());
}
/**
* 返回对象
*/
@GetMapping("/getObj")
public void getObj() {
String url = CLIENT002_8001_URL + "/getObj";
ResponseEntity<Person> entity = restTemplate.getForEntity(url, Person.class);
System.out.println("getObj返回: " + ToStringBuilder.reflectionToString(entity.getBody()));
}
/**
* 传参调用
*/
@GetMapping("/getObjParam")
public void getObjParams() {
// 使用占位符
String url1 = CLIENT002_8001_URL + "/getObjParam?name={1}";
ResponseEntity<Person> entity1 = restTemplate.getForEntity(url1, Person.class, "hehehe...");
System.out.println("getObjParam返回: " + entity1.getBody());
// 使用map
String url2 = CLIENT002_8001_URL + "/getObjParam?name={name}";
Map<String, String> map = Collections.singletonMap("name", " memeda");
ResponseEntity<Person> entity2 = restTemplate.getForEntity(url2, Person.class, map);
System.out.println("getObjParam返回: " + entity2.getBody());
// 返回对象
String url3 = CLIENT002_8001_URL + "/getObjParam?name=tatata";
Person person = restTemplate.getForObject(url3, Person.class, map);
System.out.println("getObjParam返回: " + person.toString());
}
/**
* post请求
*/
@GetMapping("/postParam")
public void postParams() {
String url = CLIENT002_8001_URL + "/postParam";
Map<String, String> map = Collections.singletonMap("name", " memeda");
ResponseEntity<Person> entity = restTemplate.postForEntity(url, map, Person.class);
System.out.println("postParam返回:" + entity.getBody());
}
/**
* postForLocation
*/
@GetMapping("/postForLocation")
public void postForLocation() {
String url = CLIENT002_8001_URL + "/postForLocation";
Map<String, String> map = Collections.singletonMap("name", "memeda");
URI location = restTemplate.postForLocation(url, map, Person.class);
System.out.println("postForLocation返回:" + location);
}
}
演示结果
访问 APP-RESTTEMPLATE
应用的接口,通过 RestTemplate调用的信息被打印在控制台:
使用拦截器
添加一个类,实现 ClientHttpRequestInterceptor
接口
package com.qiankai.rest.config;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import java.io.IOException;
/**
* 客户端调用拦截器配置
*
* @author kai_qian
* @version v1.0
* @since 2020/09/15 17:46
*/
public class LoggingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
System.out.println("进入拦截器了");
System.out.println("请求的URL是:"+request.getURI());
ClientHttpResponse response = execution.execute(request, body);
System.out.println("打印响应头:"+response.getHeaders());
return response;
}
}
修改 RestTemplate配置:
package com.qiankai.rest.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 配置
*
* @author kai_qian
* @version v1.0
* @since 2020/09/15 16:41
*/
@Configuration
public class AppConfig {
@Bean
@LoadBalanced // 开启负载均衡
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
// 添加一个拦截器
restTemplate.getInterceptors().add(new LoggingClientHttpRequestInterceptor());
return restTemplate;
}
}
调用 /postParam 接口,控制台打印日志,说明拦截器生效了: