美文网首页
RestTemplate使用

RestTemplate使用

作者: 飞鹰雪玉 | 来源:发表于2021-03-23 11:42 被阅读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请求等等。

    相关文章

      网友评论

          本文标题:RestTemplate使用

          本文链接:https://www.haomeiwen.com/subject/sjzpnktx.html