restTemplate使用笔记

时间:2025-02-22 06:59:14

文章目录

      • restTemplate为空的问题
        • 方案一
        • 方案二(这种方案编译时不报错,但是运行时会报错)
      • exchange和postForEntity的区别
        • exchange例子
        • postForEntity的例子
      • 报错: : Request processing failed; nested exception is
      • rest逻辑处理
      • httpStatus 200的判断
      • 几个方法的区别
      • 多个restTemplate
      • 有时框架自带的restTemplate带有负载均衡,但是不知道在哪里配置的怎么办?
      • 其他
        • restTempalte请求报错 No instances available for

接口只能接收json请求。 如果其他格式会报错。
日志报错:Content type 'text/plain;charset=ISO-8859-1

restTemplate代码很简单,但是要注意下文中的2个要点:

String url="/api/getUser";
User user= new User();
user.setName("zhangsan");

String s = JSON.toJSONString(user);
// 要点1: 这三句设置header非常重要
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); 
HttpEntity<String> request = new HttpEntity<String>(s, headers);

try {
	// 要点2:这里要发送包含header的request,不要直接发对象的json报文
	restTemplate.postForEntity(url, request, User.class);
}catch (Exception e){
    logger.error("异常了",e);
}

restTemplate为空的问题

方案一

在启动类,或配置类里面添加如下代码:

 @Autowired
 private RestTemplateBuilder builder;
 
 @Bean
 public RestTemplate restTemplate() {
     return new RestTemplate();
 }

问题解决。

方案二(这种方案编译时不报错,但是运行时会报错)
@Resource
private RestTemplate restTemplate;

这个方案实际不可行。只是作为反面教材来对照下。

exchange和postForEntity的区别

exchange是原始的方法,灵活度最高。
postForEntity比exchange少了一个参数,相当于把post封装了。

其实本质都一样。

exchange例子
postForEntity的例子

报错: : Request processing failed; nested exception is

如果报这个错,很可能是restTemplate不存在。 配置下build即可。

rest逻辑处理

除了状态码200等之外,还要考虑到超时等,例如主机不存在等。

@RequestMapping("/restUrl")
public String restUrl(@RequestParam(name="url") String url){
    try {
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, "1234", String.class);
        if(HttpStatus.OK==responseEntity.getStatusCode()){
            logger.info("rest请求成功,返回报文:{}",responseEntity);
        }else{
            logger.info("rest请求失败,返回报文:{}",responseEntity);
        }
    }catch (Exception e){
        logger.error("rest请求异常,error:",e);
        ;
        return e.getMessage()+e.getSuppressed();
    }

    return "query success";
}

httpStatus 200的判断

一般来说有2种写法,都是可以的:

//  最优雅
if(HttpStatus.OK==responseEntity.getStatusCode()){
}

// 不够优雅
if(HttpStatus.OK.value()=responseEntity.getStatusCode().value()){
}

// 我就拿数字直接比较... 其实这样也可以
if(200==responseEntity.getStatusCode().value()){
}

另:getStatusCode().value()可以写为getStatusCodeValue(),是一样的。

几个方法的区别

发送请求有好几种方法,会用就好。
getForObject() 返回值直接是响应体内容转为指定的对象
getForEntity() 返回值的封装包含有响应头, 响应状态码的 ResponseEntity 对象
exchange() 可以指定为get请求或者post请求,并且返回ResponseEntity 对象

多个restTemplate

注入带有负载均衡的restTemplate。

@Bean
@LoadBalanced
public RestTemplate ispRestTemplate() {
    return new RestTemplate();
}

注入常规的restTemplate。

@Bean
public RestTemplate notBalanceRestTemplate() {
    return new RestTemplate();
}
@Resource(name = "ispRestTemplate")
private RestTemplate ispRestTemplate;

@Resource(name = "notBalanceRestTemplate")
private RestTemplate notBalanceRestTemplate;

有时框架自带的restTemplate带有负载均衡,但是不知道在哪里配置的怎么办?

就是再配置一个restTemplate,但是注入的时候使用@Autowired但是不加@Qualifier,这样根据类型注入会报错,就可以找到默认的restTemplate在哪里配置的了。

报错:
Field restTemplate in required a single bean, but 2 were found:
- notBalanceRestTemplate: defined by method ‘notBalanceRestTemplate’ in class path resource [com/test/]
- ispRestTemplate: defined by method ‘ispRestTemplate’ in class path resource [com/test/]

其他

restTempalte请求报错 No instances available for

怪了,restTemplate请求就报错,但是httpUtils请求就没问题。
百度说是@LoadBalance的问题,但是在StartupApplication类配置了还是不行。

@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
	return new RestTemplate();
}

感觉不是这的问题,怪怪的。