resttemplate发送请求无服务报错

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了resttemplate发送请求无服务报错相关的知识,希望对你有一定的参考价值。

参考技术A 使用 String 类型接收
String res = restTemplate.getForObject(url,String.class,map);
// 使用json转换工具将String类型的数据转换为对象
这个方法简单有效

RestTemplate工具类根据服务名发送请求

  要使用RestTemplate 根据服务名发送请求的话需要 使用  @LoadBalanced  这个注解,用了这个注解的RestTemplate就不用使用  ip 来请求了,首先要创建一个配置类

  

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: dx
 * @Description:
 * @Date: 2020/2/14 0014
 * @Version: 1.0
 */
@Configuration
public class RestTemplateConfig {

    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

  

  然后是工具类
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.xin.xunwu.base.Exception.BizException;
import com.xin.xunwu.base.response.ApiResult;
import com.xin.xunwu.entity.ServiceApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;


/**
 * @author dx
 */
@Slf4j
@Component
public class RestUtil {

    public static final String HTTP = "http://";

    public static final String[] HTTP_METHODS = {"POST", "GET"};

    @Resource
    private RestTemplate restTemplate;

    public ResponseEntity<JSONObject> restQuery(ServiceApi serviceApi) {
        String methodStr = serviceApi.getMethod().toUpperCase();
        // 请求类型错误
        if (!Arrays.asList(HTTP_METHODS).contains(methodStr)) {
            throw new BizException(ApiResult.getErrorResult("30059"));
        }
        // 根据服务名和路径拼接url
        String url = HTTP + serviceApi.getService() + serviceApi.getPath();
        MultiValueMap<String, String> params = null;
        MultiValueMap<String, String> headers = null;

        // 转换参数
        try {
            params = jsonToMap(serviceApi.getParams());
            headers = jsonToMap(serviceApi.getHeader());
        } catch (Exception e) {
            e.printStackTrace();
            // json 转换错误
            throw new BizException(ApiResult.getErrorResult("30060"));
        }
        HttpMethod method = HttpMethod.resolve(methodStr);
        return restQuery(url, params, method, headers);
    }

    private MultiValueMap<String, String> jsonToMap(String jsonStr) {
        if (jsonStr == null) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        MultiValueMap<String, String> result = new LinkedMultiValueMap<>();
        jsonObject.forEach((key, value) -> result.add(key, value.toString()));
        return result;
    }

    private ResponseEntity<JSONObject> restQuery(String url, MultiValueMap<String, String> paramsMap,
                                                 HttpMethod method, MultiValueMap<String, String> headerMap) {
        ResponseEntity<JSONObject> responseEntity = null;
        // 转换编码格式
        List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
        for (HttpMessageConverter<?> httpMessageConverter : list) {
            if (httpMessageConverter instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter)
                        httpMessageConverter).setDefaultCharset(StandardCharsets.UTF_8);
                break;
            }
        }

        // 设置头信息
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));

        // 头信息非空的话,添加头信息
        Optional.ofNullable(headerMap).ifPresent(httpHeaders::addAll);

        // 设置头信息和请求参数
        HttpEntity<MultiValueMap<String, String>> params = new HttpEntity<>(paramsMap, httpHeaders);
     // 如果是get请求的话需要把参数拼到url上
        if(method.equals(HttpMethod.GET)){
            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
            paramsMap.forEach(builder::queryParam);
            url = builder.build().encode().toString();
        }

        try {
            responseEntity = restTemplate.exchange(url, method, params, JSONObject.class);
        } catch (Exception e) {
            // 请求失败
            log.warn("restTemplate  error [message] {}", e.getMessage());
        }
        return responseEntity;
    }
}

  然后是用到的一个实体类,这个不是必须的,可以根据自己的需要修改,我这是业务需求

  

import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Id;
import java.util.Date;

/** 
 @author Generator 
 @since 2020-02-13T10:38:02.789 
 **/
@Getter
@Setter
public class ServiceApi {
    /**
     * 通过ID生成器自动生成
     */
    @Id
    private Long id;

    /**
     * 编号
     */
    private String number;

    /**
     * 服务名(注册服务名称)
     */
    private String service;

    /**
     * 方法
     */
    private String method;

    /**
     * 路径
     */
    private String path;

    /**
     * 头信息
     */
    private String header;

    /**
     * 请求体
     */
    private String body;

    /**
     * 参数
     */
    private String params;

    /**
     * 接口类型(drop:下拉选 verify:验证)
     */
    private String type;

    /**
     * 备注
     */
    private String remark;

    /**
     * 删除标记(0:未删除;1:已删除)
     */
    @Column(name = "delete_flg")
    private String deleteFlg;

    /**
     * 创建时间
     */
    @Column(name = "create_time")
    private Date createTime;

    /**
     * 创建者
     */
    private Long creator;

    /**
     * 更新时间
     */
    @Column(name = "update_time")
    private Date updateTime;

    /**
     * 更新者
     */
    private Long updator;
}

  

以上是关于resttemplate发送请求无服务报错的主要内容,如果未能解决你的问题,请参考以下文章

RestTemplate发送请求

4种Springboot RestTemplate 服务里发送HTTP请求用法

在春季由resttemplate发出的每个请求发送客户端证书的正确方法是啥?

Spring RestTemplate 之get请求

Spring Cloud入门 - REST客户端Feign

REST访问(RestTemplate)