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 接口,控制台打印日志,说明拦截器生效了:

posted @ 2020-09-15 17:37  它山之玉  阅读(1706)  评论(0编辑  收藏  举报