RestTemplate使用

2021-03-23  本文已影响0人  飞鹰雪玉

这次遇到一个问题,两个项目之间需要通信的问题。在一个服务上调用另外一个服务的接口。不能用nacos等注册中心,所以找到了spring实现的RestTemplate方式进行通讯。

1、首先在yaml文件里面添加另外一个服务的ip和端口。

#flowable配置
flowable:
  activity-font-name: \u5B8B\u4F53
  label-font-name: \u5B8B\u4F53
  annotation-font-name: \u5B8B\u4F53
  check-process-definitions: false
  database-schema-update: true
# 访问服务设置
services:
  contacts_path: contacts
  contacts_port: 80

我这儿用的是映射,比如你如果将contacts这个服务跑在本机的话,那就需要在host文件里面配置映射。如下:

127.0.0.1 contacts

同样,如果你将自己服务跑在对应ip的服务器上,你只需要在你跑的当下服务的主机host配置服务器ip和contacts的映射。

2、覆盖原值

另外,也可以通过启动服务时候传输的环境变量里面进行设置。
如下:


image.png

当然也需要在spring启动类里面设置获取环境变量的值并且覆盖原来的值。


image.png
public class BladeApplication {

    /**
     * Create an application context
     * java -jar app.jar --spring.profiles.active=prod --server.port=2333
     *
     * @param appName application name
     * @param source  The sources
     * @return an application context created from the current state
     */
    public static ConfigurableApplicationContext run(String appName, Class source, String... args) {
        SpringApplicationBuilder builder = createSpringApplicationBuilder(appName, source, args);
        return builder.run(args);
    }

    public static SpringApplicationBuilder createSpringApplicationBuilder(String appName, Class source, String... args) {
        Assert.hasText(appName, "[appName]服务名不能为空");
        // 读取环境变量,使用spring boot的规则
        ConfigurableEnvironment environment = new StandardEnvironment();
        MutablePropertySources propertySources = environment.getPropertySources();
        propertySources.addFirst(new SimpleCommandLinePropertySource(args));
        propertySources.addLast(new MapPropertySource(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, environment.getSystemProperties()));
        propertySources.addLast(new SystemEnvironmentPropertySource(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, environment.getSystemEnvironment()));
        // 获取配置的环境变量
        String[] activeProfiles = environment.getActiveProfiles();
        // 判断环境:dev、test、prod
        List<String> profiles = Arrays.asList(activeProfiles);
        // 预设的环境
        List<String> presetProfiles = new ArrayList<>(Arrays.asList(AppConstant.DEV_CODE, AppConstant.TEST_CODE, AppConstant.PROD_CODE));
        // 交集
        presetProfiles.retainAll(profiles);
        // 当前使用
        List<String> activeProfileList = new ArrayList<>(profiles);
        Function<Object[], String> joinFun = StringUtils::arrayToCommaDelimitedString;
        SpringApplicationBuilder builder = new SpringApplicationBuilder(source);
        String profile;
        if (activeProfileList.isEmpty()) {
            // 默认dev开发
            profile = AppConstant.DEV_CODE;
            activeProfileList.add(profile);
            builder.profiles(profile);
        } else if (activeProfileList.size() == 1) {
            profile = activeProfileList.get(0);
        } else {
            // 同时存在dev、test、prod环境时
            throw new RuntimeException("同时存在环境变量:[" + StringUtils.arrayToCommaDelimitedString(activeProfiles) + "]");
        }
        String startJarPath = BladeApplication.class.getResource("/").getPath().split("!")[0];
        String activePros = joinFun.apply(activeProfileList.toArray());
        System.out.printf("----启动中,读取到的环境变量:[%s],jar地址:[%s]----%n", activePros, startJarPath);
        Properties props = System.getProperties();
        props.setProperty("spring.application.name", appName);
        props.setProperty("spring.profiles.active", profile);
        props.setProperty("info.version", AppConstant.APPLICATION_VERSION);
        props.setProperty("info.desc", appName);
        props.setProperty("file.encoding", StandardCharsets.UTF_8.name());
        props.setProperty("blade.env", profile);
        props.setProperty("blade.name", appName);
        props.setProperty("blade.is-local", String.valueOf(isLocalDev()));
        props.setProperty("blade.dev-mode", profile.equals(AppConstant.PROD_CODE) ? "false" : "true");
        props.setProperty("blade.service.version", AppConstant.APPLICATION_VERSION);
        props.setProperty("spring.main.allow-bean-definition-overriding", "true");
        props.setProperty("spring.sleuth.sampler.percentage", "1.0");
        props.setProperty("spring.cloud.nacos.config.shared-dataids", NacosConstant.sharedDataIds(profile));
        props.setProperty("spring.cloud.nacos.config.refreshable-dataids", NacosConstant.sharedDataIds(profile));
        props.setProperty("spring.cloud.nacos.config.file-extension", NacosConstant.NACOS_CONFIG_FORMAT);
        props.setProperty("spring.cloud.alibaba.seata.tx-service-group", appName.concat(NacosConstant.NACOS_GROUP_SUFFIX));
        Map<String, Object> envMap = environment.getSystemEnvironment();
        String dbUrl = "DB_URL";
        String dbUsername = "DB_USERNAME";
        String dbPassword = "DB_PASSWORD";
        String redisHost = "REDIS_HOST";
        String redisPort = "REDIS_PORT";
        String redisPassword = "REDIS_PASSWORD";
        String contactsPath = "CONTACTS_SERVER_PATH";
        String contactSport = "CONTACTS_SERVER_PORT";
        if (null != envMap.get(dbUrl)) {
            props.setProperty("spring.datasource.url", envMap.get(dbUrl).toString());
        }
        if (null != envMap.get(dbUsername)) {
            props.setProperty("spring.datasource.username", envMap.get(dbUsername).toString());
        }
        if (null != envMap.get(dbUsername)) {
            props.setProperty("spring.datasource.password", envMap.get(dbPassword).toString());
        }
        if (null != envMap.get(redisHost)) {
            props.setProperty("spring.redis.host", envMap.get(redisHost).toString());
        }
        if (null != envMap.get(redisPort)) {
            props.setProperty("spring.redis.port", envMap.get(redisPort).toString());
        }
        if (null != envMap.get(redisPassword)) {
            props.setProperty("spring.redis.password", envMap.get(redisPassword).toString());
        }
        if (null != envMap.get(contactsPath)) {
            props.setProperty("services.contacts_path", envMap.get(contactsPath).toString());
        }
        if (null != envMap.get(contactSport)) {
            props.setProperty("services.contacts_port", envMap.get(contactSport).toString());
        }

        // 加载自定义组件
        List<LauncherService> launcherList = new ArrayList<>();
        ServiceLoader.load(LauncherService.class).forEach(launcherList::add);
        launcherList.stream().sorted(Comparator.comparing(LauncherService::getOrder)).collect(Collectors.toList())
                .forEach(launcherService -> launcherService.launcher(builder, appName, profile, isLocalDev()));
        return builder;
    }
}

主要是这几句:

        Map<String, Object> envMap = environment.getSystemEnvironment();
        String contactsPath = "CONTACTS_SERVER_PATH";
        String contactSport = "CONTACTS_SERVER_PORT";
        if (null != envMap.get(contactsPath)) {
            props.setProperty("services.contacts_path", envMap.get(contactsPath).toString());
        }
        if (null != envMap.get(contactSport)) {
            props.setProperty("services.contacts_port", envMap.get(contactSport).toString());
        }

这样就覆盖了yaml文件中services下的值。

3、调用RestTemplate

package org.springblade.modules.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserVOService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * UserAccount achieved Class
 *
 * @author liupeng
 * @date 2020-12-03
 */
@Service
public class UserVOServiceImpl implements IUserVOService {

    @Value("${services.contacts_path}")
            private String contacts_path;
    @Value("${services.contacts_port}")
            private String contacts_port;
    User user = new User();

    @Override
    public User getUserById(String id) {

        //复杂构造函数的使用
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(1000);
        requestFactory.setReadTimeout(1000);

        user.setId(id);

        //利用复杂构造器可以实现超时设置,内部实际实现为 HttpClient
        RestTemplate restTemplate = new RestTemplate(requestFactory);

        String url = "http://" + contacts_path + ":"+ contacts_port + "/users/" + id;
        //发送
        ResponseEntity<JSONObject> entity = restTemplate.getForEntity(url, JSONObject.class);

        if (Func.isNotEmpty(entity)) {
            if (Func.isNotEmpty(entity.getBody())) {
                user.setName((String) entity.getBody().get("name"));
            }
        }

        return user;
    }
}

3.1、首先是使用 @Value("${services.contacts_path}") 注解将yaml文件中的值注入到声明的字符串中,为了后面组装访问url
3.2、getUserById函数中先声明一个SimpleClientHttpRequestFactory 对象,构造RestTemplate对象用来访问contacts服务。
3.3、调用restTemplate对象的getForEntity方法来实现get请求,postForEntity()实现post请求,patchForObject()实现patch请求,put()实现put请求等等。

上一篇下一篇

猜你喜欢

热点阅读